KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > schema > datatypes > AbstractDateTimeType


1 /*
2  * This file belongs to the XQuark distribution.
3  * Copyright (C) 2003 Universite de Versailles Saint-Quentin.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307.
18  * You can also get it at http://www.gnu.org/licenses/lgpl.html
19  *
20  * For more information on this software, see http://www.xquark.org.
21  */

22
23 package org.xquark.schema.datatypes;
24
25 import java.text.FieldPosition JavaDoc;
26 import java.text.ParsePosition JavaDoc;
27 import java.text.SimpleDateFormat JavaDoc;
28 import java.util.Date JavaDoc;
29
30 import org.apache.xerces.impl.xpath.regex.RegularExpression;
31 import org.xquark.schema.SchemaException;
32 import org.xquark.schema.validation.ValidationContextProvider;
33
34
35 abstract class AbstractDateTimeType extends ComparableType {
36     private static final String JavaDoc RCSRevision = "$Revision: 1.2 $";
37     private static final String JavaDoc RCSName = "$Name: $";
38     private static int[] POWERSOFTEN = { 1, 10, 100, 1000 };
39     protected static final String JavaDoc TIMEZONE_PATTERN = "((((\\+)|(\\-))[0-9]{2}:[0-9]{2})|Z)?";
40
41     private SimpleDateFormat JavaDoc timezoneFormat;
42     private FieldPosition JavaDoc emptyFieldPosition = new FieldPosition JavaDoc(0);
43         
44     AbstractDateTimeType(String JavaDoc name, int nType) {
45         super(name, nType);
46         timezoneFormat = new SimpleDateFormat JavaDoc("HH:mm");
47         timezoneFormat.setLenient(false);
48     }
49
50     protected Object JavaDoc toValidType(Object JavaDoc data) {
51         return (Date JavaDoc) data;
52     }
53     
54     protected abstract SimpleDateFormat JavaDoc getDateTimeFormat();
55     
56     protected abstract RegularExpression getRegularExpression();
57
58     protected abstract boolean isTimeFormat();
59     
60     protected abstract boolean isDateFormat();
61     
62     protected abstract DateTime createDateTime(long millis, long tz, boolean tzSpecified);
63     
64     protected Comparable JavaDoc toComparable(String JavaDoc value) throws SchemaException {
65         RegularExpression regex = getRegularExpression();
66         if (!regex.matches(value))
67             super.invalidValue(value);
68         int len = value.length();
69         SimpleDateFormat JavaDoc format = getDateTimeFormat();
70         ParsePosition JavaDoc pos = new ParsePosition JavaDoc(0);
71         Date JavaDoc date = null;
72         if (len > 1 && value.charAt(0) == '-' && value.charAt(1) != '-') {
73             // First check that the date is valid without the leading minus sign
74
format.setLenient(false);
75             pos.setIndex(1);
76             date = format.parse(value, pos);
77             if (date == null) super.invalidValue(value);
78             // Change to lenient to accept leading minus sign and compute real value
79
format.setLenient(true);
80             pos.setIndex(0);
81             date = format.parse(value, pos);
82         } else {
83             format.setLenient(false);
84             date = format.parse(value, pos);
85             if (date == null) super.invalidValue(value);
86         }
87         long tz = 0;
88         long millis = 0;
89         boolean tzSpecified = false;
90         int index = pos.getIndex();
91         if (isTimeFormat() && index < len && value.charAt(index) == '.') {
92             index++;
93             int count = 0;
94             while (index < len) {
95                 char c = value.charAt(index++);
96                 if (!Character.isDigit(c)) break;
97                 millis *= 10;
98                 millis += ((int) c - (int) '0');
99                 count++;
100             }
101             if (count > 3) {
102                 // truncate milliseconds digits after the third
103
millis = (long)(millis/Math.pow(10, count-3));
104             } else {
105                 millis *= POWERSOFTEN[3 - count];
106             }
107         }
108         if (index < len) {
109             tzSpecified = true;
110             char c = value.charAt(index);
111             // check if value has a time zone
112
if (c == 'Z') {
113                 tz = 0;
114                 index++;
115             } else if (c == '+') {
116                 pos.setIndex(index+1);
117                 Date JavaDoc tzDate = timezoneFormat.parse(value, pos);
118                 if (tzDate == null) super.invalidValue(value);
119                 tz = tzDate.getTime();
120                 if (tz > DateTime.MAX_TIMEZONE_OFFSET) super.invalidValue(value);
121                 index = pos.getIndex();
122             } else if (c == '-') {
123                 pos.setIndex(index+1);
124                 Date JavaDoc tzDate = timezoneFormat.parse(value, pos);
125                 if (tzDate == null) super.invalidValue(value);
126                 tz = -tzDate.getTime();
127                 if (tz < -DateTime.MAX_TIMEZONE_OFFSET) super.invalidValue(value);
128                 index = pos.getIndex();
129             } else {
130                 super.invalidValue(value);
131             }
132         }
133         if (index != len)
134             super.invalidValue(value);
135         return createDateTime(date.getTime()+millis, tz, tzSpecified);
136     }
137
138     public String JavaDoc toXMLString(Object JavaDoc data, ValidationContextProvider context) {
139         if (!isTimeFormat()) return stringValue(data);
140         if (data == null) return null;
141         Date JavaDoc date = (Date JavaDoc) data;
142         StringBuffer JavaDoc result = new StringBuffer JavaDoc(20);
143         SimpleDateFormat JavaDoc format = getDateTimeFormat();
144         format.format(date, result, emptyFieldPosition);
145         long millis = date.getTime() % 1000;
146         if (millis > 0) {
147             result.append('.');
148             if (millis < 10) {
149                 result.append("00");
150                 result.append(millis);
151             } else if (millis < 100) {
152                 result.append("0");
153                 result.append(millis);
154             } else {
155                 result.append(millis);
156             }
157             int len = result.length();
158             while (result.charAt(len-1) == '0') {
159                 result.setLength(len-1);
160                 len--;
161             }
162         }
163         if (date instanceof DateTime && ((DateTime) date).hasTimeZone()) {
164             result.append('Z');
165         }
166         return result.toString();
167     }
168     
169     protected String JavaDoc stringValue(Object JavaDoc data) {
170         if (data == null) return null;
171         Date JavaDoc date = (Date JavaDoc) data;
172         StringBuffer JavaDoc result = new StringBuffer JavaDoc(20);
173         SimpleDateFormat JavaDoc format = getDateTimeFormat();
174         long tz = 0;
175         boolean tzSpecified = false;
176         if (date instanceof DateTime && ((DateTime) date).hasTimeZone()) {
177             tz = ((DateTime) date).getTimeZone();
178             tzSpecified = true;
179         }
180         long time = date.getTime();
181         long millis = time % 1000;
182         format.format(new Date JavaDoc(time+tz), result, emptyFieldPosition);
183         if (millis > 0) {
184             result.append('.');
185             if (millis < 10) {
186                 result.append("00");
187                 result.append(millis);
188             } else if (millis < 100) {
189                 result.append("0");
190                 result.append(millis);
191             } else {
192                 result.append(millis);
193             }
194             int len = result.length();
195             while (result.charAt(len-1) == '0') {
196                 result.setLength(len-1);
197                 len--;
198             }
199         }
200         if (tzSpecified) {
201             if (tz == 0) {
202                 result.append('Z');
203             } else if (tz > 0) {
204                 result.append('+');
205                 timezoneFormat.format(new Date JavaDoc(tz), result, emptyFieldPosition);
206             } else {
207                 result.append('-');
208                 timezoneFormat.format(new Date JavaDoc(-tz), result, emptyFieldPosition);
209             }
210         }
211         return result.toString();
212     }
213
214 }
215
Popular Tags