001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.axis2.databinding.types;
020:
021: import java.text.ParseException;
022: import java.text.SimpleDateFormat;
023: import java.util.Calendar;
024: import java.util.Date;
025: import java.util.TimeZone;
026:
027: /** Class that represents the xsd:time XML Schema type */
028: public class Time implements java.io.Serializable {
029:
030: private static final long serialVersionUID = -9022201555535589908L;
031:
032: private Calendar _value;
033: private boolean isFromString;
034: private String originalString;
035:
036: /**
037: * a shared java.text.SimpleDateFormat instance used for parsing the basic component of the
038: * timestamp
039: */
040: private static SimpleDateFormat zulu = new SimpleDateFormat(
041: "HH:mm:ss.SSSSSSSSS'Z'");
042:
043: static {
044: zulu.setTimeZone(TimeZone.getTimeZone("GMT"));
045: }
046:
047: /** Initializes with a Calender. Year, month and date are ignored. */
048: public Time(Calendar value) {
049: this ._value = value;
050: _value.set(0, 0, 0); // ignore year, month, date
051: }
052:
053: /** Converts a string formatted as HH:mm:ss[.SSS][+/-offset] */
054: public Time(String value) throws NumberFormatException {
055: _value = makeValue(value);
056: this .isFromString = true;
057: this .originalString = value;
058: }
059:
060: /**
061: * Returns the time as a calendar. Ignores the year, month and date fields.
062: *
063: * @return Returns calendar value; may be null.
064: */
065: public Calendar getAsCalendar() {
066: return _value;
067: }
068:
069: /**
070: * Sets the time; ignores year, month, date
071: *
072: * @param date
073: */
074: public void setTime(Calendar date) {
075: this ._value = date;
076: _value.set(0, 0, 0); // ignore year, month, date
077: }
078:
079: /**
080: * Sets the time from a date instance.
081: *
082: * @param date
083: */
084: public void setTime(Date date) {
085: _value.setTime(date);
086: _value.set(0, 0, 0); // ignore year, month, date
087: }
088:
089: /** Utility function that parses xsd:time strings and returns a Date object */
090: private Calendar makeValue(String source)
091: throws NumberFormatException {
092:
093: // cannonical form of the times is hh ':' mm ':' ss ('.' s+)? (zzzzzz)?
094:
095: Calendar calendar = Calendar.getInstance();
096: SimpleDateFormat simpleDateFormat = null;
097: Date date;
098:
099: if ((source != null) && (source.length() >= 8)) {
100: if (source.length() == 8) {
101: // i.e this does not have milisecond values or time zone value
102: simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
103: } else {
104: String rest = source.substring(8);
105: if (rest.startsWith(".")) {
106: // i.e this have the ('.'s+) part
107: if (rest.endsWith("Z")) {
108: // this is in gmt time zone
109: simpleDateFormat = new SimpleDateFormat(
110: "HH:mm:ss.SSSSSSSSS'Z'");
111: simpleDateFormat.setTimeZone(TimeZone
112: .getTimeZone("GMT"));
113:
114: } else if ((rest.indexOf("+") > 0)
115: || (rest.indexOf("-") > 0)) {
116: // this is given in a general time zione
117: simpleDateFormat = new SimpleDateFormat(
118: "HH:mm:ss.SSSSSSSSSz");
119: if (rest.lastIndexOf("+") > 0) {
120: source = source.substring(0, source
121: .lastIndexOf("+"))
122: + "GMT"
123: + rest.substring(rest
124: .lastIndexOf("+"));
125: } else if (rest.lastIndexOf("-") > 0) {
126: source = source.substring(0, source
127: .lastIndexOf("-"))
128: + "GMT"
129: + rest.substring(rest
130: .lastIndexOf("-"));
131: }
132: } else {
133: // i.e it does not have time zone
134: simpleDateFormat = new SimpleDateFormat(
135: "HH:mm:ss.SSSSSSSSS");
136: }
137:
138: } else {
139: if (rest.startsWith("Z")) {
140: // this is in gmt time zone
141: simpleDateFormat = new SimpleDateFormat(
142: "HH:mm:ss'Z'");
143: simpleDateFormat.setTimeZone(TimeZone
144: .getTimeZone("GMT"));
145: } else if (rest.startsWith("+")
146: || rest.startsWith("-")) {
147: // this is given in a general time zione
148: simpleDateFormat = new SimpleDateFormat(
149: "HH:mm:ssz");
150: source = source.substring(0, 8) + "GMT" + rest;
151: } else {
152: throw new NumberFormatException(
153: "in valid time zone attribute");
154: }
155: }
156: }
157: } else {
158: throw new RuntimeException("invalid message string");
159: }
160:
161: try {
162: date = simpleDateFormat.parse(source);
163: calendar.setTime(date);
164: calendar.set(0, 0, 0);
165: } catch (ParseException e) {
166: throw new RuntimeException("invalid message string");
167: }
168:
169: return calendar;
170: }
171:
172: /**
173: * Returns the time as it would be in GMT. This is accurate to the seconds. Milliseconds
174: * probably gets lost.
175: *
176: * @return Returns String.
177: */
178: public String toString() {
179: if (_value == null) {
180: return "unassigned Time";
181: }
182:
183: if (isFromString) {
184: return originalString;
185: } else {
186: synchronized (zulu) {
187: return zulu.format(_value.getTime());
188: }
189: }
190:
191: }
192:
193: public boolean equals(Object obj) {
194: if (obj == null)
195: return false;
196: if (!(obj instanceof Time))
197: return false;
198: Time other = (Time) obj;
199: if (this == obj)
200: return true;
201:
202: boolean _equals;
203: _equals = ((_value == null && other._value == null) || (_value != null && _value
204: .getTime().equals(other._value.getTime())));
205:
206: return _equals;
207:
208: }
209:
210: /**
211: * Returns the hashcode of the underlying calendar.
212: *
213: * @return Returns an <code>int</code> value.
214: */
215: public int hashCode() {
216: return _value == null ? 0 : _value.hashCode();
217: }
218: }
|