| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.apache.axis2.databinding.types; |
| |
| |
| import org.apache.axis2.databinding.utils.ConverterUtil; |
| |
| import java.util.Calendar; |
| import java.util.Date; |
| import java.util.TimeZone; |
| |
| /** Class that represents the xsd:time XML Schema type */ |
| public class Time implements java.io.Serializable { |
| |
| private static final long serialVersionUID = -9022201555535589908L; |
| |
| private Calendar _value; |
| private boolean isFromString; |
| private String originalString; |
| |
| /** |
| * a shared java.text.SimpleDateFormat instance used for parsing the basic component of the |
| * timestamp |
| */ |
| |
| /** Initializes with a Calender. Year, month and date are ignored. */ |
| public Time(Calendar value) { |
| this._value = value; |
| this._value.clear(Calendar.YEAR); |
| this._value.clear(Calendar.MONTH); |
| this._value.clear(Calendar.DATE); |
| } |
| |
| /** Converts a string formatted as HH:mm:ss[.SSS][+/-offset] */ |
| public Time(String value) throws NumberFormatException { |
| _value = makeValue(value); |
| this.isFromString = true; |
| this.originalString = value; |
| } |
| |
| /** |
| * Returns the time as a calendar. Ignores the year, month and date fields. |
| * |
| * @return Returns calendar value; may be null. |
| */ |
| public Calendar getAsCalendar() { |
| return _value; |
| } |
| |
| /** |
| * Sets the time; ignores year, month, date |
| * |
| * @param date |
| */ |
| public void setTime(Calendar date) { |
| this._value = date; |
| this._value.clear(Calendar.YEAR); |
| this._value.clear(Calendar.MONTH); |
| this._value.clear(Calendar.DATE); |
| } |
| |
| /** |
| * Sets the time from a date instance. |
| * |
| * @param date |
| */ |
| public void setTime(Date date) { |
| _value.setTime(date); |
| this._value.clear(Calendar.YEAR); |
| this._value.clear(Calendar.MONTH); |
| this._value.clear(Calendar.DATE); |
| } |
| |
| /** Utility function that parses xsd:time strings and returns a Date object */ |
| private Calendar makeValue(String source) throws NumberFormatException { |
| |
| // cannonical form of the times is hh ':' mm ':' ss ('.' s+)? (zzzzzz)? |
| if ((source == null) || (source.trim().length() == 0)){ |
| return null; |
| } |
| |
| source = source.trim(); |
| |
| Calendar calendar = Calendar.getInstance(); |
| calendar.clear(); |
| calendar.setLenient(false); |
| int hour = 0; |
| int minite = 0; |
| int second = 0; |
| long miliSecond = 0; |
| |
| int timeZoneOffSet = TimeZone.getDefault().getRawOffset(); |
| int milliSecondPartLength = 0; |
| if (source.length() >= 8) { |
| if ((source.charAt(2) != ':' )|| (source.charAt(5) != ':')){ |
| throw new RuntimeException("Invalid time format (" + source + ") having : s in wrong places"); |
| } |
| hour = Integer.parseInt(source.substring(0, 2)); |
| minite = Integer.parseInt(source.substring(3, 5)); |
| second = Integer.parseInt(source.substring(6, 8)); |
| |
| |
| |
| if (source.length() > 8) { |
| String rest = source.substring(8); |
| if (rest.startsWith(".")) { |
| // i.e this have the ('.'s+) part |
| if (rest.endsWith("Z")) { |
| // this is in gmt time zone |
| timeZoneOffSet = 0; |
| miliSecond = Integer.parseInt(rest.substring(1, rest.lastIndexOf("Z"))); |
| milliSecondPartLength = rest.substring(1,rest.lastIndexOf("Z")).trim().length(); |
| } else if ((rest.lastIndexOf("+") > 0) || (rest.lastIndexOf("-") > 0)) { |
| // this is given in a general time zione |
| String timeOffSet = null; |
| if (rest.lastIndexOf("+") > 0) { |
| timeOffSet = rest.substring(rest.lastIndexOf("+") + 1); |
| miliSecond = Integer.parseInt(rest.substring(1, rest.lastIndexOf("+"))); |
| milliSecondPartLength = rest.substring(1, rest.lastIndexOf("+")).trim().length(); |
| // we keep +1 or -1 to finally calculate the value |
| timeZoneOffSet = 1; |
| |
| } else if (rest.lastIndexOf("-") > 0) { |
| timeOffSet = rest.substring(rest.lastIndexOf("-") + 1); |
| miliSecond = Integer.parseInt(rest.substring(1, rest.lastIndexOf("-"))); |
| milliSecondPartLength = rest.substring(1, rest.lastIndexOf("-")).trim().length(); |
| // we keep +1 or -1 to finally calculate the value |
| timeZoneOffSet = -1; |
| } |
| if (timeOffSet.charAt(2) != ':') { |
| throw new RuntimeException("invalid time zone format (" + source |
| + ") without : at correct place"); |
| } |
| int hours = Integer.parseInt(timeOffSet.substring(0, 2)); |
| int minits = Integer.parseInt(timeOffSet.substring(3, 5)); |
| timeZoneOffSet = ((hours * 60) + minits) * 60000 * timeZoneOffSet; |
| |
| } else { |
| // i.e it does not have time zone |
| miliSecond = Integer.parseInt(rest.substring(1)); |
| milliSecondPartLength = rest.substring(1).trim().length(); |
| } |
| |
| } else { |
| if (rest.startsWith("Z")) { |
| // this is in gmt time zone |
| timeZoneOffSet = 0; |
| } else if (rest.startsWith("+") || rest.startsWith("-")) { |
| // this is given in a general time zione |
| if (rest.charAt(3) != ':') { |
| throw new RuntimeException("invalid time zone format (" + source |
| + ") without : at correct place"); |
| } |
| int hours = Integer.parseInt(rest.substring(1, 3)); |
| int minits = Integer.parseInt(rest.substring(4, 6)); |
| timeZoneOffSet = ((hours * 60) + minits) * 60000; |
| if (rest.startsWith("-")) { |
| timeZoneOffSet = timeZoneOffSet * -1; |
| } |
| } else { |
| throw new NumberFormatException("in valid time zone attribute"); |
| } |
| } |
| } |
| } else { |
| throw new RuntimeException("invalid message string"); |
| } |
| |
| calendar.set(Calendar.HOUR_OF_DAY, hour); |
| calendar.set(Calendar.MINUTE, minite); |
| calendar.set(Calendar.SECOND, second); |
| if (milliSecondPartLength != 3) { |
| // milisecond part represenst the fraction of the second so we have to |
| // find the fraction and multiply it by 1000. So if milisecond part |
| // has three digits nothing required |
| miliSecond = miliSecond * 1000; |
| for (int i = 0; i < milliSecondPartLength; i++) { |
| miliSecond = miliSecond / 10; |
| } |
| } |
| calendar.set(Calendar.MILLISECOND, (int)miliSecond); |
| calendar.set(Calendar.ZONE_OFFSET, timeZoneOffSet); |
| calendar.set(Calendar.DST_OFFSET, 0); |
| |
| return calendar; |
| } |
| |
| |
| /** |
| * Returns the time as it would be in GMT. This is accurate to the seconds. Milliseconds |
| * probably gets lost. |
| * |
| * @return Returns String. |
| */ |
| public String toString() { |
| if (_value == null) { |
| return "unassigned Time"; |
| } |
| |
| if (isFromString) { |
| return originalString; |
| } else { |
| StringBuffer timeString = new StringBuffer(); |
| ConverterUtil.appendTime(_value,timeString); |
| ConverterUtil.appendTimeZone(_value,timeString); |
| return timeString.toString(); |
| } |
| |
| } |
| |
| public boolean equals(Object obj) { |
| if (obj == null) return false; |
| if (!(obj instanceof Time)) return false; |
| Time other = (Time)obj; |
| if (this == obj) return true; |
| |
| boolean _equals; |
| _equals = ((_value == null && other._value == null) || |
| (_value != null && |
| _value.getTime().equals(other._value.getTime()))); |
| |
| return _equals; |
| |
| } |
| |
| /** |
| * Returns the hashcode of the underlying calendar. |
| * |
| * @return Returns an <code>int</code> value. |
| */ |
| public int hashCode() { |
| return _value == null ? 0 : _value.hashCode(); |
| } |
| } |