KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > apache > xerces > validators > datatype > AbstractStringValidator


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999, 2000, 2001 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 2001, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package org.enhydra.apache.xerces.validators.datatype;
59
60 import java.util.Enumeration JavaDoc;
61 import java.util.Hashtable JavaDoc;
62 import java.util.Vector JavaDoc;
63
64 import org.enhydra.apache.xerces.utils.XMLCharacterProperties;
65 import org.enhydra.apache.xerces.utils.regex.RegularExpression;
66 import org.enhydra.apache.xerces.validators.schema.SchemaSymbols;
67
68 /**
69  * AbstractStringValidator is a base class for anyURI, string,
70  * hexBinary, base64Binary, QName and Notation datatypes.
71  *
72  * @author Elena Litani
73  * @version $Id: AbstractStringValidator.java,v 1.2 2005/01/26 08:28:44 jkjome Exp $
74  */

75 public abstract class AbstractStringValidator extends AbstractDatatypeValidator {
76
77     protected int fLength = 0;
78     protected int fMaxLength = Integer.MAX_VALUE;
79     protected int fMinLength = 0;
80     protected Vector JavaDoc fEnumeration = null;
81
82     // _dummy_ facet for which special token parser to use
83
public static final String JavaDoc FACET_SPECIAL_TOKEN = "specialToken";
84     public static final String JavaDoc SPECIAL_TOKEN_NONE = "NONE";
85     public static final String JavaDoc SPECIAL_TOKEN_NMTOKEN = "NMTOKEN";
86     public static final String JavaDoc SPECIAL_TOKEN_NAME = "Name";
87     public static final String JavaDoc SPECIAL_TOKEN_IDNAME = "ID(Name)";
88     public static final String JavaDoc SPECIAL_TOKEN_IDREFNAME = "IDREF(Name)";
89     public static final String JavaDoc SPECIAL_TOKEN_NCNAME = "NCName";
90     public static final String JavaDoc SPECIAL_TOKEN_IDNCNAME = "ID(NCName)";
91     public static final String JavaDoc SPECIAL_TOKEN_IDREFNCNAME = "IDREF(NCName)";
92     public static final String JavaDoc SPECIAL_TOKEN_ENTITY = "ENTITY(NCName)";
93
94     protected String JavaDoc fTokenType = SPECIAL_TOKEN_NONE; //flags special token parser
95

96     public AbstractStringValidator () throws InvalidDatatypeFacetException{
97         this( null, null, false ); // Native, No Facets defined, Restriction
98

99     }
100
101     public AbstractStringValidator ( DatatypeValidator base, Hashtable JavaDoc facets,
102                                      boolean derivedByList ) throws InvalidDatatypeFacetException {
103
104         // Set base type
105
fBaseValidator = base;
106
107         if ( derivationList(derivedByList) )
108             return;
109         // Set Facets if any defined
110
if ( facets != null ) {
111             for ( Enumeration JavaDoc e = facets.keys(); e.hasMoreElements(); ) {
112                 String JavaDoc key = (String JavaDoc) e.nextElement();
113
114                 if ( key.equals(SchemaSymbols.ELT_LENGTH) ) {
115                     fFacetsDefined |= DatatypeValidator.FACET_LENGTH;
116                     String JavaDoc lengthValue = (String JavaDoc)facets.get(key);
117                     try {
118                         fLength = Integer.parseInt( lengthValue );
119                     }
120                     catch ( NumberFormatException JavaDoc nfe ) {
121                         throw new InvalidDatatypeFacetException("Length value '"+lengthValue+"' is invalid.");
122                     }
123                     // check 4.3.1.c0 must: length >= 0
124
if ( fLength < 0 )
125                         throw new InvalidDatatypeFacetException("Length value '"+lengthValue+"' must be a nonNegativeInteger.");
126
127                 }
128                 else if ( key.equals(SchemaSymbols.ELT_MINLENGTH) ) {
129                     fFacetsDefined |= DatatypeValidator.FACET_MINLENGTH;
130                     String JavaDoc minLengthValue = (String JavaDoc)facets.get(key);
131                     try {
132                         fMinLength = Integer.parseInt( minLengthValue );
133                     }
134                     catch ( NumberFormatException JavaDoc nfe ) {
135                         throw new InvalidDatatypeFacetException("minLength value '"+minLengthValue+"' is invalid.");
136                     }
137                     // check 4.3.2.c0 must: minLength >= 0
138
if ( fMinLength < 0 )
139                         throw new InvalidDatatypeFacetException("minLength value '"+minLengthValue+"' must be a nonNegativeInteger.");
140
141                 }
142                 else if ( key.equals(SchemaSymbols.ELT_MAXLENGTH) ) {
143                     fFacetsDefined |= DatatypeValidator.FACET_MAXLENGTH;
144                     String JavaDoc maxLengthValue = (String JavaDoc)facets.get(key);
145                     try {
146                         fMaxLength = Integer.parseInt( maxLengthValue );
147                     }
148                     catch ( NumberFormatException JavaDoc nfe ) {
149                         throw new InvalidDatatypeFacetException("maxLength value '"+maxLengthValue+"' is invalid.");
150                     }
151                     // check 4.3.3.c0 must: maxLength >= 0
152
if ( fMaxLength < 0 )
153                         throw new InvalidDatatypeFacetException("maxLength value '"+maxLengthValue+"' must be a nonNegativeInteger.");
154                 }
155                 else if ( key.equals(SchemaSymbols.ELT_PATTERN) ) {
156                     fFacetsDefined |= DatatypeValidator.FACET_PATTERN;
157                     fPattern = (String JavaDoc)facets.get(key);
158                     if ( fPattern != null )
159                         fRegex = new RegularExpression(fPattern, "X");
160                 }
161                 else if ( key.equals(SchemaSymbols.ELT_ENUMERATION) ) {
162                     fEnumeration = (Vector JavaDoc)facets.get(key);
163                     fFacetsDefined |= DatatypeValidator.FACET_ENUMERATION;
164                 }
165                 else if ( key.equals(DatatypeValidator.FACET_FIXED) ) {// fixed flags
166
fFlags = ((Short JavaDoc)facets.get(key)).shortValue();
167                 }
168                 else if ( key == FACET_SPECIAL_TOKEN ) {// special token parser
169
setTokenType((String JavaDoc)facets.get(key));
170                 }
171                 else {
172                     assignAdditionalFacets(key, facets);
173                 }
174             }
175
176             if ( base != null ) {
177                 // check 4.3.5.c0 must: enumeration values from the value space of base
178
//REVISIT: we should try either to delay it till validate() or
179
// store enumeration values in _value_space
180
// otherwise we end up creating and throwing objects
181
if ( (fFacetsDefined & DatatypeValidator.FACET_ENUMERATION) != 0 &&
182                      (fEnumeration != null) ) {
183                     int i = 0;
184                     try {
185                         for ( ; i < fEnumeration.size(); i++ ) {
186                             ((AbstractStringValidator)base).checkContent ((String JavaDoc)fEnumeration.elementAt(i), null, false);
187                         }
188                     }
189                     catch ( Exception JavaDoc idve ) {
190                         throw new InvalidDatatypeFacetException( "Value of enumeration = '" + fEnumeration.elementAt(i) +
191                                                                  "' must be from the value space of base.");
192                     }
193                 }
194             }
195
196             // check 4.3.1.c1 error: length & (maxLength | minLength)
197
if ( ((fFacetsDefined & DatatypeValidator.FACET_LENGTH ) != 0 ) ) {
198                 if ( ((fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH ) != 0 ) ) {
199                     throw new InvalidDatatypeFacetException("It is an error for both length and maxLength to be members of facets." );
200                 }
201                 else if ( ((fFacetsDefined & DatatypeValidator.FACET_MINLENGTH ) != 0 ) ) {
202                     throw new InvalidDatatypeFacetException("It is an error for both length and minLength to be members of facets." );
203                 }
204             }
205
206             // check 4.3.2.c1 must: minLength <= maxLength
207
if ( ( (fFacetsDefined & ( DatatypeValidator.FACET_MINLENGTH |
208                                        DatatypeValidator.FACET_MAXLENGTH) ) != 0 ) ) {
209                 if ( fMinLength > fMaxLength ) {
210                     throw new InvalidDatatypeFacetException( "Value of minLength = '" + fMinLength +
211                                                              "'must be <= the value of maxLength = '" + fMaxLength + "'.");
212                 }
213             }
214
215             // if base type is string, check facets against base.facets, and inherit facets from base
216
if ( base != null ) {
217                 AbstractStringValidator strBase = (AbstractStringValidator)base;
218
219                 // check 4.3.1.c1 error: length & (base.maxLength | base.minLength)
220
if ( ((fFacetsDefined & DatatypeValidator.FACET_LENGTH ) != 0 ) ) {
221                     if ( ((strBase.fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH ) != 0 ) ) {
222                         throw new InvalidDatatypeFacetException("It is an error for both length and maxLength to be members of facets." );
223                     }
224                     else if ( ((strBase.fFacetsDefined & DatatypeValidator.FACET_MINLENGTH ) != 0 ) ) {
225                         throw new InvalidDatatypeFacetException("It is an error for both length and minLength to be members of facets." );
226                     }
227                     else if ( (strBase.fFacetsDefined & DatatypeValidator.FACET_LENGTH) != 0 ) {
228                         // check 4.3.1.c2 error: length != base.length
229
if ( fLength != strBase.fLength )
230                             throw new InvalidDatatypeFacetException( "Value of length = '" + fLength +
231                                                                      "' must be = the value of base.length = '" + strBase.fLength + "'.");
232                     }
233                 }
234
235                 // check 4.3.1.c1 error: base.length & (maxLength | minLength)
236
if ( ((strBase.fFacetsDefined & DatatypeValidator.FACET_LENGTH ) != 0 ) ) {
237                     if ( ((fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH ) != 0 ) ) {
238                         throw new InvalidDatatypeFacetException("It is an error for both length and maxLength to be members of facets." );
239                     }
240                     else if ( ((fFacetsDefined & DatatypeValidator.FACET_MINLENGTH ) != 0 ) ) {
241                         throw new InvalidDatatypeFacetException("It is an error for both length and minLength to be members of facets." );
242                     }
243                 }
244
245                 // check 4.3.2.c1 must: minLength <= base.maxLength
246
if ( ((fFacetsDefined & DatatypeValidator.FACET_MINLENGTH ) != 0 ) ) {
247                     if ( (strBase.fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH ) != 0 ) {
248                         if ( fMinLength > strBase.fMaxLength ) {
249                             throw new InvalidDatatypeFacetException( "Value of minLength = '" + fMinLength +
250                                                                      "'must be <= the value of maxLength = '" + fMaxLength + "'.");
251                         }
252                     }
253                     else if ( (strBase.fFacetsDefined & DatatypeValidator.FACET_MINLENGTH) != 0 ) {
254                         if ( (strBase.fFlags & DatatypeValidator.FACET_MINLENGTH) != 0 &&
255                              fMinLength != strBase.fMinLength ) {
256                             throw new InvalidDatatypeFacetException( "minLength value = '" + fMinLength +
257                                                                      "' must be equal to base.minLength value = '" +
258                                                                      strBase.fMinLength + "' with attribute {fixed} = true" );
259                         }
260                         // check 4.3.2.c2 error: minLength < base.minLength
261
if ( fMinLength < strBase.fMinLength ) {
262                             throw new InvalidDatatypeFacetException( "Value of minLength = '" + fMinLength +
263                                                                      "' must be >= the value of base.minLength = '" + strBase.fMinLength + "'.");
264                         }
265                     }
266                 }
267
268
269                 // check 4.3.2.c1 must: base.minLength <= maxLength
270
if ( ((strBase.fFacetsDefined & DatatypeValidator.FACET_MINLENGTH ) != 0 ) &&
271                      ((fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH ) != 0 ) ) {
272                     if ( strBase.fMinLength > fMaxLength ) {
273                         throw new InvalidDatatypeFacetException( "Value of minLength = '" + fMinLength +
274                                                                  "'must be <= the value of maxLength = '" + fMaxLength + "'.");
275                     }
276                 }
277
278                 // check 4.3.3.c1 error: maxLength > base.maxLength
279
if ( (fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH) != 0 ) {
280                     if ( (strBase.fFlags & DatatypeValidator.FACET_MAXLENGTH) != 0 &&
281                          fMaxLength != strBase.fMaxLength ) {
282                         throw new InvalidDatatypeFacetException( "maxLength value = '" + fMaxLength +
283                                                                  "' must be equal to base.maxLength value = '" +
284                                                                  strBase.fMaxLength + "' with attribute {fixed} = true" );
285                     }
286                     if ( (strBase.fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH) != 0 ) {
287                         if ( fMaxLength > strBase.fMaxLength ) {
288
289                             throw new InvalidDatatypeFacetException( "Value of maxLength = '" + fMaxLength +
290                                                                      "' must be <= the value of base.maxLength = '" + strBase.fMaxLength + "'.");
291                         }
292                     }
293                 }
294
295
296                 checkBaseFacetConstraints();
297
298                 // inherit length
299
if ( (strBase.fFacetsDefined & DatatypeValidator.FACET_LENGTH) != 0 ) {
300                     if ( (fFacetsDefined & DatatypeValidator.FACET_LENGTH) == 0 ) {
301                         fFacetsDefined |= DatatypeValidator.FACET_LENGTH;
302                         fLength = strBase.fLength;
303                     }
304                 }
305                 // inherit minLength
306
if ( (strBase.fFacetsDefined & DatatypeValidator.FACET_MINLENGTH) != 0 ) {
307                     if ( (fFacetsDefined & DatatypeValidator.FACET_MINLENGTH) == 0 ) {
308                         fFacetsDefined |= DatatypeValidator.FACET_MINLENGTH;
309                         fMinLength = strBase.fMinLength;
310                     }
311                 }
312                 // inherit maxLength
313
if ( (strBase.fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH) != 0 ) {
314                     if ( (fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH) == 0 ) {
315                         fFacetsDefined |= DatatypeValidator.FACET_MAXLENGTH;
316                         fMaxLength = strBase.fMaxLength;
317                     }
318                 }
319                 // inherit enumeration
320
if ( (fFacetsDefined & DatatypeValidator.FACET_ENUMERATION) == 0 &&
321                      (strBase.fFacetsDefined & DatatypeValidator.FACET_ENUMERATION) != 0 ) {
322                     fFacetsDefined |= DatatypeValidator.FACET_ENUMERATION;
323                     fEnumeration = strBase.fEnumeration;
324                 }
325                 inheritAdditionalFacets();
326
327                 //inherit fixed values
328
fFlags |= strBase.fFlags;
329             }
330         }// End of Facets Setting
331
}
332
333     //
334
// string has whiteSpace facet
335
// all other datatypes will throw InvalidDatatypeFacetException
336
//
337
abstract protected void assignAdditionalFacets(String JavaDoc key, Hashtable JavaDoc facets)
338     throws InvalidDatatypeFacetException;
339
340     //
341
// string has additional whiteSpace facet
342
//
343
protected void inheritAdditionalFacets() {
344     }
345
346     //
347
// string needs to check constraints on whiteSpace
348
// check is done against fBaseValidator
349
//
350
protected void checkBaseFacetConstraints() throws InvalidDatatypeFacetException {}
351
352     protected boolean derivationList (boolean derivedByList) {
353         // list types are handled by ListDatatypeValidator, we do nothing here.
354
return derivedByList;
355     }
356
357     /**
358      * validate that a string is a W3C string type
359      *
360      * @param content A string containing the content to be validated
361      * @param list
362      * @exception throws InvalidDatatypeException if the content is
363      * not a W3C string type
364      * @exception InvalidDatatypeValueException
365      */

366     public Object JavaDoc validate(String JavaDoc content, Object JavaDoc state) throws InvalidDatatypeValueException {
367         checkContent( content, state, false );
368         return null;
369     }
370
371
372     private void checkContent( String JavaDoc content, Object JavaDoc state, boolean asBase )
373     throws InvalidDatatypeValueException {
374         // validate against parent type if any
375
if ( this.fBaseValidator != null ) {
376             // validate content as a base type
377
((AbstractStringValidator)fBaseValidator).checkContent(content, state, true);
378         }
379
380         // we check pattern first
381
if ( (fFacetsDefined & DatatypeValidator.FACET_PATTERN ) != 0 ) {
382             if ( fRegex == null || fRegex.matches( content) == false )
383                 throw new InvalidDatatypeValueException("Value '"+content+
384                                                         "' does not match regular expression facet '" + fPattern + "'." );
385         }
386
387         // validate special kinds of token, in place of old pattern matching
388
if (fTokenType != SPECIAL_TOKEN_NONE) {
389             validateToken(fTokenType, content);
390         }
391
392         // if this is a base validator, we only need to check pattern facet
393
// all other facet were inherited by the derived type
394
if ( asBase )
395             return;
396
397         checkValueSpace (content);
398         int length = getLength(content);
399
400         if ( (fFacetsDefined & DatatypeValidator.FACET_MAXLENGTH) != 0 ) {
401             if ( length > fMaxLength ) {
402                 throw new InvalidDatatypeValueException("Value '"+content+
403                                                         "' with length '"+length+
404                                                         "' exceeds maximum length facet of '"+fMaxLength+"'.");
405             }
406         }
407         if ( (fFacetsDefined & DatatypeValidator.FACET_MINLENGTH) != 0 ) {
408             if ( length < fMinLength ) {
409                 throw new InvalidDatatypeValueException("Value '"+content+
410                                                         "' with length '"+length+
411                                                         "' is less than minimum length facet of '"+fMinLength+"'." );
412             }
413         }
414
415         if ( (fFacetsDefined & DatatypeValidator.FACET_LENGTH) != 0 ) {
416             if ( length != fLength ) {
417                 throw new InvalidDatatypeValueException("Value '"+content+
418                                                         "' with length '"+length+
419                                                         "' is not equal to length facet '"+fLength+"'.");
420             }
421         }
422
423         if ( (fFacetsDefined & DatatypeValidator.FACET_ENUMERATION) != 0 &&
424              (fEnumeration != null) ) {
425             if ( fEnumeration.contains( content ) == false )
426                 throw new InvalidDatatypeValueException("Value '"+content+"' must be one of "+fEnumeration);
427         }
428     }
429     protected int getLength( String JavaDoc content) {
430         return content.length();
431     }
432
433     protected void checkValueSpace (String JavaDoc content) throws InvalidDatatypeValueException {}
434
435     /**
436      * Returns a copy of this object.
437      *
438      * @return
439      * @exception CloneNotSupportedException
440      */

441     public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
442         throw new CloneNotSupportedException JavaDoc("clone() is not supported in "+this.getClass().getName());
443     }
444
445     public void setTokenType (String JavaDoc tokenType) {
446         fTokenType = tokenType;
447     }
448
449
450     protected static void validateToken(String JavaDoc tokenType, String JavaDoc content) throws InvalidDatatypeValueException {
451         int len;
452         if (content == null || (len = content.length()) == 0) {
453             throw new InvalidDatatypeValueException(
454                            "The length of the content must be greater than 0");
455         }
456         boolean seenErr = false;
457         if (tokenType == SPECIAL_TOKEN_NMTOKEN) {
458             // PATTERN "\\c+"
459
seenErr = !XMLCharacterProperties.validNmtoken(content);
460         }
461         else if (tokenType == SPECIAL_TOKEN_NAME ||
462                    tokenType == SPECIAL_TOKEN_IDNAME ||
463                    tokenType == SPECIAL_TOKEN_IDREFNAME) {
464             // PATTERN "\\i\\c*"
465
seenErr = !XMLCharacterProperties.validName(content);
466         } else if (tokenType == SPECIAL_TOKEN_NCNAME ||
467                    tokenType == SPECIAL_TOKEN_IDNCNAME ||
468                    tokenType == SPECIAL_TOKEN_IDREFNCNAME ||
469                    tokenType == SPECIAL_TOKEN_ENTITY) {
470             // PATTERN "[\\i-[:]][\\c-[:]]*"
471
seenErr = !XMLCharacterProperties.validNCName(content);
472         }
473         if (seenErr) {
474             throw new InvalidDatatypeValueException(
475                             "Value '"+content+"' is not a valid " + tokenType);
476         }
477     }
478 }
479
Popular Tags