View Javadoc
1   /*
2    * Redistribution and use of this software and associated documentation ("Software"), with or
3    * without modification, are permitted provided that the following conditions are met:
4    *
5    * 1. Redistributions of source code must retain copyright statements and notices. Redistributions
6    * must also contain a copy of this document.
7    *
8    * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
9    * conditions and the following disclaimer in the documentation and/or other materials provided with
10   * the distribution.
11   *
12   * 3. The name "Exolab" must not be used to endorse or promote products derived from this Software
13   * without prior written permission of Intalio, Inc. For written permission, please contact
14   * info@exolab.org.
15   *
16   * 4. Products derived from this Software may not be called "Exolab" nor may "Exolab" appear in
17   * their names without prior written permission of Intalio, Inc. Exolab is a registered trademark of
18   * Intalio, Inc.
19   *
20   * 5. Due credit should be given to the Exolab Project (http://www.exolab.org/).
21   *
22   * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR
23   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
24   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTALIO, INC. OR ITS
25   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
29   * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30   *
31   * Copyright 2001 (C) Intalio, Inc. All Rights Reserved.
32   *
33   * $Id$ Date Author Changes 04/18/2002 Arnaud String constructor 05/24/2001 Arnaud Blandin Created
34   */
35  package org.exolab.castor.types;
36  
37  import java.text.SimpleDateFormat;
38  import java.text.ParseException;
39  
40  /**
41   * Describe an XML schema gMonth type.
42   * <p>
43   * The format is defined by W3C XML Schema Recommendation and ISO8601 i.e
44   * <tt>--MM--(Z|(+|-)hh:mm)</tt>
45   * 
46   * @author <a href="mailto:blandin@intalio.com">Arnaud Blandin</a>
47   * @author <a href="mailto:edward.kuns@aspect.com">Edward Kuns</a>
48   * @version $Revision$
49   */
50  public class GMonth extends DateTimeBase {
51  
52    /** SerialVersionUID */
53    private static final long serialVersionUID = -1950758441188466762L;
54  
55    /** The gMonth SimpleDateFormat string. */
56    private static final String MONTH_FORMAT = "--MM--";
57    /** Prefix of any complaint we make. */
58    private static final String BAD_GMONTH = "Bad gMonth format: ";
59  
60    /**
61     * public only for the generated source code
62     */
63    public GMonth() {
64      // Nothing to do
65    }
66  
67    /**
68     * Constructs a XML Schema GMonth instance given all the values of the different fields. By
69     * default a GMonth is not UTC and is local.
70     * 
71     * @param month the month value.
72     */
73    public GMonth(short month) {
74      setMonth(month);
75    }
76  
77    /**
78     * Constructs a XML Schema GMonth instance given all the values of the different fields. By
79     * default a GMonth is not UTC and is local.
80     * 
81     * @param month the month value.
82     */
83    public GMonth(int month) {
84      setMonth((short) month);
85    }
86  
87    /**
88     * Constructs a GMonth from a string value.
89     * 
90     * @param gmonth the string representation of the GMonth to instantiate
91     * @throws ParseException a parse exception is thrown if the string to parse does not follow the
92     *         rigth format (see the description of this class)
93     */
94    public GMonth(String gmonth) throws ParseException {
95      parseGMonthInternal(gmonth, this);
96    }
97  
98    /**
99     * Sets all the fields by reading the values in an array
100    * <p>
101    * if a Time Zone is specificied it has to be set by using
102    * {@link DateTimeBase#setZone(short, short) setZone}.
103    *
104    * @param values an array of shorts with the values the array is supposed to be of length 1 and
105    *        ordered like the following:
106    *        <ul>
107    *        <li>Month</li>
108    *        </ul>
109    */
110   public void setValues(short[] values) {
111     if (values.length != 1) {
112       throw new IllegalArgumentException("GMonth#setValues: not the right number of values");
113     }
114     this.setMonth(values[0]);
115   }
116 
117   /**
118    * Returns an array of short with all the fields that describe this gDay type.
119    * <p>
120    * Note:the time zone is not included.
121    * 
122    * @return an array of short with all the fields that describe this Date type.
123    */
124   public short[] getValues() {
125     short[] result = new short[1];
126     result[0] = this.getMonth();
127     return result;
128   } // getValues
129 
130   /**
131    * converts this GMonth into a local java Date.
132    * 
133    * @return a local date representing this Date.
134    */
135   public java.util.Date toDate() {
136     SimpleDateFormat df = new SimpleDateFormat(MONTH_FORMAT);
137     setDateFormatTimeZone(df);
138 
139     java.util.Date date = null;
140     try {
141       date = df.parse(this.toString());
142     } catch (ParseException e) {
143       // this can't happen since toString() should return the proper string format
144       e.printStackTrace();
145       return null;
146     }
147 
148     return date;
149   } // toDate()
150 
151   /**
152    * convert this GMonth to a string The format is defined by W3C XML Schema recommendation and
153    * ISO8601 i.e --MM--(Z|(+|-)hh:mm)
154    * 
155    * @return a string representing this Date
156    */
157   public String toString() {
158     StringBuffer result = new StringBuffer("--");
159 
160     if ((this.getMonth() / 10) == 0) {
161       result.append(0);
162     }
163     result.append(this.getMonth());
164 
165     result.append("--");
166 
167     appendTimeZoneString(result);
168 
169     return result.toString();
170   } // toString
171 
172   /**
173    * parse a String and convert it into an java.lang.Object
174    * 
175    * @param str the string to parse
176    * @return an Object represented by the string
177    * @throws ParseException a parse exception is thrown if the string to parse does not follow the
178    *         rigth format (see the description of this class)
179    */
180   public static Object parse(String str) throws ParseException {
181     return parseGMonth(str);
182   }
183 
184   /**
185    * parse a String and convert it into a GMonth.
186    * 
187    * @param str the string to parse
188    * @return the Date represented by the string
189    * @throws ParseException a parse exception is thrown if the string to parse does not follow the
190    *         rigth format (see the description of this class)
191    */
192   public static GMonth parseGMonth(String str) throws ParseException {
193     GMonth result = new GMonth();
194     return parseGMonthInternal(str, result);
195   }
196 
197   private static GMonth parseGMonthInternal(String str, GMonth result) throws ParseException {
198     if (str == null) {
199       throw new IllegalArgumentException("The string to be parsed must not be null.");
200     }
201 
202     if (result == null) {
203       result = new GMonth();
204     }
205 
206     char[] chars = str.toCharArray();
207 
208     int idx = 0;
209     if (chars[0] != '-' || chars[1] != '-') {
210       throw new ParseException(
211           BAD_GMONTH + str + "\nA gMonth must follow the pattern --DD--(Z|((+|-)hh:mm)).", 0);
212     }
213 
214     idx += 2;
215 
216     // Month
217     if (!Character.isDigit(chars[idx]) || !Character.isDigit(chars[idx + 1])) {
218       throw new ParseException(BAD_GMONTH + str + "\nThe Month must be 2 digits long", idx);
219     }
220 
221     short value1 = (short) ((chars[idx] - '0') * 10 + (chars[idx + 1] - '0'));
222     result.setMonth(value1);
223 
224     idx += 2;
225 
226     if (chars[idx] != '-' || chars[idx + 1] != '-') {
227       throw new ParseException(
228           BAD_GMONTH + str + "\nA gMonth must follow the pattern --DD--(Z|((+|-)hh:mm)).", 0);
229     }
230 
231     idx += 2;
232 
233     parseTimeZone(str, result, chars, idx, BAD_GMONTH);
234 
235     return result;
236   } // parse
237 
238   /////////////////////////// DISALLOWED METHODS ///////////////////////////
239 
240   public boolean hasIsNegative() {
241     return false;
242   }
243 
244   public boolean isNegative() {
245     String err = "org.exolab.castor.types.GMonth does not have a 'negative' field.";
246     throw new UnsupportedOperationException(err);
247   }
248 
249   public void setNegative() {
250     String err = "org.exolab.castor.types.GMonth cannot be negative.";
251     throw new UnsupportedOperationException(err);
252   }
253 
254   public boolean hasCentury() {
255     return false;
256   }
257 
258   public short getCentury() {
259     String err = "org.exolab.castor.types.GMonth does not have a Century field.";
260     throw new UnsupportedOperationException(err);
261   }
262 
263   public void setCentury(short century) {
264     String err = "org.exolab.castor.types.GMonth does not have a Century field.";
265     throw new UnsupportedOperationException(err);
266   }
267 
268   public boolean hasYear() {
269     return false;
270   }
271 
272   public short getYear() {
273     String err = "org.exolab.castor.types.GMonth does not have a Year field.";
274     throw new UnsupportedOperationException(err);
275   }
276 
277   public void setYear(short year) {
278     String err = "org.exolab.castor.types.GMonth does not have a Year field.";
279     throw new UnsupportedOperationException(err);
280   }
281 
282   public boolean hasDay() {
283     return false;
284   }
285 
286   public short getDay() {
287     String err = "org.exolab.castor.types.GMonth does not have a Day field.";
288     throw new UnsupportedOperationException(err);
289   }
290 
291   public void setDay(short month) {
292     String err = "org.exolab.castor.types.GMonth does not have a Day field.";
293     throw new UnsupportedOperationException(err);
294   }
295 
296   public boolean hasHour() {
297     return false;
298   }
299 
300   public short getHour() {
301     String err = "org.exolab.castor.types.GMonth does not have an Hour field.";
302     throw new UnsupportedOperationException(err);
303   }
304 
305   public void setHour(short hour) {
306     String err = "org.exolab.castor.types.GMonth does not have an Hour field.";
307     throw new UnsupportedOperationException(err);
308   }
309 
310   public boolean hasMinute() {
311     return false;
312   }
313 
314   public short getMinute() {
315     String err = "org.exolab.castor.types.GMonth does not have a Minute field.";
316     throw new UnsupportedOperationException(err);
317   }
318 
319   public void setMinute(short minute) {
320     String err = "org.exolab.castor.types.GMonth does not have a Minute field.";
321     throw new UnsupportedOperationException(err);
322   }
323 
324   public boolean hasSeconds() {
325     return false;
326   }
327 
328   public short getSeconds() {
329     String err = "org.exolab.castor.types.GMonth does not have a Seconds field.";
330     throw new UnsupportedOperationException(err);
331   }
332 
333   public void setSecond(short second) {
334     String err = "org.exolab.castor.types.GMonth does not have a Seconds field.";
335     throw new UnsupportedOperationException(err);
336   }
337 
338   public boolean hasMilli() {
339     return false;
340   }
341 
342   public short getMilli() {
343     String err = "org.exolab.castor.types.GMonth does not have a Milliseconds field.";
344     throw new UnsupportedOperationException(err);
345   }
346 
347   public void setMilliSecond(short millisecond) {
348     String err = "org.exolab.castor.types.GMonth does not have a Milliseconds field.";
349     throw new UnsupportedOperationException(err);
350   }
351 
352 }