001: /*
002: * $Id: Timestamp.java,v 1.7 2007/03/01 06:34:59 ashutoshshahi Exp $
003: */
004:
005: /*
006: * The contents of this file are subject to the terms
007: * of the Common Development and Distribution License
008: * (the License). You may not use this file except in
009: * compliance with the License.
010: *
011: * You can obtain a copy of the license at
012: * https://glassfish.dev.java.net/public/CDDLv1.0.html.
013: * See the License for the specific language governing
014: * permissions and limitations under the License.
015: *
016: * When distributing Covered Code, include this CDDL
017: * Header Notice in each file and include the License file
018: * at https://glassfish.dev.java.net/public/CDDLv1.0.html.
019: * If applicable, add the following below the CDDL Header,
020: * with the fields enclosed by brackets [] replaced by
021: * you own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Copyright 2006 Sun Microsystems Inc. All Rights Reserved
025: */
026:
027: package com.sun.xml.wss.core;
028:
029: import com.sun.xml.wss.logging.LogDomainConstants;
030: import com.sun.xml.wss.impl.MessageConstants;
031: import com.sun.xml.wss.impl.XMLUtil;
032: import com.sun.xml.wss.XWSSecurityException;
033: import java.text.SimpleDateFormat;
034: import java.util.Calendar;
035: import java.util.GregorianCalendar;
036: import java.util.Iterator;
037: import java.util.logging.Level;
038: import java.util.logging.Logger;
039:
040: import javax.xml.soap.SOAPElement;
041: import javax.xml.soap.SOAPException;
042:
043: import com.sun.xml.wss.impl.misc.SecurityHeaderBlockImpl;
044:
045: import org.w3c.dom.Node;
046:
047: /**
048: * @author XWS-Security RI Development Team
049: */
050: public class Timestamp extends SecurityHeaderBlockImpl {
051:
052: private static Logger log = Logger.getLogger(
053: LogDomainConstants.WSS_API_DOMAIN,
054: LogDomainConstants.WSS_API_DOMAIN_BUNDLE);
055:
056: // -------------------------- constants --------------------------
057: private static String XSD_DATE_TIME = "xsd:dateTime";
058:
059: public static final long MAX_CLOCK_SKEW = 300000; // milliseconds
060: public static final long TIMESTAMP_FRESHNESS_LIMIT = 300000; // milliseconds
061:
062: /*
063: * /wsu:Timestamp/wsu:Created
064: */
065: private String created;
066:
067: private long timeout = 0;
068:
069: /*
070: * /wsu:Timestamp/wsu:Created/@ValueType
071: * optional attribute to specify the type of time data
072: * default is "xsd:dateTime".
073: */
074: private String createdValueType = XSD_DATE_TIME;
075:
076: /*
077: * /wsu:Timestamp/wsu:Expires
078: * This is optional but can appear at most once in a Timestamp element.
079: */
080: private String expires = null;
081:
082: /*
083: * /wsu:Timestamp/wsu:Expires/@ValueType
084: */
085: private String expiresValueType = XSD_DATE_TIME;
086:
087: /*
088: * /wsu:Timestamp@wsu:Id
089: */
090: private String wsuId = null;
091:
092: public Timestamp() {
093: }
094:
095: /**
096: * Takes a SOAPElement and checks if it has the right name.
097: */
098: public Timestamp(SOAPElement element) throws XWSSecurityException {
099:
100: if (!(element.getLocalName().equals("Timestamp") && XMLUtil
101: .inWsuNS(element))) {
102: log.log(Level.SEVERE, "WSS0385.error.creating.timestamp",
103: element.getTagName());
104: throw new XWSSecurityException(
105: "Invalid timestamp element passed");
106: }
107:
108: setSOAPElement(element);
109:
110: // extract and initialize the values of the rest of the variables.
111: Iterator children = element.getChildElements();
112: while (children.hasNext()) {
113:
114: Node object = (Node) children.next();
115:
116: if (object.getNodeType() == Node.ELEMENT_NODE) {
117: SOAPElement subElement = (SOAPElement) object;
118: if ("Created".equals(subElement.getLocalName())
119: && XMLUtil.inWsuNS(subElement)) {
120:
121: if (isBSP() && created != null) {
122: // created is already present
123: log.log(Level.SEVERE,
124: "BSP3203.Onecreated.Timestamp");
125: throw new XWSSecurityException(
126: "There can be only one wsu:Created element under Timestamp");
127: }
128:
129: created = subElement.getValue();
130: createdValueType = subElement
131: .getAttribute("ValueType");
132:
133: if (isBSP() && createdValueType != null
134: && createdValueType.length() > 0) {
135: // BSP:R3225 @ValueType MUST NOT be present
136: log.log(Level.SEVERE,
137: "BSP3225.createdValueType.Timestamp");
138: throw new XWSSecurityException(
139: "A wsu:Created element within a TIMESTAMP MUST NOT include a ValueType attribute.");
140: }
141: if ("".equalsIgnoreCase(createdValueType)) {
142: createdValueType = null;
143: }
144: }
145:
146: if ("Expires".equals(subElement.getLocalName())
147: && XMLUtil.inWsuNS(subElement)) {
148:
149: if (isBSP() && expires != null) {
150: // expires is already present
151: log.log(Level.SEVERE,
152: "BSP3224.Oneexpires.Timestamp");
153: throw new XWSSecurityException(
154: "There can be only one wsu:Expires element under Timestamp");
155: }
156:
157: if (isBSP() && created == null) {
158: // created is not present
159: log
160: .log(Level.SEVERE,
161: "BSP3221.CreatedBeforeExpires.Timestamp");
162: throw new XWSSecurityException(
163: "wsu:Expires must appear after wsu:Created in the Timestamp");
164: }
165:
166: expires = subElement.getValue();
167: // attr@ValueType
168: expiresValueType = subElement
169: .getAttribute("ValueType");
170:
171: if (isBSP() && expiresValueType != null
172: && expiresValueType.length() > 0) {
173: // BSP:R3226 @ValueType MUST NOT be present
174: log.log(Level.SEVERE,
175: "BSP3226.expiresValueType.Timestamp");
176: throw new XWSSecurityException(
177: "A wsu:Expires element within a TIMESTAMP MUST NOT include a ValueType attribute.");
178: }
179: if ("".equalsIgnoreCase(expiresValueType)) {
180: expiresValueType = null;
181: }
182: }
183: }
184: }
185: wsuId = element.getAttribute("wsu:Id");
186: if ("".equalsIgnoreCase(wsuId)) {
187: wsuId = null;
188: }
189: }
190:
191: /*
192: * Get creation time.
193: */
194: public String getCreated() {
195: return this .created;
196: }
197:
198: /*
199: * Set creation time.
200: */
201: public void setCreated(String created) {
202: this .created = created;
203: }
204:
205: /*
206: * Get the type of timeData.
207: */
208: public String getCreatedValueType() {
209: return this .createdValueType;
210: }
211:
212: /*
213: * Sets the type of timeData.
214: */
215: public void setCreatedValueType(String createdValueType) {
216: this .createdValueType = createdValueType;
217: }
218:
219: /**
220: * The timeout is assumed to be in seconds
221: */
222: public void setTimeout(long timeout) {
223: this .timeout = timeout;
224: }
225:
226: /*
227: * @return Get the expiration of the security semantics.
228: */
229: public String getExpires() {
230: return this .expires;
231: }
232:
233: /*
234: * Set the expiration of the security sematics.
235: */
236: public void setExpires(String expires) {
237: this .expires = expires;
238: }
239:
240: /*
241: * @return String Get the type of expires timeData.
242: */
243: public String getExpiresValueType() {
244: return this .expiresValueType;
245: }
246:
247: /*
248: * @return Sets the type of expires timeData.
249: */
250: public void setExpiresValueType(String expiresValueType) {
251: this .expiresValueType = expiresValueType;
252: }
253:
254: /*
255: * Get the type of timeData.
256: */
257: public String getId() {
258: return this .wsuId;
259: }
260:
261: /*
262: *
263: * @return Sets the wsu:Id attribute.
264: */
265: public void setId(String wsuId) {
266: this .wsuId = wsuId;
267: }
268:
269: // create the Element based on the values specified in the class.
270: public SOAPElement getAsSoapElement() throws XWSSecurityException {
271:
272: createDateTime();
273:
274: SOAPElement timestamp;
275:
276: try {
277: timestamp = getSoapFactory().createElement("Timestamp",
278: MessageConstants.WSU_PREFIX,
279: MessageConstants.WSU_NS);
280:
281: timestamp.addNamespaceDeclaration(
282: MessageConstants.WSU_PREFIX,
283: MessageConstants.WSU_NS);
284:
285: SOAPElement createdElement = timestamp.addChildElement(
286: "Created", MessageConstants.WSU_PREFIX)
287: .addTextNode(created);
288:
289: if (createdValueType != null
290: && !XSD_DATE_TIME
291: .equalsIgnoreCase(createdValueType))
292: createdElement.setAttribute("ValueType",
293: createdValueType);
294: // BSP:R3225 MUST NOT include ValueType attribute
295:
296: if (expires != null) {
297: SOAPElement expiresElement = timestamp.addChildElement(
298: "Expires", MessageConstants.WSU_PREFIX)
299: .addTextNode(expires);
300:
301: if (expiresValueType != null
302: && !XSD_DATE_TIME
303: .equalsIgnoreCase(expiresValueType))
304: expiresElement.setAttribute("ValueType",
305: expiresValueType);
306: // BSP:R3226 - MUST NOT include valueType attribute
307: }
308:
309: if (wsuId != null) {
310: setWsuIdAttr(timestamp, getId());
311: }
312:
313: } catch (SOAPException se) {
314: log.log(Level.SEVERE, "WSS0386.error.creating.timestamp",
315: se.getMessage());
316: throw new XWSSecurityException(
317: "There was an error creating " + " Timestamp "
318: + se.getMessage());
319: }
320:
321: setSOAPElement(timestamp);
322: return timestamp;
323: }
324:
325: /*
326: * The <wsu:Created> element specifies a timestamp used to
327: * indicate the creation time. It is defined as part of the
328: * <wsu:Timestamp> definition.
329: *
330: * Time reference in WSS work should be in terms of
331: * dateTime type specified in XML Schema in UTC time(Recommmended)
332: */
333: public void createDateTime() throws XWSSecurityException {
334: if (created == null) {
335: Calendar c = new GregorianCalendar();
336: int offset = c.get(Calendar.ZONE_OFFSET);
337: if (c.getTimeZone().inDaylightTime(c.getTime())) {
338: offset += c.getTimeZone().getDSTSavings();
339: }
340: synchronized (calendarFormatter2) {
341: calendarFormatter2.setTimeZone(c.getTimeZone());
342:
343: // always send UTC/GMT time
344: long beforeTime = c.getTimeInMillis();
345: long currentTime = 0;
346: currentTime = beforeTime - offset;
347: c.setTimeInMillis(currentTime);
348: // finished UTC/GMT adjustment
349:
350: setCreated(calendarFormatter2.format(c.getTime()));
351:
352: c.setTimeInMillis(currentTime + timeout);
353: setExpires(calendarFormatter2.format(c.getTime()));
354: }
355: }
356: }
357:
358: public static final SimpleDateFormat calendarFormatter1 = new SimpleDateFormat(
359: "yyyy-MM-dd'T'HH:mm:ss'Z'");
360:
361: public static final SimpleDateFormat calendarFormatter2 = new SimpleDateFormat(
362: "yyyy-MM-dd'T'HH:mm:ss'.'SSS'Z'");
363: }
|