Imported GNU Classpath 0.90
[official-gcc.git] / libjava / classpath / gnu / xml / validation / datatype / TimeType.java
blob0152e11717da5bfa740eab358e90dfebb6b1c722
1 /* TimeType.java --
2 Copyright (C) 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package gnu.xml.validation.datatype;
40 import java.util.TimeZone;
41 import javax.xml.XMLConstants;
42 import javax.xml.namespace.QName;
43 import org.relaxng.datatype.DatatypeException;
44 import org.relaxng.datatype.ValidationContext;
46 /**
47 * The XML Schema time type.
49 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
51 final class TimeType
52 extends AtomicSimpleType
55 static class Time
56 implements Comparable
58 int minutes;
59 float seconds;
61 public int hashCode()
63 return minutes * 31 + new Float(seconds).hashCode();
66 public boolean equals(Object other)
68 if (other instanceof Time)
70 Time time = (Time) other;
71 return time.minutes == minutes && time.seconds == seconds;
73 return false;
76 public int compareTo(Object other)
78 if (other instanceof Time)
80 Time time = (Time) other;
81 if (time.minutes != minutes)
82 return minutes - time.minutes;
83 if (time.seconds == seconds)
84 return 0;
85 return (seconds < time.seconds) ? -1 : 1;
87 return 0;
92 static final int[] CONSTRAINING_FACETS = {
93 Facet.PATTERN,
94 Facet.ENUMERATION,
95 Facet.WHITESPACE,
96 Facet.MAX_INCLUSIVE,
97 Facet.MAX_EXCLUSIVE,
98 Facet.MIN_INCLUSIVE,
99 Facet.MIN_EXCLUSIVE
102 TimeType()
104 super(new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "time"),
105 TypeLibrary.ANY_SIMPLE_TYPE);
108 public int[] getConstrainingFacets()
110 return CONSTRAINING_FACETS;
113 public void checkValid(String value, ValidationContext context)
114 throws DatatypeException
116 super.checkValid(value, context);
117 int len = value.length();
118 int state = 3;
119 int start = 0;
120 for (int i = 0; i < len; i++)
122 char c = value.charAt(i);
123 if (c == '-' && state == 0)
125 start++;
126 continue;
128 if (c >= 0x30 && c <= 0x39)
129 continue;
130 switch (state)
132 case 3: // hour
133 if (c == ':')
135 if (i - start != 2)
136 throw new DatatypeException(i, "invalid time value");
137 state = 4;
138 start = i + 1;
139 continue;
141 break;
142 case 4: // minute
143 if (c == ':')
145 if (i - start != 2)
146 throw new DatatypeException(i, "invalid time value");
147 state = 5;
148 start = i + 1;
149 continue;
151 break;
152 case 5: // second
153 if (c == '.')
155 if (i - start != 2)
156 throw new DatatypeException(i, "invalid time value");
157 state = 6;
158 start = i + 1;
159 continue;
161 else if (c == ' ')
163 if (i - start != 2)
164 throw new DatatypeException(i, "invalid time value");
165 state = 7;
166 start = i + 1;
167 continue;
169 break;
170 case 6: // second fraction
171 if (c == ' ')
173 state = 7;
174 start = i + 1;
175 continue;
177 break;
178 case 7: // timezone 1
179 if (start == i)
181 if (c == '+' || c == '-')
182 continue;
183 else if (c == 'Z')
185 state = 9;
186 start = i + 1;
187 continue;
190 if (c == ':')
192 if (i - start != 2)
193 throw new DatatypeException(i, "invalid time value");
194 state = 8;
195 start = i + 1;
196 continue;
198 break;
200 throw new DatatypeException(i, "invalid time value");
202 switch (state)
204 case 5: // second
205 if (len - start != 2)
206 throw new DatatypeException(len, "invalid time value");
207 break;
208 case 6: // second fraction
209 break;
210 case 8: // timezone 2
211 if (len - start != 2)
212 throw new DatatypeException(len, "invalid time value");
213 break;
214 case 9: // post Z
215 break;
216 default:
217 throw new DatatypeException(len, "invalid time value");
221 public Object createValue(String value, ValidationContext context) {
222 int len = value.length();
223 int state = 3;
224 int start = 0;
225 Time time = new Time();
228 for (int i = 0; i < len; i++)
230 char c = value.charAt(i);
231 if (c >= 0x30 && c <= 0x39)
232 continue;
233 switch (state)
235 case 3: // hour
236 if (c == ':')
238 time.minutes =
239 Integer.parseInt(value.substring(start, i)) * 60;
240 state = 4;
241 start = i + 1;
242 continue;
244 break;
245 case 4: // minute
246 if (c == ':')
248 time.minutes +=
249 Integer.parseInt(value.substring(start, i));
250 state = 5;
251 start = i + 1;
252 continue;
254 break;
255 case 5: // second
256 if (c == ' ')
258 time.seconds =
259 Float.parseFloat(value.substring(start, i));
260 state = 7;
261 start = i + 1;
262 continue;
264 break;
267 // end of input
268 if (len - start > 0 && state == 7)
270 // Timezone
271 String timezone = value.substring(len - start);
272 int i = timezone.indexOf(':');
273 if (i == -1)
275 if ("Z".equals(timezone))
276 timezone = "UTC";
277 TimeZone tz = TimeZone.getTimeZone(timezone);
278 if (tz == null)
279 return null;
280 time.minutes += tz.getRawOffset();
282 else
284 String tzh = timezone.substring(0, i);
285 String tzm = timezone.substring(i + 1);
286 int offset = Integer.parseInt(tzh) * 60;
287 if (offset < 0)
288 offset -= Integer.parseInt(tzm);
289 else
290 offset += Integer.parseInt(tzm);
291 time.minutes += offset;
294 return time;
296 catch (NumberFormatException e)
298 return null;