1 /* TypeBuilder.java --
2    Copyright (C) 2006  Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
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.
10 
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.
15 
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.
20 
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.
25 
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. */
37 
38 package gnu.xml.validation.datatype;
39 
40 import java.util.LinkedHashSet;
41 import java.util.regex.Pattern;
42 import org.relaxng.datatype.Datatype;
43 import org.relaxng.datatype.DatatypeBuilder;
44 import org.relaxng.datatype.DatatypeException;
45 import org.relaxng.datatype.ValidationContext;
46 
47 /**
48  * Datatype builder.
49  *
50  * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
51  */
52 public class TypeBuilder
53   implements DatatypeBuilder
54 {
55 
56   final SimpleType type;
57 
TypeBuilder(SimpleType type)58   TypeBuilder(SimpleType type)
59   {
60     this.type = type;
61     // TODO fundamental facets
62     type.facets = new LinkedHashSet();
63   }
64 
addParameter(String name, String value, ValidationContext context)65   public void addParameter(String name, String value, ValidationContext context)
66     throws DatatypeException
67   {
68     // TODO fundamental facets
69     if ("length".equals(name))
70       type.facets.add(parseLengthFacet(value));
71     else if ("minLength".equals(name))
72       type.facets.add(parseMinLengthFacet(value));
73     else if ("maxLength".equals(name))
74       type.facets.add(parseMaxLengthFacet(value));
75     else if ("pattern".equals(name))
76       type.facets.add(parsePatternFacet(value));
77     else if ("enumeration".equals(name))
78       type.facets.add(parseEnumerationFacet(value));
79     else if ("whiteSpace".equals(name))
80       type.facets.add(parseWhiteSpaceFacet(value));
81     else if ("maxInclusive".equals(name))
82       type.facets.add(parseMaxInclusiveFacet(value, context));
83     else if ("maxExclusive".equals(name))
84       type.facets.add(parseMaxExclusiveFacet(value, context));
85     else if ("minExclusive".equals(name))
86       type.facets.add(parseMinExclusiveFacet(value, context));
87     else if ("minInclusive".equals(name))
88       type.facets.add(parseMinInclusiveFacet(value, context));
89     else if ("totalDigits".equals(name))
90       type.facets.add(parseTotalDigitsFacet(value));
91     else if ("fractionDigits".equals(name))
92       type.facets.add(parseFractionDigitsFacet(value));
93   }
94 
parseLengthFacet(String value)95   LengthFacet parseLengthFacet(String value)
96     throws DatatypeException
97   {
98     int si = value.indexOf(' ');
99     boolean fixed = false;
100     if (si != -1)
101       {
102         if (!"FIXED".equalsIgnoreCase(value.substring(si + 1)))
103           throw new DatatypeException("second argument must be FIXED if present");
104         fixed = true;
105         value = value.substring(0, si);
106       }
107     return new LengthFacet(Integer.parseInt(value), fixed, null);
108   }
109 
parseMinLengthFacet(String value)110   MinLengthFacet parseMinLengthFacet(String value)
111     throws DatatypeException
112   {
113     int si = value.indexOf(' ');
114     boolean fixed = false;
115     if (si != -1)
116       {
117         if (!"FIXED".equalsIgnoreCase(value.substring(si + 1)))
118           throw new DatatypeException("second argument must be FIXED if present");
119         fixed = true;
120         value = value.substring(0, si);
121       }
122     return new MinLengthFacet(Integer.parseInt(value), fixed, null);
123   }
124 
parseMaxLengthFacet(String value)125   MaxLengthFacet parseMaxLengthFacet(String value)
126     throws DatatypeException
127   {
128     int si = value.indexOf(' ');
129     boolean fixed = false;
130     if (si != -1)
131       {
132         if (!"FIXED".equalsIgnoreCase(value.substring(si + 1)))
133           throw new DatatypeException("second argument must be FIXED if present");
134         fixed = true;
135         value = value.substring(0, si);
136       }
137     return new MaxLengthFacet(Integer.parseInt(value), fixed, null);
138   }
139 
parsePatternFacet(String value)140   PatternFacet parsePatternFacet(String value)
141     throws DatatypeException
142   {
143     return new PatternFacet(Pattern.compile(value), null);
144   }
145 
parseEnumerationFacet(String value)146   EnumerationFacet parseEnumerationFacet(String value)
147     throws DatatypeException
148   {
149     return new EnumerationFacet(value, null);
150   }
151 
parseWhiteSpaceFacet(String value)152   WhiteSpaceFacet parseWhiteSpaceFacet(String value)
153     throws DatatypeException
154   {
155     int si = value.indexOf(' ');
156     boolean fixed = false;
157     if (si != -1)
158       {
159         if (!"FIXED".equalsIgnoreCase(value.substring(si + 1)))
160           throw new DatatypeException("second argument must be FIXED if present");
161         fixed = true;
162         value = value.substring(0, si);
163       }
164     if ("preserve".equals(value))
165       return new WhiteSpaceFacet(WhiteSpaceFacet.PRESERVE, fixed, null);
166     if ("replace".equals(value))
167       return new WhiteSpaceFacet(WhiteSpaceFacet.REPLACE, fixed, null);
168     if ("collapse".equals(value))
169       return new WhiteSpaceFacet(WhiteSpaceFacet.COLLAPSE, fixed, null);
170     throw new DatatypeException("argument must be preserve, replace, or collapse");
171   }
172 
parseMaxInclusiveFacet(String value, ValidationContext context)173   MaxInclusiveFacet parseMaxInclusiveFacet(String value,
174                                            ValidationContext context)
175     throws DatatypeException
176   {
177     int si = value.indexOf(' ');
178     boolean fixed = false;
179     if (si != -1)
180       {
181         if (!"FIXED".equalsIgnoreCase(value.substring(si + 1)))
182           throw new DatatypeException("second argument must be FIXED if present");
183         fixed = true;
184         value = value.substring(0, si);
185       }
186     return new MaxInclusiveFacet(type.createValue(value, context), fixed, null);
187   }
188 
parseMaxExclusiveFacet(String value, ValidationContext context)189   MaxExclusiveFacet parseMaxExclusiveFacet(String value,
190                                            ValidationContext context)
191     throws DatatypeException
192   {
193     int si = value.indexOf(' ');
194     boolean fixed = false;
195     if (si != -1)
196       {
197         if (!"FIXED".equalsIgnoreCase(value.substring(si + 1)))
198           throw new DatatypeException("second argument must be FIXED if present");
199         fixed = true;
200         value = value.substring(0, si);
201       }
202     return new MaxExclusiveFacet(type.createValue(value, context), fixed, null);
203   }
204 
parseMinExclusiveFacet(String value, ValidationContext context)205   MinExclusiveFacet parseMinExclusiveFacet(String value,
206                                            ValidationContext context)
207     throws DatatypeException
208   {
209     int si = value.indexOf(' ');
210     boolean fixed = false;
211     if (si != -1)
212       {
213         if (!"FIXED".equalsIgnoreCase(value.substring(si + 1)))
214           throw new DatatypeException("second argument must be FIXED if present");
215         fixed = true;
216         value = value.substring(0, si);
217       }
218     return new MinExclusiveFacet(type.createValue(value, context), fixed, null);
219   }
220 
parseMinInclusiveFacet(String value, ValidationContext context)221   MinInclusiveFacet parseMinInclusiveFacet(String value,
222                                            ValidationContext context)
223     throws DatatypeException
224   {
225     int si = value.indexOf(' ');
226     boolean fixed = false;
227     if (si != -1)
228       {
229         if (!"FIXED".equalsIgnoreCase(value.substring(si + 1)))
230           throw new DatatypeException("second argument must be FIXED if present");
231         fixed = true;
232         value = value.substring(0, si);
233       }
234     return new MinInclusiveFacet(type.createValue(value, context), fixed, null);
235   }
236 
parseTotalDigitsFacet(String value)237   TotalDigitsFacet parseTotalDigitsFacet(String value)
238     throws DatatypeException
239   {
240     int si = value.indexOf(' ');
241     boolean fixed = false;
242     if (si != -1)
243       {
244         if (!"FIXED".equalsIgnoreCase(value.substring(si + 1)))
245           throw new DatatypeException("second argument must be FIXED if present");
246         fixed = true;
247         value = value.substring(0, si);
248       }
249     int val = Integer.parseInt(value);
250     if (val < 0)
251       throw new DatatypeException("value must be a positiveInteger");
252     return new TotalDigitsFacet(val, fixed, null);
253   }
254 
parseFractionDigitsFacet(String value)255   FractionDigitsFacet parseFractionDigitsFacet(String value)
256     throws DatatypeException
257   {
258     int si = value.indexOf(' ');
259     boolean fixed = false;
260     if (si != -1)
261       {
262         if (!"FIXED".equalsIgnoreCase(value.substring(si + 1)))
263           throw new DatatypeException("second argument must be FIXED if present");
264         fixed = true;
265         value = value.substring(0, si);
266       }
267     int val = Integer.parseInt(value);
268     if (val < 0)
269       throw new DatatypeException("value must be a positiveInteger");
270     return new FractionDigitsFacet(val, fixed, null);
271   }
272 
createDatatype()273   public Datatype createDatatype()
274   {
275     return type;
276   }
277 
278 }
279