KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > types > Duration


1 /*
2  * Copyright 2002-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.types;
18
19 import org.apache.axis.utils.Messages;
20
21 import java.util.Calendar JavaDoc;
22
23 /**
24  * Implementation of the XML Schema type duration. Duration supports a minimum
25  * fractional second precision of milliseconds.
26  *
27  * @author Wes Moulder <wes@themindelectric.com>
28  * @author Dominik Kacprzak (dominik@opentoolbox.com)
29  * @see <a HREF="http://www.w3.org/TR/xmlschema-2/#duration">XML Schema 3.2.6</a>
30  */

31 public class Duration implements java.io.Serializable JavaDoc {
32     boolean isNegative = false;
33     int years;
34     int months;
35     int days;
36     int hours;
37     int minutes;
38     double seconds;
39
40     /**
41      * Default no-arg constructor
42      */

43     public Duration() {
44     }
45
46     /**
47      * @param negative
48      * @param aYears
49      * @param aMonths
50      * @param aDays
51      * @param aHours
52      * @param aMinutes
53      * @param aSeconds
54      */

55     public Duration(boolean negative, int aYears, int aMonths, int aDays,
56                     int aHours, int aMinutes, double aSeconds) {
57         isNegative = negative;
58         years = aYears;
59         months = aMonths;
60         days = aDays;
61         hours = aHours;
62         minutes = aMinutes;
63         setSeconds(aSeconds);
64     }
65
66     /**
67      * Constructs Duration from a String in an xsd:duration format -
68      * PnYnMnDTnHnMnS.
69      *
70      * @param duration String
71      * @throws SchemaException if the string doesn't parse correctly.
72      */

73     public Duration(String JavaDoc duration) throws IllegalArgumentException JavaDoc {
74         int position = 1;
75         int timePosition = duration.indexOf("T");
76
77         // P is required but P by itself is invalid
78
if (duration.indexOf("P") == -1 || duration.equals("P")) {
79             throw new IllegalArgumentException JavaDoc(
80                     Messages.getMessage("badDuration"));
81         }
82
83         // if present, time cannot be empty
84
if (duration.lastIndexOf("T") == duration.length() - 1) {
85             throw new IllegalArgumentException JavaDoc(
86                     Messages.getMessage("badDuration"));
87         }
88
89         // check the sign
90
if (duration.startsWith("-")) {
91             isNegative = true;
92             position++;
93         }
94
95         // parse time part
96
if (timePosition != -1) {
97             parseTime(duration.substring(timePosition + 1));
98         } else {
99             timePosition = duration.length();
100         }
101
102         // parse date part
103
if (position != timePosition) {
104             parseDate(duration.substring(position, timePosition));
105         }
106     }
107
108     /**
109      * Constructs Duration from a Calendar.
110      *
111      * @param calendar Calendar
112      * @throws IllegalArgumentException if the calendar object does not
113      * represent any date nor time.
114      */

115     public Duration(boolean negative, Calendar JavaDoc calendar) throws
116             IllegalArgumentException JavaDoc {
117         this.isNegative = negative;
118         this.years = calendar.get(Calendar.YEAR);
119         this.months = calendar.get(Calendar.MONTH);
120         this.days = calendar.get(Calendar.DATE);
121         this.hours = calendar.get(Calendar.HOUR);
122         this.minutes = calendar.get(Calendar.MINUTE);
123         this.seconds = calendar.get(Calendar.SECOND);
124         this.seconds += ((double) calendar.get(Calendar.MILLISECOND)) / 100;
125         if (years == 0 && months == 0 && days == 0 && hours == 0 &&
126             minutes == 0 && seconds == 0) {
127             throw new IllegalArgumentException JavaDoc(Messages.getMessage(
128                     "badCalendarForDuration"));
129         }
130     }
131
132     /**
133      * This method parses the time portion of a String that represents
134      * xsd:duration - nHnMnS.
135      *
136      * @param time
137      * @throws IllegalArgumentException if time does not match pattern
138      *
139      */

140     public void parseTime(String JavaDoc time) throws IllegalArgumentException JavaDoc {
141         if (time.length() == 0 || time.indexOf("-") != -1) {
142             throw new IllegalArgumentException JavaDoc(
143                     Messages.getMessage("badTimeDuration"));
144         }
145
146         // check if time ends with either H, M, or S
147
if (!time.endsWith("H") && !time.endsWith("M") && !time.endsWith("S")) {
148             throw new IllegalArgumentException JavaDoc(
149                     Messages.getMessage("badTimeDuration"));
150         }
151
152         try {
153             // parse string and extract hours, minutes, and seconds
154
int start = 0;
155
156             // Hours
157
int end = time.indexOf("H");
158             // if there is H in a string but there is no value for hours,
159
// throw an exception
160
if (start == end) {
161                 throw new IllegalArgumentException JavaDoc(
162                         Messages.getMessage("badTimeDuration"));
163             }
164             if (end != -1) {
165                 hours = Integer.parseInt(time.substring(0, end));
166                 start = end + 1;
167             }
168
169             // Minutes
170
end = time.indexOf("M");
171             // if there is M in a string but there is no value for hours,
172
// throw an exception
173
if (start == end) {
174                 throw new IllegalArgumentException JavaDoc(
175                         Messages.getMessage("badTimeDuration"));
176             }
177
178             if (end != -1) {
179                 minutes = Integer.parseInt(time.substring(start, end));
180                 start = end + 1;
181             }
182
183             // Seconds
184
end = time.indexOf("S");
185             // if there is S in a string but there is no value for hours,
186
// throw an exception
187
if (start == end) {
188                 throw new IllegalArgumentException JavaDoc(
189                         Messages.getMessage("badTimeDuration"));
190             }
191
192             if (end != -1) {
193                 setSeconds(Double.parseDouble(time.substring(start, end)));
194             }
195         } catch (NumberFormatException JavaDoc e) {
196             throw new IllegalArgumentException JavaDoc(
197                     Messages.getMessage("badTimeDuration"));
198         }
199     }
200
201     /**
202      * This method parses the date portion of a String that represents
203      * xsd:duration - nYnMnD.
204      *
205      * @param date
206      * @throws IllegalArgumentException if date does not match pattern
207      *
208      */

209     public void parseDate(String JavaDoc date) throws IllegalArgumentException JavaDoc {
210         if (date.length() == 0 || date.indexOf("-") != -1) {
211             throw new IllegalArgumentException JavaDoc(
212                     Messages.getMessage("badDateDuration"));
213         }
214
215         // check if date string ends with either Y, M, or D
216
if (!date.endsWith("Y") && !date.endsWith("M") && !date.endsWith("D")) {
217             throw new IllegalArgumentException JavaDoc(
218                     Messages.getMessage("badDateDuration"));
219         }
220
221         // catch any parsing exception
222
try {
223             // parse string and extract years, months, days
224
int start = 0;
225             int end = date.indexOf("Y");
226
227             // if there is Y in a string but there is no value for years,
228
// throw an exception
229
if (start == end) {
230                 throw new IllegalArgumentException JavaDoc(
231                         Messages.getMessage("badDateDuration"));
232             }
233             if (end != -1) {
234                 years = Integer.parseInt(date.substring(0, end));
235                 start = end + 1;
236             }
237
238             // months
239
end = date.indexOf("M");
240             // if there is M in a string but there is no value for months,
241
// throw an exception
242
if (start == end) {
243                 throw new IllegalArgumentException JavaDoc(
244                         Messages.getMessage("badDateDuration"));
245             }
246             if (end != -1) {
247                 months = Integer.parseInt(date.substring(start, end));
248                 start = end + 1;
249             }
250
251             end = date.indexOf("D");
252             // if there is D in a string but there is no value for days,
253
// throw an exception
254
if (start == end) {
255                 throw new IllegalArgumentException JavaDoc(
256                         Messages.getMessage("badDateDuration"));
257             }
258             if (end != -1) {
259                 days = Integer.parseInt(date.substring(start, end));
260             }
261         } catch (NumberFormatException JavaDoc e) {
262             throw new IllegalArgumentException JavaDoc(
263                     Messages.getMessage("badDateDuration"));
264         }
265     }
266
267     /**
268      *
269      */

270     public boolean isNegative() {
271         return isNegative;
272     }
273
274     /**
275      *
276      */

277     public int getYears() {
278         return years;
279     }
280
281     /**
282      *
283      */

284     public int getMonths() {
285         return months;
286     }
287
288     /**
289      *
290      */

291     public int getDays() {
292         return days;
293     }
294
295     /**
296      *
297      */

298     public int getHours() {
299         return hours;
300     }
301
302     /**
303      *
304      */

305     public int getMinutes() {
306         return minutes;
307     }
308
309     /**
310      *
311      */

312     public double getSeconds() {
313         return seconds;
314     }
315
316     /**
317      * @param negative
318      */

319     public void setNegative(boolean negative) {
320         isNegative = negative;
321     }
322
323     /**
324      * @param years
325      */

326     public void setYears(int years) {
327         this.years = years;
328     }
329
330     /**
331      * @param months
332      */

333     public void setMonths(int months) {
334         this.months = months;
335     }
336
337     /**
338      * @param days
339      */

340     public void setDays(int days) {
341         this.days = days;
342     }
343
344     /**
345      * @param hours
346      */

347     public void setHours(int hours) {
348         this.hours = hours;
349     }
350
351     /**
352      * @param minutes
353      */

354     public void setMinutes(int minutes) {
355         this.minutes = minutes;
356     }
357
358     /**
359      * @param seconds
360      * @deprecated use {@link #setSeconds(double) setSeconds(double)}
361      * instead
362      */

363     public void setSeconds(int seconds) {
364         this.seconds = seconds;
365     }
366
367     /**
368      * Sets the seconds. NOTE: The fractional value of seconds is rounded up to
369      * milliseconds.
370      *
371      * @param seconds double
372      */

373     public void setSeconds(double seconds) {
374         this.seconds = ((double) (Math.round(seconds * 100))) / 100;
375     }
376
377     /**
378      * This returns the xml representation of an xsd:duration object.
379      */

380     public String JavaDoc toString() {
381         StringBuffer JavaDoc duration = new StringBuffer JavaDoc();
382
383         duration.append("P");
384
385         if (years != 0) {
386             duration.append(years + "Y");
387         }
388         if (months != 0) {
389             duration.append(months + "M");
390         }
391         if (days != 0) {
392             duration.append(days + "D");
393         }
394         if (hours != 0 || minutes != 0 || seconds != 0.0) {
395             duration.append("T");
396
397             if (hours != 0) {
398                 duration.append(hours + "H");
399
400             }
401             if (minutes != 0) {
402                 duration.append(minutes + "M");
403
404             }
405             if (seconds != 0) {
406                 if (seconds == (int) seconds) {
407                     duration.append((int) seconds + "S");
408                 } else {
409                     duration.append(seconds + "S");
410                 }
411             }
412         }
413
414         if (duration.length() == 1) {
415             duration.append("T0S");
416         }
417
418         if (isNegative) {
419             duration.insert(0, "-");
420         }
421
422         return duration.toString();
423     }
424
425     /**
426      * The equals method compares the time represented by duration object, not
427      * its string representation.
428      * Hence, a duration object representing 65 minutes is considered equal to a
429      * duration object representing 1 hour and 5 minutes.
430      *
431      * @param object
432      */

433     public boolean equals(Object JavaDoc object) {
434         if (!(object instanceof Duration)) {
435             return false;
436         }
437
438         Calendar JavaDoc thisCalendar = this.getAsCalendar();
439         Duration duration = (Duration) object;
440
441         return this.isNegative == duration.isNegative &&
442                 this.getAsCalendar().equals(duration.getAsCalendar());
443     }
444
445     public int hashCode() {
446         int hashCode = 0;
447
448         if (isNegative) {
449             hashCode++;
450         }
451         hashCode += years;
452         hashCode += months;
453         hashCode += days;
454         hashCode += hours;
455         hashCode += minutes;
456         hashCode += seconds;
457         // milliseconds
458
hashCode += (seconds * 100) % 100;
459
460         return hashCode;
461     }
462
463     /**
464      * Returns duration as a calendar. Due to the way a Calendar class works,
465      * the values for particular fields may not be the same as obtained through
466      * getter methods. For example, if a duration's object getMonths
467      * returns 20, a similar call on a calendar object will return 1 year and
468      * 8 months.
469      *
470      * @return Calendar
471      */

472     public Calendar JavaDoc getAsCalendar() {
473         return getAsCalendar(Calendar.getInstance());
474     }
475
476     /**
477      * Returns duration as a calendar. Due to the way a Calendar class works,
478      * the values for particular fields may not be the same as obtained through
479      * getter methods. For example, if a Duration's object getMonths
480      * returns 20, a similar call on a Calendar object will return 1 year and
481      * 8 months.
482      *
483      * @param startTime Calendar
484      * @return Calendar
485      */

486     public Calendar JavaDoc getAsCalendar(Calendar JavaDoc startTime) {
487         Calendar JavaDoc ret = (Calendar JavaDoc) startTime.clone();
488         ret.set(Calendar.YEAR, years);
489         ret.set(Calendar.MONTH, months);
490         ret.set(Calendar.DATE, days);
491         ret.set(Calendar.HOUR, hours);
492         ret.set(Calendar.MINUTE, minutes);
493         ret.set(Calendar.SECOND, (int) seconds);
494         ret.set(Calendar.MILLISECOND,
495                 (int) (seconds * 100 - Math.round(seconds) * 100));
496         return ret;
497     }
498 }
499
Popular Tags