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 Constructor with string 05/24/2001 Arnaud Blandin
34   * Created
35   */
36  package org.exolab.castor.types;
37  
38  import java.text.SimpleDateFormat;
39  import java.text.ParseException;
40  
41  /**
42   * Describe an XML schema gMonthDay type.
43   * <p>
44   * The format is defined by W3C XML Schema Recommendation and ISO8601 i.e
45   * <tt>--MM-DD(Z|(+|-)hh:mm)</tt>
46   * 
47   * @author <a href="mailto:blandin@intalio.com">Arnaud Blandin</a>
48   * @author <a href="mailto:edward.kuns@aspect.com">Edward Kuns</a>
49   * @version $Revision$
50   */
51  public class GMonthDay extends DateTimeBase {
52  
53    /** SerialVersionUID */
54    private static final long serialVersionUID = -6351252242146921258L;
55  
56    /** The gMonthDay SimpleDateFormat string. */
57    private static final String MONTHDAY_FORMAT = "--MM-dd";
58    /** Prefix of any complaint we make. */
59    private static final String BAD_GMONTHDAY = "Bad gMonthDay format: ";
60  
61    /**
62     * public only for the generated source code
63     */
64    public GMonthDay() {
65      // Nothing to do
66    }
67  
68    /**
69     * Instantiates a new gMonthDay given the value of the month and the value of the day.
70     * 
71     * @param month the month value
72     * @param day the day value
73     */
74    public GMonthDay(short month, short day) {
75      setMonth(month);
76      setDay(day);
77    }
78  
79    /**
80     * Instantiates a new gMonthDay given the value of the month and the value of the day.
81     * 
82     * @param month the month value
83     * @param day the day value
84     */
85    public GMonthDay(int month, int day) {
86      setMonth((short) month);
87      setDay((short) day);
88    }
89  
90    /**
91     * Constructs a XML Schema GMonthDay instance given all the values of the different fields. By
92     * default a GMonthDay is not UTC and is local.
93     * 
94     * @param values an array of shorts that represent the different fields of Time.
95     */
96    public GMonthDay(short[] values) {
97      this.setValues(values);
98    }
99  
100   /**
101    * Construct a GMonthDay from a string value
102    * 
103    * @param gmonthDay the string representation of the GMonthDay to instantiate
104    * @throws ParseException a parse exception is thrown if the string to parse does not follow the
105    *         rigth format (see the description of this class)
106    */
107   public GMonthDay(String gmonthDay) throws ParseException {
108     parseGMonthDayInternal(gmonthDay, this);
109   }
110 
111   /**
112    * Sets all the fields by reading the values in an array
113    * <p>
114    * if a Time Zone is specificied it has to be set by using
115    * {@link DateTimeBase#setZone(short, short) setZone}.
116    * 
117    * @param values an array of shorts with the values the array is supposed to be of length 2 and
118    *        ordered like the following:
119    *        <ul>
120    *        <li>Month</li>
121    *        <li>Day</li>
122    *        </ul>
123    */
124   public void setValues(short[] values) {
125     if (values.length != 2) {
126       throw new IllegalArgumentException("GMonthDay#setValues: not the right number of values");
127     }
128     this.setMonth(values[0]);
129     this.setDay(values[1]);
130   }
131 
132   /**
133    * Returns an array of short with all the fields that describe this gMonthDay type.
134    * <p>
135    * Note:the time zone is not included.
136    * 
137    * @return an array of short with all the fields that describe this Date type.
138    */
139   public short[] getValues() {
140     short[] result = new short[2];
141     result[0] = this.getMonth();
142     result[1] = this.getDay();
143     return result;
144   } // getValues
145 
146   /**
147    * converts this gMonthDay into a local java Date.
148    * 
149    * @return a local date representing this Date.
150    */
151   public java.util.Date toDate() {
152     SimpleDateFormat df = new SimpleDateFormat(MONTHDAY_FORMAT);
153     setDateFormatTimeZone(df);
154 
155     java.util.Date date = null;
156     try {
157       date = df.parse(this.toString());
158     } catch (ParseException e) {
159       // this can't happen since toString() should return the proper string format
160       e.printStackTrace();
161       return null;
162     }
163 
164     return date;
165   } // toDate()
166 
167   /**
168    * convert this gMonthDay to a string The format is defined by W3C XML Schema recommendation and
169    * ISO8601 i.e --MM-DD(Z|(+|-)hh:mm)
170    * 
171    * @return a string representing this Date
172    */
173   public String toString() {
174     StringBuffer result = new StringBuffer("--");
175 
176     if ((this.getMonth() / 10) == 0) {
177       result.append(0);
178     }
179     result.append(this.getMonth());
180 
181     result.append("-");
182 
183     if ((this.getDay() / 10) == 0) {
184       result.append(0);
185     }
186     result.append(this.getDay());
187 
188     appendTimeZoneString(result);
189 
190     return result.toString();
191   } // toString
192 
193   /**
194    * parse a String and convert it into an java.lang.Object
195    * 
196    * @param str the string to parse
197    * @return an Object represented by the string
198    * @throws ParseException a parse exception is thrown if the string to parse does not follow the
199    *         rigth format (see the description of this class)
200    */
201   public static Object parse(String str) throws ParseException {
202     return parseGMonthDay(str);
203   }
204 
205   /**
206    * parse a String and convert it into a gMonthDay.
207    * 
208    * @param str the string to parse
209    * @return the Date represented by the string
210    * @throws ParseException a parse exception is thrown if the string to parse does not follow the
211    *         rigth format (see the description of this class)
212    */
213   public static GMonthDay parseGMonthDay(String str) throws ParseException {
214     return parseGMonthDayInternal(str, null);
215   }
216 
217   private static GMonthDay parseGMonthDayInternal(String str, GMonthDay result)
218       throws ParseException {
219     if (str == null) {
220       throw new IllegalArgumentException("The string to be parsed must not be null.");
221     }
222 
223     if (result == null) {
224       result = new GMonthDay();
225     }
226 
227     char[] chars = str.toCharArray();
228 
229     int idx = 0;
230     if (chars[idx] != '-' || chars[idx + 1] != '-') {
231       throw new ParseException(
232           BAD_GMONTHDAY + str + "\nA gMonthDay must follow the pattern --MM-DD(Z|((+|-)hh:mm)).",
233           0);
234     }
235 
236     idx += 2;
237 
238     // Month
239     if (!Character.isDigit(chars[idx]) || !Character.isDigit(chars[idx + 1])) {
240       throw new ParseException(BAD_GMONTHDAY + str + "\nThe Month must be 2 digits long", idx);
241     }
242 
243     short value1 = (short) ((chars[idx] - '0') * 10 + (chars[idx + 1] - '0'));
244     result.setMonth(value1);
245 
246     idx += 2;
247 
248     if (chars[idx] != '-') {
249       throw new ParseException(
250           BAD_GMONTHDAY + str + "\nA gMonthDay must follow the pattern --MM-DD(Z|((+|-)hh:mm)).",
251           0);
252     }
253 
254     idx++;
255 
256     // Day
257     if (!Character.isDigit(chars[idx]) || !Character.isDigit(chars[idx + 1])) {
258       throw new ParseException(BAD_GMONTHDAY + str + "\nThe Day must be 2 digits long", idx);
259     }
260 
261     value1 = (short) ((chars[idx] - '0') * 10 + (chars[idx + 1] - '0'));
262     result.setDay(value1);
263 
264     idx += 2;
265 
266     parseTimeZone(str, result, chars, idx, BAD_GMONTHDAY);
267 
268     return result;
269   } // parse
270 
271   /////////////////////////// DISALLOWED METHODS ///////////////////////////
272 
273   public boolean hasIsNegative() {
274     return false;
275   }
276 
277   public boolean isNegative() {
278     String err = "org.exolab.castor.types.GMonthDay does not have a 'negative' field.";
279     throw new UnsupportedOperationException(err);
280   }
281 
282   public void setNegative() {
283     String err = "org.exolab.castor.types.GMonthDay cannot be negative.";
284     throw new UnsupportedOperationException(err);
285   }
286 
287   public boolean hasCentury() {
288     return false;
289   }
290 
291   public short getCentury() {
292     String err = "org.exolab.castor.types.GMonthDay does not have a Century field.";
293     throw new UnsupportedOperationException(err);
294   }
295 
296   public void setCentury(short century) {
297     String err = "org.exolab.castor.types.GMonthDay does not have a Century field.";
298     throw new UnsupportedOperationException(err);
299   }
300 
301   public boolean hasYear() {
302     return false;
303   }
304 
305   public short getYear() {
306     String err = "org.exolab.castor.types.GMonthDay does not have a Year field.";
307     throw new UnsupportedOperationException(err);
308   }
309 
310   public void setYear(short year) {
311     String err = "org.exolab.castor.types.GMonthDay does not have a Year field.";
312     throw new UnsupportedOperationException(err);
313   }
314 
315   public boolean hasHour() {
316     return false;
317   }
318 
319   public short getHour() {
320     String err = "org.exolab.castor.types.GMonthDay does not have an Hour field.";
321     throw new UnsupportedOperationException(err);
322   }
323 
324   public void setHour(short hour) {
325     String err = "org.exolab.castor.types.GMonthDay does not have an Hour field.";
326     throw new UnsupportedOperationException(err);
327   }
328 
329   public boolean hasMinute() {
330     return false;
331   }
332 
333   public short getMinute() {
334     String err = "org.exolab.castor.types.GMonthDay does not have a Minute field.";
335     throw new UnsupportedOperationException(err);
336   }
337 
338   public void setMinute(short minute) {
339     String err = "org.exolab.castor.types.GMonthDay does not have a Minute field.";
340     throw new UnsupportedOperationException(err);
341   }
342 
343   public boolean hasSeconds() {
344     return false;
345   }
346 
347   public short getSeconds() {
348     String err = "org.exolab.castor.types.GMonthDay does not have a Seconds field.";
349     throw new UnsupportedOperationException(err);
350   }
351 
352   public void setSecond(short second) {
353     String err = "org.exolab.castor.types.GMonthDay does not have a Seconds field.";
354     throw new UnsupportedOperationException(err);
355   }
356 
357   public boolean hasMilli() {
358     return false;
359   }
360 
361   public short getMilli() {
362     String err = "org.exolab.castor.types.GMonthDay does not have a Milliseconds field.";
363     throw new UnsupportedOperationException(err);
364   }
365 
366   public void setMilliSecond(short millisecond) {
367     String err = "org.exolab.castor.types.GMonthDay does not have a Milliseconds field.";
368     throw new UnsupportedOperationException(err);
369   }
370 
371 }