KickJava   Java API By Example, From Geeks To Geeks.

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


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.util.*;
26
27 import org.apache.xerces.impl.xpath.regex.RegularExpression;
28 import org.xquark.schema.Facet;
29 import org.xquark.schema.SchemaConstants;
30 import org.xquark.schema.SchemaException;
31 import org.xquark.schema.validation.ValidationContextProvider;
32
33 public abstract class PrimitiveType implements Cloneable JavaDoc, SchemaConstants {
34     private static final String JavaDoc RCSRevision = "$Revision: 1.3 $";
35     private static final String JavaDoc RCSName = "$Name: $";
36     public static final int VOID = 0;
37     public static final int STRING = 1;
38     public static final int BOOLEAN = 2;
39     public static final int DECIMAL = 3;
40     public static final int DOUBLE = 4;
41     public static final int FLOAT = 5;
42     public static final int DURATION = 6;
43     public static final int DATE_TIME = 7;
44     public static final int TIME = 8;
45     public static final int DATE = 9;
46     public static final int GYEAR_MONTH = 10;
47     public static final int GYEAR = 11;
48     public static final int GMONTH_DAY = 12;
49     public static final int GDAY = 13;
50     public static final int GMONTH = 14;
51     public static final int HEX_BINARY = 15;
52     public static final int BASE64_BINARY = 16;
53     public static final int ANY_URI = 17;
54     public static final int QNAME = 18;
55     public static final int NOTATION = 19;
56
57     public static final int ID = 20;
58     public static final int IDREF = 21;
59
60     public static final int LIST = 30;
61     public static final int UNION = 31;
62     public static final int ANYSIMPLETYPE = 32;
63
64     // constants used only by whiteSpace treating
65
public static final int PRESERVE = 0;
66     public static final int REPLACE = 1;
67     public static final int COLLAPSE = 2;
68
69     // Facet constants
70
public static final int LENGTH_FACET = 0;
71     public static final int MIN_LENGTH_FACET = 1;
72     public static final int MAX_LENGTH_FACET = 2;
73     public static final int PATTERN_FACET = 3;
74     public static final int ENUMERATION_FACET = 4;
75     public static final int WHITESPACE_FACET = 5;
76     public static final int MIN_EXCLUSIVE_FACET = 6;
77     public static final int MIN_INCLUSIVE_FACET = 7;
78     public static final int MAX_EXCLUSIVE_FACET = 8;
79     public static final int MAX_INCLUSIVE_FACET = 9;
80     public static final int TOTALDIGITS_FACET = 10;
81     public static final int FRACTIONDIGITS_FACET = 11;
82
83     private String JavaDoc name;
84     private int type;
85     protected int nWhiteSpace = COLLAPSE; // default value
86
protected int fixedBitSet = 1 << WHITESPACE_FACET;
87
88     // parterns
89
private ArrayList patterns = null;
90
91     PrimitiveType(String JavaDoc name, int type) {
92         this.name = name;
93         this.type = type;
94     }
95
96     public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
97         PrimitiveType result = (PrimitiveType) super.clone();
98         if (patterns != null)
99             result.patterns = (ArrayList) patterns.clone();
100         return result;
101     }
102
103     public String JavaDoc getName() {
104         return name;
105     }
106
107     public int getType() {
108         return type;
109     }
110
111     public int getLength() {
112         return -1;
113     }
114
115     public int getMinLength() {
116         return -1;
117     }
118
119     public int getMaxLength() {
120         return -1;
121     }
122
123     public int getTotalDigits() {
124         return -1;
125     }
126
127     public int getFractionDigits() {
128         return -1;
129     }
130
131     public Comparable JavaDoc getMinValue() {
132         return null;
133     }
134
135     public Comparable JavaDoc getMaxValue() {
136         return null;
137     }
138
139     public boolean isMinInclusive() {
140         return false;
141     }
142
143     public boolean isMaxInclusive() {
144         return false;
145     }
146
147     public List getValues() {
148         return null;
149     }
150
151     public String JavaDoc toString() {
152         return "Datatype " + name;
153     }
154
155     public String JavaDoc normalizedValue(String JavaDoc value) {
156         return normalize(value, 0, value.length(), nWhiteSpace);
157     }
158
159     public StringBuffer JavaDoc normalizedValue(StringBuffer JavaDoc value, StringBuffer JavaDoc out) {
160         if (out == null)
161             out = new StringBuffer JavaDoc();
162         return normalize(value, 0, value.length(), nWhiteSpace, out);
163     }
164
165     /**
166      * This method modifies its input.
167      */

