KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > thaiopensource > datatype > xsd > DatatypeBuilderImpl


1 package com.thaiopensource.datatype.xsd;
2
3 import java.util.ResourceBundle JavaDoc;
4 import java.text.MessageFormat JavaDoc;
5
6 import org.relaxng.datatype.Datatype;
7 import org.relaxng.datatype.DatatypeBuilder;
8 import org.relaxng.datatype.ValidationContext;
9 import org.relaxng.datatype.DatatypeException;
10 import com.thaiopensource.datatype.xsd.regex.RegexSyntaxException;
11 import com.thaiopensource.util.Localizer;
12
13 class DatatypeBuilderImpl implements DatatypeBuilder {
14   static final Localizer localizer = new Localizer(DatatypeBuilderImpl.class);
15
16   private DatatypeBase base;
17   private final DatatypeLibraryImpl library;
18
19   DatatypeBuilderImpl(DatatypeLibraryImpl library, DatatypeBase base) throws DatatypeException {
20     this.library = library;
21     this.base = base;
22   }
23
24   public void addParameter(String JavaDoc name,
25                String JavaDoc value,
26                ValidationContext context) throws DatatypeException {
27     if (name.equals("pattern"))
28       addPatternParam(value);
29     else if (name.equals("minInclusive"))
30       addMinInclusiveParam(value, context);
31     else if (name.equals("maxInclusive"))
32       addMaxInclusiveParam(value, context);
33     else if (name.equals("minExclusive"))
34       addMinExclusiveParam(value, context);
35     else if (name.equals("maxExclusive"))
36       addMaxExclusiveParam(value, context);
37     else if (name.equals("length"))
38       addLengthParam(value);
39     else if (name.equals("minLength"))
40       addMinLengthParam(value);
41     else if (name.equals("maxLength"))
42       addMaxLengthParam(value);
43     else if (name.equals("fractionDigits"))
44       addScaleParam(value);
45     else if (name.equals("totalDigits"))
46       addPrecisionParam(value);
47     else if (name.equals("enumeration"))
48       error("enumeration_param");
49     else if (name.equals("whiteSpace"))
50       error("whiteSpace_param");
51     else
52       error("unrecognized_param", name);
53   }
54
55   private void addPatternParam(String JavaDoc value) throws DatatypeException {
56     try {
57       base = new PatternRestrictDatatype(base,
58                      library.getRegexEngine().compile(value));
59     }
60     catch (RegexSyntaxException e) {
61       int pos = e.getPosition();
62       if (pos == RegexSyntaxException.UNKNOWN_POSITION)
63         pos = DatatypeException.UNKNOWN;
64       error("invalid_regex", e.getMessage(), pos);
65     }
66   }
67
68   private void addMinInclusiveParam(String JavaDoc value, ValidationContext context)
69     throws DatatypeException {
70     base = new MinInclusiveRestrictDatatype(base,
71                         getLimit(value, context));
72   }
73
74   private void addMaxInclusiveParam(String JavaDoc value, ValidationContext context)
75     throws DatatypeException {
76     base = new MaxInclusiveRestrictDatatype(base,
77                         getLimit(value, context));
78   }
79
80   private void addMinExclusiveParam(String JavaDoc value, ValidationContext context)
81     throws DatatypeException {
82     base = new MinExclusiveRestrictDatatype(base,
83                         getLimit(value, context));
84   }
85
86   private void addMaxExclusiveParam(String JavaDoc value, ValidationContext context)
87     throws DatatypeException {
88     base = new MaxExclusiveRestrictDatatype(base,
89                         getLimit(value, context));
90   }
91
92   private Object JavaDoc getLimit(String JavaDoc str, ValidationContext context)
93     throws DatatypeException {
94     if (base.getOrderRelation() == null)
95       error("not_ordered");
96     Object JavaDoc value = base.createValue(str, context);
97     if (value == null)
98       error("invalid_limit", str);
99     return value;
100   }
101
102   private void addLengthParam(String JavaDoc value) throws DatatypeException {
103     base = new LengthRestrictDatatype(base, getLength(value));
104   }
105
106   private void addMinLengthParam(String JavaDoc value) throws DatatypeException {
107     base = new MinLengthRestrictDatatype(base, getLength(value));
108   }
109
110   private void addMaxLengthParam(String JavaDoc value) throws DatatypeException {
111     base = new MaxLengthRestrictDatatype(base, getLength(value));
112   }
113
114   private int getLength(String JavaDoc str) throws DatatypeException {
115     if (base.getMeasure() == null)
116       error("no_length");
117     int len = convertNonNegativeInteger(str);
118     if (len < 0)
119       error("value_not_non_negative_integer");
120     return len;
121   }
122     
123   private void addScaleParam(String JavaDoc str) throws DatatypeException {
124     if (!(base.getPrimitive() instanceof DecimalDatatype))
125       error("scale_not_derived_from_decimal");
126     int scale = convertNonNegativeInteger(str);
127     if (scale < 0)
128       error("value_not_non_negative_integer");
129     base = new ScaleRestrictDatatype(base, scale);
130   }
131
132   private void addPrecisionParam(String JavaDoc str) throws DatatypeException {
133     if (!(base.getPrimitive() instanceof DecimalDatatype))
134       error("precision_not_derived_from_decimal");
135     int scale = convertNonNegativeInteger(str);
136     if (scale <= 0)
137       error("value_not_positive_integer");
138     base = new PrecisionRestrictDatatype(base, scale);
139   }
140
141   public Datatype createDatatype() {
142     return base;
143   }
144
145   private static void error(String JavaDoc key) throws DatatypeException {
146     throw new DatatypeException(localizer.message(key));
147   }
148
149   private static void error(String JavaDoc key, String JavaDoc arg) throws DatatypeException {
150     throw new DatatypeException(localizer.message(key, arg));
151   }
152
153   private static void error(String JavaDoc key, String JavaDoc arg, int pos) throws DatatypeException {
154     throw new DatatypeException(pos, localizer.message(key, arg));
155   }
156
157   // Return -1 for anything that is not a nonNegativeInteger
158
// Return Integer.MAX_VALUE for values that are too big
159

160   private int convertNonNegativeInteger(String JavaDoc str) {
161     str = str.trim();
162     DecimalDatatype decimal = new DecimalDatatype();
163     if (!decimal.lexicallyAllows(str))
164       return -1;
165     // Canonicalize the value
166
str = decimal.getValue(str, null).toString();
167     // Reject negative and fractional numbers
168
if (str.charAt(0) == '-' || str.indexOf('.') >= 0)
169       return -1;
170     try {
171       return Integer.parseInt(str);
172     }
173     catch (NumberFormatException JavaDoc e) {
174       // Map out of range integers to MAX_VALUE
175
return Integer.MAX_VALUE;
176     }
177   }
178 }
179
Popular Tags