Source code: org/apache/axis/encoding/ser/CalendarDeserializer.java
1 /*
2 * Copyright 2001-2004 The Apache Software Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.apache.axis.encoding.ser;
18
19 import org.apache.axis.utils.Messages;
20
21 import javax.xml.namespace.QName;
22 import java.text.SimpleDateFormat;
23 import java.util.Calendar;
24 import java.util.Date;
25 import java.util.GregorianCalendar;
26 import java.util.TimeZone;
27
28 /**
29 * The CalendarSerializer deserializes a dateTime.
30 * Much of the work is done in the base class.
31 *
32 * @author Sam Ruby (rubys@us.ibm.com)
33 * Modified for JAX-RPC @author Rich Scheuerle (scheu@us.ibm.com)
34 */
35 public class CalendarDeserializer extends SimpleDeserializer {
36
37 private static SimpleDateFormat zulu =
38 new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
39 // 0123456789 0 123456789
40
41 static {
42 zulu.setTimeZone(TimeZone.getTimeZone("GMT"));
43 }
44
45 /**
46 * The Deserializer is constructed with the xmlType and
47 * javaType
48 */
49 public CalendarDeserializer(Class javaType, QName xmlType) {
50 super(javaType, xmlType);
51 }
52
53 /**
54 * The simple deserializer provides most of the stuff.
55 * We just need to override makeValue().
56 */
57 public Object makeValue(String source) {
58 Calendar calendar = Calendar.getInstance();
59 Date date;
60 boolean bc = false;
61
62 // validate fixed portion of format
63 if (source == null || source.length() == 0) {
64 throw new NumberFormatException(
65 Messages.getMessage("badDateTime00"));
66 }
67 if (source.charAt(0) == '+') {
68 source = source.substring(1);
69 }
70 if (source.charAt(0) == '-') {
71 source = source.substring(1);
72 bc = true;
73 }
74 if (source.length() < 19) {
75 throw new NumberFormatException(
76 Messages.getMessage("badDateTime00"));
77 }
78 if (source.charAt(4) != '-' || source.charAt(7) != '-' ||
79 source.charAt(10) != 'T') {
80 throw new NumberFormatException(Messages.getMessage("badDate00"));
81 }
82 if (source.charAt(13) != ':' || source.charAt(16) != ':') {
83 throw new NumberFormatException(Messages.getMessage("badTime00"));
84 }
85 // convert what we have validated so far
86 try {
87 synchronized (zulu) {
88 date = zulu.parse(source.substring(0, 19) + ".000Z");
89 }
90 } catch (Exception e) {
91 throw new NumberFormatException(e.toString());
92 }
93 int pos = 19;
94
95 // parse optional milliseconds
96 if (pos < source.length() && source.charAt(pos) == '.') {
97 int milliseconds = 0;
98 int start = ++pos;
99 while (pos < source.length() &&
100 Character.isDigit(source.charAt(pos))) {
101 pos++;
102 }
103 String decimal = source.substring(start, pos);
104 if (decimal.length() == 3) {
105 milliseconds = Integer.parseInt(decimal);
106 } else if (decimal.length() < 3) {
107 milliseconds = Integer.parseInt((decimal + "000")
108 .substring(0, 3));
109 } else {
110 milliseconds = Integer.parseInt(decimal.substring(0, 3));
111 if (decimal.charAt(3) >= '5') {
112 ++milliseconds;
113 }
114 }
115
116 // add milliseconds to the current date
117 date.setTime(date.getTime() + milliseconds);
118 }
119
120 // parse optional timezone
121 if (pos + 5 < source.length() &&
122 (source.charAt(pos) == '+' || (source.charAt(pos) == '-'))) {
123 if (!Character.isDigit(source.charAt(pos + 1)) ||
124 !Character.isDigit(source.charAt(pos + 2)) ||
125 source.charAt(pos + 3) != ':' ||
126 !Character.isDigit(source.charAt(pos + 4)) ||
127 !Character.isDigit(source.charAt(pos + 5))) {
128 throw new NumberFormatException(
129 Messages.getMessage("badTimezone00"));
130 }
131 int hours = (source.charAt(pos + 1) - '0') * 10
132 + source.charAt(pos + 2) - '0';
133 int mins = (source.charAt(pos + 4) - '0') * 10
134 + source.charAt(pos + 5) - '0';
135 int milliseconds = (hours * 60 + mins) * 60 * 1000;
136
137 // subtract milliseconds from current date to obtain GMT
138 if (source.charAt(pos) == '+') {
139 milliseconds = -milliseconds;
140 }
141 date.setTime(date.getTime() + milliseconds);
142 pos += 6;
143 }
144 if (pos < source.length() && source.charAt(pos) == 'Z') {
145 pos++;
146 calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
147 }
148 if (pos < source.length()) {
149 throw new NumberFormatException(Messages.getMessage("badChars00"));
150 }
151 calendar.setTime(date);
152
153 // support dates before the Christian era
154 if (bc) {
155 calendar.set(Calendar.ERA, GregorianCalendar.BC);
156 }
157 if (super.javaType == Date.class) {
158 return date;
159 } else {
160 return calendar;
161 }
162 }
163 }