168     public StringBuffer JavaDoc normalizedValue(StringBuffer JavaDoc value) {
169         return normalize(value, 0, value.length(), nWhiteSpace, value);
170     }
171
172     public String JavaDoc toXMLString(Object JavaDoc data, ValidationContextProvider context) {
173         if (data == null) return null;
174         else return data.toString();
175     }
176
177     public Object JavaDoc convert(String JavaDoc string, boolean normalize, ValidationContextProvider context) throws SchemaException {
178         String JavaDoc value = string;
179         if (normalize) value = normalize(string, 0, string.length(), nWhiteSpace);
180         return convert(value, context);
181     }
182     
183     public Object JavaDoc convertObject(Object JavaDoc data) throws SchemaException {
184         if (data == null) return null;
185         Object JavaDoc value = null;
186         try {
187             value = toValidType(data);
188         } catch (ClassCastException JavaDoc e) {
189             throw new SchemaException(e);
190         }
191         checkFacets(value);
192         return value;
193     }
194
195     protected abstract Object JavaDoc toValidType(Object JavaDoc data);
196
197     /**
198      * This method modifies its input.
199      * @param string
200      * @param normalize
201      * @param context
202      * @return
203      * @throws SchemaException
204      */

205     public Object JavaDoc convert(StringBuffer JavaDoc string, boolean normalize, ValidationContextProvider context)
206         throws SchemaException {
207         if (normalize) normalize(string, 0, string.length(), nWhiteSpace, string);
208         return convert(string.toString(), context);
209     }
210
211     public Object JavaDoc convert(String JavaDoc string, boolean normalize) throws SchemaException {
212         return convert(string, normalize, null);
213     }
214
215     public Object JavaDoc convert(StringBuffer JavaDoc string, boolean normalize) throws SchemaException {
216         return convert(string, normalize, null);
217     }
218
219     protected void setPattern(String JavaDoc value) throws SchemaException {
220         try {
221             RegularExpression pattern = new RegularExpression(value, "X");
222             if (patterns == null)
223                 patterns = new ArrayList();
224             patterns.add(pattern);
225         } catch (Exception JavaDoc e) {
226             // "Illegal pattern";
227
throw new SchemaException("unknown-error-code.2");
228         }
229     }
230
231     public void checkPattern(String JavaDoc value) throws SchemaException {
232         if (patterns == null)
233             return;
234         Iterator it = patterns.iterator();
235         while (it.hasNext()) {
236             RegularExpression pattern = (RegularExpression) it.next();
237             if (!pattern.matches(value))
238                 invalidFacet("cvc-pattern-valid.1", pattern.getPattern(), value);
239         }
240     }
241
242     public abstract void checkFacets(Object JavaDoc valueSpace) throws SchemaException;
243     abstract protected Object JavaDoc toValueSpace(String JavaDoc value, ValidationContextProvider context) throws SchemaException;
244
245     protected Object JavaDoc convert(String JavaDoc value, ValidationContextProvider context) throws SchemaException {
246         checkPattern(value);
247         Object JavaDoc result = toValueSpace(value, context);
248         checkFacets(result);
249         return result;
250     }
251
252     static public PrimitiveType createType(String JavaDoc name) {
253         if (name.equals("anySimpleType"))
254             return new AnySimpleType();
255         else if (name.equals("string"))
256             return new StringType();
257         else if (name.equals("boolean"))
258             return new BooleanType();
259         else if (name.equals("decimal"))
260             return new DecimalType();
261         else if (name.equals("float"))
262             return new FloatType();
263         else if (name.equals("double"))
264             return new DoubleType();
265         else if (name.equals("duration"))
266             return new DurationType();
267         else if (name.equals("dateTime"))
268             return new DateTimeType();
269         else if (name.equals("time"))
270             return new TimeType();
271         else if (name.equals("date"))
272             return new DateType();
273         else if (name.equals("gYearMonth"))
274             return new GYearMonthType();
275         else if (name.equals("gYear"))
276             return new GYearType();
277         else if (name.equals("gMonthDay"))
278             return new GMonthDayType();
279         else if (name.equals("gDay"))
280             return new GDayType();
281         else if (name.equals("gMonth"))
282             return new GMonthType();
283         else if (name.equals("hexBinary"))
284             return new HexBinaryType();
285         else if (name.equals("base64Binary"))
286             return new Base64BinaryType();
287         else if (name.equals("anyURI"))
288             return new AnyURIType();
289         else if (name.equals("QName"))
290             return new QNameType();
291         else if (name.equals("NOTATION"))
292             return new NOTATIONType();
293
294         else
295             return null;
296     }
297
298     static public PrimitiveType createListType(PrimitiveType itemPrimitive) {
299         return new PrimitiveListType(itemPrimitive);
300     }
301
302     static public PrimitiveType createUnionType(ArrayList primitives, String JavaDoc unionName) {
303         return new PrimitiveUnionType(primitives, unionName);
304     }
305
306     public void setFacet(Facet aFacet, ValidationContextProvider vcProvider) throws SchemaException {
307         String JavaDoc facetName = aFacet.getName();
308         String JavaDoc value = aFacet.getValue();
309         boolean fixed = aFacet.isFixed();
310
311         try {
312             if (facetName.equals(LENGTH_TAG))
313                 setLength(value, fixed);
314             else if (facetName.equals(MIN_LENGTH_TAG))
315                 setMinLength(value, fixed);
316             else if (facetName.equals(MAX_LENGTH_TAG))
317                 setMaxLength(value, fixed);
318             else if (facetName.equals(PATTERN_TAG))
319                 setPattern(value);
320             else if (facetName.equals(ENUMERATION_TAG))
321                 setEnumeration(aFacet.getEnumFacets(), vcProvider);
322             else if (facetName.equals(WHITESPACE_TAG))
323                 setWhiteSpace(value, fixed);
324             else if (facetName.equals(MIN_EXCLUSIVE_TAG))
325                 setMinExclusive(value, fixed);
326             else if (facetName.equals(MIN_INCLUSIVE_TAG))
327                 setMinInclusive(value, fixed);
328             else if (facetName.equals(MAX_EXCLUSIVE_TAG))
329                 setMaxExclusive(value, fixed);
330             else if (facetName.equals(MAX_INCLUSIVE_TAG))
331                 setMaxInclusive(value, fixed);
332             else if (facetName.equals(TOTALDIGITS_TAG))
333                 setTotalDigits(value, fixed);
334             else if (facetName.equals(FRACTIONDIGITS_TAG))
335                 setFractionDigits(value, fixed);
336         } catch (SchemaException se) {
337             throw new SchemaException(se.getErrorCode(), aFacet, se);
338         }
339     }
340
341     protected void setLength(String JavaDoc value, boolean fixed) throws SchemaException {
342         // "Facet length not supported in " + this;
343
throw new SchemaException("cos-applicable-facets");
344     }
345
346     protected void setMinLength(String JavaDoc value, boolean fixed) throws SchemaException {
347         // "Facet length not supported in " + this;
348
throw new SchemaException("cos-applicable-facets");
349     }
350
351     protected void setMaxLength(String JavaDoc value, boolean fixed) throws SchemaException {
352         // "Facet length not supported in " + this;
353
throw new SchemaException("cos-applicable-facets");
354     }
355
356     protected void setEnumeration(HashSet value, ValidationContextProvider vcProvider) throws SchemaException {
357         // "Facet length not supported in " + this;
358
throw new SchemaException("cos-applicable-facets");
359     }
360
361     protected void setMinExclusive(String JavaDoc value, boolean fixed) throws SchemaException {
362         // "Facet length not supported in " + this;
363
throw new SchemaException("cos-applicable-facets");
364     }
365
366     protected void setMinInclusive(String JavaDoc value, boolean fixed) throws SchemaException {
367         // "Facet length not supported in " + this;
368
throw new SchemaException("cos-applicable-facets");
369     }
370
371     protected void setMaxExclusive(String JavaDoc value, boolean fixed) throws SchemaException {
372         // "Facet length not supported in " + this;
373
throw new SchemaException("cos-applicable-facets");
374     }
375
376     protected void setMaxInclusive(String JavaDoc value, boolean fixed) throws SchemaException {
377         // "Facet length not supported in " + this;
378
throw new SchemaException("cos-applicable-facets");
379     }
380
381     protected void setTotalDigits(String JavaDoc value, boolean fixed) throws SchemaException {
382         // "Facet length not supported in " + this;
383
throw new SchemaException("cos-applicable-facets");
384     }
385
386     protected void setFractionDigits(String JavaDoc value, boolean fixed) throws SchemaException {
387         // "Facet length not supported in " + this;
388
throw new SchemaException("cos-applicable-facets");
389     }
390
391     protected void setWhiteSpace(String JavaDoc value, boolean fixed) throws SchemaException {
392         int ws = -1;
393         if ("preserve".equals(value))
394             ws = PRESERVE;
395         else if ("replace".equals(value))
396             ws = REPLACE;
397         else if ("collapse".equals(value))
398             ws = COLLAPSE;
399
400         // check that value is legal (ws != -1) and more constrained
401
if ((isFixed(WHITESPACE_FACET) && ws != nWhiteSpace)) {
402             // "facet value is fixed";
403
throw new SchemaException("unknown-error-code.1");
404         }
405
406         if ((ws == PRESERVE || ws == REPLACE) && nWhiteSpace == COLLAPSE) {
407             // "whiteSpace value can't be <replace> or <preserve>";
408
throw new SchemaException("whiteSpace-valid-restriction.1");
409         }
410
411         if (ws == PRESERVE && nWhiteSpace == REPLACE) {
412             // "whiteSpace value can't be <preserve>";
413
throw new SchemaException("whiteSpace-valid-restriction.2");
414         }
415
416         nWhiteSpace = ws;
417         setFixed(WHITESPACE_FACET, fixed);
418     }
419
420     public int getWhiteSpace() {
421         return nWhiteSpace;
422     }
423
424     protected boolean isFixed(int facet) {
425         int mask = 1 << facet;
426         return (mask & fixedBitSet) != 0;
427     }
428
429     protected void setFixed(int facet, boolean fixed) {
430         if (fixed) {
431             int mask = 1 << facet;
432             fixedBitSet |= mask;
433         }
434     }
435
436     protected void invalidFacet(String JavaDoc errCode, Object JavaDoc facetVal, String JavaDoc value) throws SchemaException {
437         Object JavaDoc invalidFacet = "Constraint: " + facetVal + ", value: " + value;
438         SchemaException se = new SchemaException(errCode, invalidFacet);
439         if ("cvc-pattern-valid".equals(errCode))
440             throw new SchemaException("cvc-datatype-valid.1.1", this, se);
441         else
442             throw new SchemaException("cvc-datatype-valid.2", this, se);
443     }
444
445     protected void invalidValue(String JavaDoc value) throws SchemaException {
446         throw new SchemaException("cvc-datatype-valid.1.2.1", "value = " + value);
447     }
448
449     public static boolean isXMLWhitespace(char c) {
450         switch (c) {
451             case 0x20 :
452             case 0x9 :
453             case 0xA :
454             case 0xD :
455                 return true;
456             default :
457                 return false;
458         }
459     }
460
461     private static String JavaDoc normalize(String JavaDoc value, int offset, int length, int whitespace) {
462         StringBuffer JavaDoc result;
463         switch (whitespace) {
464             case PRESERVE :
465                 if (offset == 0 && length == value.length())
466                     return value;
467                 else
468                     return value.substring(offset, length);
469             case REPLACE :
470                 result = new StringBuffer JavaDoc();
471                 for (int i = offset; i < offset + length; i++) {
472                     if (isXMLWhitespace(value.charAt(i)))
473                         result.append((char) 0x20);
474                     else
475                         result.append(value.charAt(i));
476                 }
477                 return result.toString();
478             case COLLAPSE :
479                 result = new StringBuffer JavaDoc();
480                 boolean start = true;
481                 int nIndex = 0;
482                 for (int i = offset; i < offset + length; i++) {
483                     if (isXMLWhitespace(value.charAt(i))) {
484                         // if leading WS, do nothing
485
if (!start) {
486                             // collapse continuous sequences of 0x20 to a single 0x20
487
if (result.charAt(nIndex - 1) != 0x20) {
488                                 result.append((char) 0x20);
489                                 nIndex++;
490                             }
491                         }
492                     } else {
493                         result.append(value.charAt(i));
494                         nIndex++;
495                         start = false;
496                     }
497                 }
498                 // remove trailing 0x20
499
if (nIndex > 0 && result.charAt(nIndex - 1) == 0x20)
500                     result.setLength(nIndex - 1);
501                 return result.toString();
502             default :
503                 throw new IllegalArgumentException JavaDoc("Illegal value for whitespace handling");
504         }
505     }
506
507     private static StringBuffer JavaDoc normalize(
508         StringBuffer JavaDoc value,
509         int offset,
510         int length,
511         int whitespace,
512         StringBuffer JavaDoc result) {
513         int nIndex = offset;
514         switch (whitespace) {
515             case PRESERVE :
516                 if (result != value) {
517                     if (offset == 0 && length == value.length()) {
518                         result.append(value);
519                     } else {
520                         result.append(value.substring(offset, length));
521                     }
522                 }
523                 return result;
524             case REPLACE :
525                 if (result != value) {
526                     nIndex = result.length();
527                     result.setLength(nIndex + length);
528                 }
529                 for (int i = offset; i < offset + length; i++) {
530                     if (isXMLWhitespace(value.charAt(i)))
531                         result.setCharAt(nIndex, (char) 0x20);
532                     else
533                         result.setCharAt(nIndex, value.charAt(i));
534                     nIndex++;
535                 }
536                 return result;
537             case COLLAPSE :
538                 if (result != value) {
539                     nIndex = result.length();
540                     result.setLength(nIndex + length);
541                 }
542                 boolean start = true;
543                 for (int i = offset; i < offset + length; i++) {
544                     if (isXMLWhitespace(value.charAt(i))) {
545                         // if leading WS, do nothing
546
if (!start) {
547                             // collapse continuous sequences of 0x20 to a single 0x20
548
if (result.charAt(nIndex - 1) != 0x20) {
549                                 result.setCharAt(nIndex, (char) 0x20);
550                                 nIndex++;
551                             }
552                         }
553                     } else {
554                         result.setCharAt(nIndex, value.charAt(i));
555                         nIndex++;
556                         start = false;
557                     }
558                 }
559                 // remove trailing 0x20
560
if (!start && result.charAt(nIndex - 1) == 0x20)
561                     nIndex--;
562                 if (result != value)
563                     result.setLength(nIndex);
564                 else
565                     result.delete(nIndex, offset + length);
566                 return result;
567             default :
568                 throw new IllegalArgumentException JavaDoc("Illegal value for whitespace handling");
569         }
570     }
571
572 }
573
Popular Tags