Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

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 }