KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xerces > internal > impl > dv > xs > AbstractDateTimeDV


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999-2003 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 2001, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package com.sun.org.apache.xerces.internal.impl.dv.xs;
59
60 /**
61  * This is the base class of all date/time datatype validators.
62  * It implements common code for parsing, validating and comparing datatypes.
63  * Classes that extend this class, must implement parse() method.
64  *
65  * REVISIT: There are many instance variables, which would cause problems
66  * when we support grammar caching. A grammar is possibly used by
67  * two parser instances at the same time, then the same simple type
68  * decl object can be used to validate two strings at the same time.
69  * -SG
70  *
71  * @author Elena Litani
72  * @author Len Berman
73  * @author Gopal Sharma, SUN Microsystems Inc.
74  *
75  * @version $Id: AbstractDateTimeDV.java,v 1.12 2003/06/16 18:15:51 sandygao Exp $
76  */

77 public abstract class AbstractDateTimeDV extends TypeValidator {
78
79     //debugging
80
private static final boolean DEBUG=false;
81
82     //define shared variables for date/time
83

84     //define constants
85
protected final static int CY = 0, M = 1, D = 2, h = 3,
86     m = 4, s = 5, ms = 6, utc=7, hh=0, mm=1;
87
88     //size for all objects must have the same fields:
89
//CCYY, MM, DD, h, m, s, ms + timeZone
90
protected final static int TOTAL_SIZE = 8;
91
92     //define constants to be used in assigning default values for
93
//all date/time excluding duration
94
protected final static int YEAR=2000;
95     protected final static int MONTH=01;
96     protected final static int DAY = 15;
97
98     public short getAllowedFacets(){
99         return ( XSSimpleTypeDecl.FACET_PATTERN | XSSimpleTypeDecl.FACET_WHITESPACE | XSSimpleTypeDecl.FACET_ENUMERATION |XSSimpleTypeDecl.FACET_MAXINCLUSIVE |XSSimpleTypeDecl.FACET_MININCLUSIVE | XSSimpleTypeDecl.FACET_MAXEXCLUSIVE | XSSimpleTypeDecl.FACET_MINEXCLUSIVE );
100     }//getAllowedFacets()
101

102     // the parameters are in compiled form (from getActualValue)
103
public int compare (Object JavaDoc value1, Object JavaDoc value2) {
104         return compareDates(((DateTimeData)value1).data,
105                             ((DateTimeData)value2).data, true);
106     }//compare()
107

108     /**
109      * Compare algorithm described in dateDime (3.2.7).
110      * Duration datatype overwrites this method
111      *
112      * @param date1 normalized date representation of the first value
113      * @param date2 normalized date representation of the second value
114      * @param strict
115      * @return less, greater, less_equal, greater_equal, equal
116      */

117     protected short compareDates(int[] date1, int[] date2, boolean strict) {
118         if ( date1[utc]==date2[utc] ) {
119             return compareOrder(date1, date2);
120         }
121         short c1, c2;
122         
123         int[] tempDate = new int[TOTAL_SIZE];
124         int[] timeZone = new int[2];
125
126         if ( date1[utc]=='Z' ) {
127
128             //compare date1<=date1<=(date2 with time zone -14)
129
//
130
cloneDate(date2, tempDate); //clones date1 value to global temporary storage: fTempDate
131
timeZone[hh]=14;
132             timeZone[mm]=0;
133             tempDate[utc]='+';
134             normalize(tempDate, timeZone);
135             c1 = compareOrder(date1, tempDate);
136             if (c1 == LESS_THAN)
137                 return c1;
138
139             //compare date1>=(date2 with time zone +14)
140
//
141
cloneDate(date2, tempDate); //clones date1 value to global temporary storage: tempDate
142
timeZone[hh]=14;
143             timeZone[mm]=0;
144             tempDate[utc]='-';
145             normalize(tempDate, timeZone);
146             c2 = compareOrder(date1, tempDate);
147             if (c2 == GREATER_THAN)
148                 return c2;
149
150             return INDETERMINATE;
151         }
152         else if ( date2[utc]=='Z' ) {
153
154             //compare (date1 with time zone -14)<=date2
155
//
156
cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate
157
timeZone[hh]=14;
158             timeZone[mm]=0;
159             tempDate[utc]='-';
160             if (DEBUG) {
161                System.out.println("tempDate=" + dateToString(tempDate));
162             }
163             normalize(tempDate, timeZone);
164             c1 = compareOrder(tempDate, date2);
165             if (DEBUG) {
166                 System.out.println("date=" + dateToString(date2));
167                 System.out.println("tempDate=" + dateToString(tempDate));
168             }
169             if (c1 == LESS_THAN)
170                 return c1;
171
172             //compare (date1 with time zone +14)<=date2
173
//
174
cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate
175
timeZone[hh]=14;
176             timeZone[mm]=0;
177             tempDate[utc]='+';
178             normalize(tempDate, timeZone);
179             c2 = compareOrder(tempDate, date2);
180             if (DEBUG) {
181                System.out.println("tempDate=" + dateToString(tempDate));
182             }
183             if (c2 == GREATER_THAN)
184                 return c2;
185
186             return INDETERMINATE;
187         }
188         return INDETERMINATE;
189
190     }
191
192     /**
193      * Given normalized values, determines order-relation
194      * between give date/time objects.
195      *
196      * @param date1 date/time object
197      * @param date2 date/time object
198      * @return 0 if date1 and date2 are equal, a value less than 0 if date1 is less than date2, a value greater than 0 if date1 is greater than date2
199      */

200     protected short compareOrder (int[] date1, int[] date2) {
201
202         for ( int i=0;i<TOTAL_SIZE;i++ ) {
203             if ( date1[i]<date2[i] ) {
204                 return -1;
205             }
206             else if ( date1[i]>date2[i] ) {
207                 return 1;
208             }
209         }
210         return 0;
211     }
212
213     /**
214      * Parses time hh:mm:ss.sss and time zone if any
215      *
216      * @param start
217      * @param end
218      * @param data
219      * @exception RuntimeException
220      */

221     protected void getTime (String JavaDoc buffer, int start, int end, int[] data, int[] timeZone) throws RuntimeException JavaDoc{
222
223         int stop = start+2;
224
225         //get hours (hh)
226
data[h]=parseInt(buffer, start,stop);
227
228         //get minutes (mm)
229

230         if (buffer.charAt(stop++)!=':') {
231                 throw new RuntimeException JavaDoc("Error in parsing time zone" );
232         }
233         start = stop;
234         stop = stop+2;
235         data[m]=parseInt(buffer, start,stop);
236
237         //get seconds (ss)
238
if (buffer.charAt(stop++)!=':') {
239                 throw new RuntimeException JavaDoc("Error in parsing time zone" );
240         }
241         start = stop;
242         stop = stop+2;
243         data[s]=parseInt(buffer, start,stop);
244
245         if (stop == end)
246             return;
247         
248         //get miliseconds (ms)
249
start = stop;
250         int milisec = buffer.charAt(start) == '.' ? start : -1;
251
252         //find UTC sign if any
253
int sign = findUTCSign(buffer, start, end);
254
255         //parse miliseconds
256
if ( milisec != -1 ) {
257             // The end of millisecond part is between . and
258
// either the end of the UTC sign
259
start = sign < 0 ? end : sign;
260             data[ms]=parseInt(buffer, milisec+1, start);
261         }
262
263         //parse UTC time zone (hh:mm)
264
if ( sign>0 ) {
265             if (start != sign)
266                 throw new RuntimeException JavaDoc("Error in parsing time zone" );
267             getTimeZone(buffer, data, sign, end, timeZone);
268         }
269         else if (start != end) {
270             throw new RuntimeException JavaDoc("Error in parsing time zone" );
271         }
272     }
273
274     /**
275      * Parses date CCYY-MM-DD
276      *
277      * @param start
278      * @param end
279      * @param data
280      * @exception RuntimeException
281      */

282     protected int getDate (String JavaDoc buffer, int start, int end, int[] date) throws RuntimeException JavaDoc{
283
284         start = getYearMonth(buffer, start, end, date);
285
286         if (buffer.charAt(start++) !='-') {
287             throw new RuntimeException JavaDoc("CCYY-MM must be followed by '-' sign");
288         }
289         int stop = start + 2;
290         date[D]=parseInt(buffer, start, stop);
291         return stop;
292     }
293
294     /**
295      * Parses date CCYY-MM
296      *
297      * @param start
298      * @param end
299      * @param data
300      * @exception RuntimeException
301      */

302     protected int getYearMonth (String JavaDoc buffer, int start, int end, int[] date) throws RuntimeException JavaDoc{
303
304         if ( buffer.charAt(0)=='-' ) {
305             // REVISIT: date starts with preceding '-' sign
306
// do we have to do anything with it?
307
//
308
start++;
309         }
310         int i = indexOf(buffer, start, end, '-');
311         if ( i==-1 ) throw new RuntimeException JavaDoc("Year separator is missing or misplaced");
312         int length = i-start;
313         if (length<4) {
314             throw new RuntimeException JavaDoc("Year must have 'CCYY' format");
315         }
316         else if (length > 4 && buffer.charAt(start)=='0'){
317             throw new RuntimeException JavaDoc("Leading zeros are required if the year value would otherwise have fewer than four digits; otherwise they are forbidden");
318         }
319         date[CY]= parseIntYear(buffer, i);
320         if (buffer.charAt(i)!='-') {
321             throw new RuntimeException JavaDoc("CCYY must be followed by '-' sign");
322         }
323         start = ++i;
324         i = start +2;
325         date[M]=parseInt(buffer, start, i);
326         return i; //fStart points right after the MONTH
327
}
328
329     /**
330      * Shared code from Date and YearMonth datatypes.
331      * Finds if time zone sign is present
332      *
333      * @param end
334      * @param date
335      * @exception RuntimeException
336      */

337     protected void parseTimeZone (String JavaDoc buffer, int start, int end, int[] date, int[] timeZone) throws RuntimeException JavaDoc{
338
339         //fStart points right after the date
340

341         if ( start<end ) {
342             int sign = findUTCSign(buffer, start, end);
343             if ( sign<0 ) {
344                 throw new RuntimeException JavaDoc ("Error in month parsing");
345             }
346             else {
347                 getTimeZone(buffer, date, sign, end, timeZone);
348             }
349         }
350     }
351
352     /**
353      * Parses time zone: 'Z' or {+,-} followed by hh:mm
354      *
355      * @param data
356      * @param sign
357      * @exception RuntimeException
358      */

359     protected void getTimeZone (String JavaDoc buffer, int[] data, int sign, int end, int[] timeZone) throws RuntimeException JavaDoc{
360         data[utc]=buffer.charAt(sign);
361
362         if ( buffer.charAt(sign) == 'Z' ) {
363             if (end>(++sign)) {
364                 throw new RuntimeException JavaDoc("Error in parsing time zone");
365             }
366             return;
367         }
368         if ( sign<=(end-6) ) {
369
370             //parse [hh]
371
int stop = ++sign+2;
372             timeZone[hh]=parseInt(buffer, sign, stop);
373             if (buffer.charAt(stop++)!=':') {
374                 throw new RuntimeException JavaDoc("Error in parsing time zone" );
375             }
376
377             //parse [ss]
378
timeZone[mm]=parseInt(buffer, stop, stop+2);
379
380             if ( stop+2!=end ) {
381                 throw new RuntimeException JavaDoc("Error in parsing time zone");
382             }
383
384         }
385         else {
386             throw new RuntimeException JavaDoc("Error in parsing time zone");
387         }
388         if ( DEBUG ) {
389             System.out.println("time[hh]="+timeZone[hh] + " time[mm]=" +timeZone[mm]);
390         }
391     }
392
393     /**
394      * Computes index of given char within StringBuffer
395      *
396      * @param start
397      * @param end
398      * @param ch character to look for in StringBuffer
399      * @return index of ch within StringBuffer
400      */

401     protected int indexOf (String JavaDoc buffer, int start, int end, char ch) {
402         for ( int i=start;i<end;i++ ) {
403             if ( buffer.charAt(i) == ch ) {
404                 return i;
405             }
406         }
407         return -1;
408     }
409
410     /**
411      * Validates given date/time object accoring to W3C PR Schema
412      * [D.1 ISO 8601 Conventions]
413      *
414      * @param data
415      */

416     protected void validateDateTime (int[] data, int[] timeZone) {
417
418         //REVISIT: should we throw an exception for not valid dates
419
// or reporting an error message should be sufficient?
420
if ( data[CY]==0 ) {
421             throw new RuntimeException JavaDoc("The year \"0000\" is an illegal year value");
422
423         }
424
425         if ( data[M]<1 || data[M]>12 ) {
426             throw new RuntimeException JavaDoc("The month must have values 1 to 12");
427
428         }
429
430         //validate days
431
if ( data[D]>maxDayInMonthFor(data[CY], data[M]) || data[D]<1 ) {
432             throw new RuntimeException JavaDoc("The day must have values 1 to 31");
433         }
434
435         //validate hours
436
if ( data[h]>23 || data[h]<0 ) {
437             if (data[h] == 24 && data[m] == 0 && data[s] == 0 && data[ms] == 0) {
438                 data[h] = 0;
439                 if (++data[D] > maxDayInMonthFor(data[CY], data[M])) {
440                     data[D] = 1;
441                     if (++data[M] > 12) {
442                         data[M] = 1;
443                         if (++data[CY] == 0)
444                             data[CY] = 1;
445                     }
446                 }
447             }
448             else {
449                 throw new RuntimeException JavaDoc("Hour must have values 0-23, unless 24:00:00");
450             }
451         }
452
453         //validate
454
if ( data[m]>59 || data[m]<0 ) {
455             throw new RuntimeException JavaDoc("Minute must have values 0-59");
456         }
457
458         //validate
459
if ( data[s]>60 || data[s]<0 ) {
460             throw new RuntimeException JavaDoc("Second must have values 0-60");
461
462         }
463
464         //validate
465
if ( timeZone[hh]>14 || timeZone[hh]<-14 ) {
466             throw new RuntimeException JavaDoc("Time zone should have range -14..+14");
467         }
468
469         //validate
470
if ( timeZone[mm]>59 || timeZone[mm]<-59 ) {
471             throw new RuntimeException JavaDoc("Minute must have values 0-59");
472         }
473     }
474
475     /**
476      * Return index of UTC char: 'Z', '+', '-'
477      *
478      * @param start
479      * @param end
480      * @return index of the UTC character that was found
481      */

482     protected int findUTCSign (String JavaDoc buffer, int start, int end) {
483         int c;
484         for ( int i=start;i<end;i++ ) {
485             c=buffer.charAt(i);
486             if ( c == 'Z' || c=='+' || c=='-' ) {
487                 return i;
488             }
489
490         }
491         return -1;
492     }
493
494     /**
495      * Given start and end position, parses string value
496      *
497      * @param value string to parse
498      * @param start Start position
499      * @param end end position
500      * @return return integer representation of characters
501      */

502     protected int parseInt (String JavaDoc buffer, int start, int end)
503     throws NumberFormatException JavaDoc{
504         //REVISIT: more testing on this parsing needs to be done.
505
int radix=10;
506         int result = 0;
507         int digit=0;
508         int limit = -Integer.MAX_VALUE;
509         int multmin = limit / radix;
510         int i = start;
511         do {
512             digit = getDigit(buffer.charAt(i));
513             if ( digit < 0 ) throw new NumberFormatException JavaDoc("'"+buffer.toString()+"' has wrong format");
514             if ( result < multmin ) throw new NumberFormatException JavaDoc("'"+buffer.toString()+"' has wrong format");
515             result *= radix;
516             if ( result < limit + digit ) throw new NumberFormatException JavaDoc("'"+buffer.toString()+"' has wrong format");
517             result -= digit;
518
519         }while ( ++i < end );
520         return -result;
521     }
522
523     // parse Year differently to support negative value.
524
protected int parseIntYear (String JavaDoc buffer, int end){
525         int radix=10;
526         int result = 0;
527         boolean negative = false;
528         int i=0;
529         int limit;
530         int multmin;
531         int digit=0;
532
533         if (buffer.charAt(0) == '-'){
534             negative = true;
535             limit = Integer.MIN_VALUE;
536             i++;
537
538         }
539         else{
540             limit = -Integer.MAX_VALUE;
541         }
542         multmin = limit / radix;
543         while (i < end)
544         {
545             digit = getDigit(buffer.charAt(i++));
546             if (digit < 0) throw new NumberFormatException JavaDoc("'"+buffer.toString()+"' has wrong format");
547             if (result < multmin) throw new NumberFormatException JavaDoc("'"+buffer.toString()+"' has wrong format");
548             result *= radix;
549             if (result < limit + digit) throw new NumberFormatException JavaDoc("'"+buffer.toString()+"' has wrong format");
550             result -= digit;
551         }
552
553         if (negative)
554         {
555             if (i > 1) return result;
556             else throw new NumberFormatException JavaDoc("'"+buffer.toString()+"' has wrong format");
557         }
558         return -result;
559
560     }
561
562     /**
563      * If timezone present - normalize dateTime [E Adding durations to dateTimes]
564      *
565      * @param date CCYY-MM-DDThh:mm:ss+03
566      * @return CCYY-MM-DDThh:mm:ssZ
567      */

568     protected void normalize (int[] date, int[] timeZone) {
569
570         // REVISIT: we have common code in addDuration() for durations
571
// should consider reorganizing it.
572
//
573

574         //add minutes (from time zone)
575
int negate = 1;
576         if (date[utc]=='+') {
577             negate = -1;
578         }
579         if ( DEBUG ) {
580             System.out.println("==>date[m]"+date[m]);
581             System.out.println("==>timeZone[mm]" +timeZone[mm]);
582         }
583         int temp = date[m] + negate*timeZone[mm];
584         int carry = fQuotient (temp, 60);
585         date[m]= mod(temp, 60, carry);
586
587         if ( DEBUG ) {
588             System.out.println("==>carry: " + carry);
589         }
590         //add hours
591
temp = date[h] + negate*timeZone[hh] + carry;
592         carry = fQuotient(temp, 24);
593         date[h]=mod(temp, 24, carry);
594         if ( DEBUG ) {
595             System.out.println("==>date[h]"+date[h]);
596             System.out.println("==>carry: " + carry);
597         }
598
599         date[D]=date[D]+carry;
600
601         while ( true ) {
602             temp=maxDayInMonthFor(date[CY], date[M]);
603             if (date[D]<1) {
604                 date[D] = date[D] + maxDayInMonthFor(date[CY], date[M]-1);
605                 carry=-1;
606             }
607             else if ( date[D]>temp ) {
608                 date[D]=date[D]-temp;
609                 carry=1;
610             }
611             else {
612                 break;
613             }
614             temp=date[M]+carry;
615             date[M]=modulo(temp, 1, 13);
616             date[CY]=date[CY]+fQuotient(temp, 1, 13);
617         }
618         date[utc]='Z';
619     }
620
621
622     /**
623      * Resets object representation of date/time
624      *
625      * @param data date/time object
626      */

627     protected void resetDateObj (int[] data) {
628         for ( int i=0;i<TOTAL_SIZE;i++ ) {
629             data[i]=0;
630         }
631     }
632
633     /**
634      * Given {year,month} computes maximum
635      * number of days for given month
636      *
637      * @param year
638      * @param month
639      * @return integer containg the number of days in a given month
640      */

641     protected int maxDayInMonthFor(int year, int month) {
642         //validate days
643
if ( month==4 || month==6 || month==9 || month==11 ) {
644             return 30;
645         }
646         else if ( month==2 ) {
647             if ( isLeapYear(year) ) {
648                 return 29;
649             }
650             else {
651                 return 28;
652             }
653         }
654         else {
655             return 31;
656         }
657     }
658
659     private boolean isLeapYear(int year) {
660
661         //REVISIT: should we take care about Julian calendar?
662
return((year%4 == 0) && ((year%100 != 0) || (year%400 == 0)));
663     }
664
665     //
666
// help function described in W3C PR Schema [E Adding durations to dateTimes]
667
//
668
protected int mod (int a, int b, int quotient) {
669         //modulo(a, b) = a - fQuotient(a,b)*b
670
return (a - quotient*b) ;
671     }
672
673     //
674
// help function described in W3C PR Schema [E Adding durations to dateTimes]
675
//
676
protected int fQuotient (int a, int b) {
677
678         //fQuotient(a, b) = the greatest integer less than or equal to a/b
679
return (int)Math.floor((float)a/b);
680     }
681
682     //
683
// help function described in W3C PR Schema [E Adding durations to dateTimes]
684
//
685
protected int modulo (int temp, int low, int high) {
686         //modulo(a - low, high - low) + low
687
int a = temp - low;
688         int b = high - low;
689         return (mod (a, b, fQuotient(a, b)) + low) ;
690     }
691
692     //
693
// help function described in W3C PR Schema [E Adding durations to dateTimes]
694
//
695
protected int fQuotient (int temp, int low, int high) {
696         //fQuotient(a - low, high - low)
697

698         return fQuotient(temp - low, high - low);
699     }
700
701
702     protected String JavaDoc dateToString(int[] date) {
703         StringBuffer JavaDoc message = new StringBuffer JavaDoc(25);
704         append(message, date[CY], 4);
705         message.append('-');
706         append(message, date[M], 2);
707         message.append('-');
708         append(message, date[D], 2);
709         message.append('T');
710         append(message, date[h], 2);
711         message.append(':');
712         append(message, date[m], 2);
713         message.append(':');
714         append(message, date[s], 2);
715         message.append('.');
716         message.append(date[ms]);
717         append(message, (char)date[utc], 0);
718         return message.toString();
719     }
720     
721     protected void append(StringBuffer JavaDoc message, int value, int nch) {
722         if (value < 0) {
723             message.append('-');
724             value = -value;
725         }
726         if (nch == 4) {
727             if (value < 10)
728                 message.append("000");
729             else if (value < 100)
730                 message.append("00");
731             else if (value < 1000)
732                 message.append("0");
733             message.append(value);
734         }
735         else if (nch == 2) {
736             if (value < 10)
737                 message.append('0');
738             message.append(value);
739         }
740         else {
741             if (value != 0)
742                 message.append((char)value);
743         }
744     }
745
746     //
747
//Private help functions
748
//
749

750     private void cloneDate (int[] finalValue, int[] tempDate) {
751         System.arraycopy(finalValue, 0, tempDate, 0, TOTAL_SIZE);
752     }
753
754     /**
755      * Represents date time data
756      */

757     static final class DateTimeData {
758         // actual data stored in an int array
759
final int[] data;
760         // a pointer to the type that was used go generate this data
761
// note that this is not the actual simple type, but one of the
762
// statically created XXXDV objects, so this won't cause any GC problem.
763
final AbstractDateTimeDV type;
764         private String JavaDoc canonical;
765         public DateTimeData(int[] data, AbstractDateTimeDV type) {
766             this.data = data;
767             this.type = type;
768         }
769         public boolean equals(Object JavaDoc obj) {
770             if (!(obj instanceof DateTimeData))
771                 return false;
772             int[] odata = ((DateTimeData)obj).data;
773             return type.compareDates(data, odata, true)==0;
774         }
775         public synchronized String JavaDoc toString() {
776             if (canonical == null) {
777                 canonical = type.dateToString(data);
778             }
779             return canonical;
780         }
781     }
782 }
783
Popular Tags