KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xerces > impl > dv > xs > XSSimpleTypeDecl


1 /*
2  * Copyright 2001-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.xerces.impl.dv.xs;
18
19 import java.util.StringTokenizer JavaDoc;
20 import java.util.Vector JavaDoc;
21
22 import org.apache.xerces.impl.Constants;
23 import org.apache.xerces.impl.dv.DatatypeException;
24 import org.apache.xerces.impl.dv.InvalidDatatypeFacetException;
25 import org.apache.xerces.impl.dv.InvalidDatatypeValueException;
26 import org.apache.xerces.impl.dv.ValidatedInfo;
27 import org.apache.xerces.impl.dv.ValidationContext;
28 import org.apache.xerces.impl.dv.XSFacets;
29 import org.apache.xerces.impl.dv.XSSimpleType;
30 import org.apache.xerces.impl.xpath.regex.RegularExpression;
31 import org.apache.xerces.impl.xs.SchemaSymbols;
32 import org.apache.xerces.impl.xs.util.ShortListImpl;
33 import org.apache.xerces.impl.xs.util.StringListImpl;
34 import org.apache.xerces.impl.xs.util.XSObjectListImpl;
35 import org.apache.xerces.util.XMLChar;
36 import org.apache.xerces.xni.NamespaceContext;
37 import org.apache.xerces.xs.ShortList;
38 import org.apache.xerces.xs.StringList;
39 import org.apache.xerces.xs.XSAnnotation;
40 import org.apache.xerces.xs.XSConstants;
41 import org.apache.xerces.xs.XSFacet;
42 import org.apache.xerces.xs.XSMultiValueFacet;
43 import org.apache.xerces.xs.XSNamespaceItem;
44 import org.apache.xerces.xs.XSObjectList;
45 import org.apache.xerces.xs.XSSimpleTypeDefinition;
46 import org.apache.xerces.xs.XSTypeDefinition;
47 import org.apache.xerces.xs.datatypes.ObjectList;
48 import org.w3c.dom.TypeInfo JavaDoc;
49
50 /**
51  * @xerces.internal
52  *
53  * @author Sandy Gao, IBM
54  * @author Neeraj Bajaj, Sun Microsystems, inc.
55  *
56  * @version $Id: XSSimpleTypeDecl.java,v 1.74 2005/06/24 17:19:21 mrglavas Exp $
57  */

58 public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo JavaDoc {
59     
60     static final short DV_STRING = PRIMITIVE_STRING;
61     static final short DV_BOOLEAN = PRIMITIVE_BOOLEAN;
62     static final short DV_DECIMAL = PRIMITIVE_DECIMAL;
63     static final short DV_FLOAT = PRIMITIVE_FLOAT;
64     static final short DV_DOUBLE = PRIMITIVE_DOUBLE;
65     static final short DV_DURATION = PRIMITIVE_DURATION;
66     static final short DV_DATETIME = PRIMITIVE_DATETIME;
67     static final short DV_TIME = PRIMITIVE_TIME;
68     static final short DV_DATE = PRIMITIVE_DATE;
69     static final short DV_GYEARMONTH = PRIMITIVE_GYEARMONTH;
70     static final short DV_GYEAR = PRIMITIVE_GYEAR;
71     static final short DV_GMONTHDAY = PRIMITIVE_GMONTHDAY;
72     static final short DV_GDAY = PRIMITIVE_GDAY;
73     static final short DV_GMONTH = PRIMITIVE_GMONTH;
74     static final short DV_HEXBINARY = PRIMITIVE_HEXBINARY;
75     static final short DV_BASE64BINARY = PRIMITIVE_BASE64BINARY;
76     static final short DV_ANYURI = PRIMITIVE_ANYURI;
77     static final short DV_QNAME = PRIMITIVE_QNAME;
78     static final short DV_PRECISIONDECIMAL = PRIMITIVE_PRECISIONDECIMAL;
79     static final short DV_NOTATION = PRIMITIVE_NOTATION;
80     
81     static final short DV_ANYSIMPLETYPE = 0;
82     static final short DV_ID = DV_NOTATION + 1;
83     static final short DV_IDREF = DV_NOTATION + 2;
84     static final short DV_ENTITY = DV_NOTATION + 3;
85     static final short DV_INTEGER = DV_NOTATION + 4;
86     static final short DV_LIST = DV_NOTATION + 5;
87     static final short DV_UNION = DV_NOTATION + 6;
88     static final short DV_YEARMONTHDURATION = DV_NOTATION + 7;
89     static final short DV_DAYTIMEDURATION = DV_NOTATION + 8;
90     static final short DV_ANYATOMICTYPE = DV_NOTATION + 9;
91     
92     static final TypeValidator[] fDVs = {
93             new AnySimpleDV(),
94             new StringDV(),
95             new BooleanDV(),
96             new DecimalDV(),
97             new FloatDV(),
98             new DoubleDV(),
99             new DurationDV(),
100             new DateTimeDV(),
101             new TimeDV(),
102             new DateDV(),
103             new YearMonthDV(),
104             new YearDV(),
105             new MonthDayDV(),
106             new DayDV(),
107             new MonthDV(),
108             new HexBinaryDV(),
109             new Base64BinaryDV(),
110             new AnyURIDV(),
111             new QNameDV(),
112             new PrecisionDecimalDV(), // XML Schema 1.1 type
113
new QNameDV(), // notation use the same one as qname
114
new IDDV(),
115             new IDREFDV(),
116             new EntityDV(),
117             new IntegerDV(),
118             new ListDV(),
119             new UnionDV(),
120             new YearMonthDurationDV(), // XML Schema 1.1 type
121
new DayTimeDurationDV(), // XML Schema 1.1 type
122
new AnyAtomicDV() // XML Schema 1.1 type
123
};
124     
125     static final short NORMALIZE_NONE = 0;
126     static final short NORMALIZE_TRIM = 1;
127     static final short NORMALIZE_FULL = 2;
128     static final short[] fDVNormalizeType = {
129             NORMALIZE_NONE, //AnySimpleDV(),
130
NORMALIZE_FULL, //StringDV(),
131
NORMALIZE_TRIM, //BooleanDV(),
132
NORMALIZE_TRIM, //DecimalDV(),
133
NORMALIZE_TRIM, //FloatDV(),
134
NORMALIZE_TRIM, //DoubleDV(),
135
NORMALIZE_TRIM, //DurationDV(),
136
NORMALIZE_TRIM, //DateTimeDV(),
137
NORMALIZE_TRIM, //TimeDV(),
138
NORMALIZE_TRIM, //DateDV(),
139
NORMALIZE_TRIM, //YearMonthDV(),
140
NORMALIZE_TRIM, //YearDV(),
141
NORMALIZE_TRIM, //MonthDayDV(),
142
NORMALIZE_TRIM, //DayDV(),
143
NORMALIZE_TRIM, //MonthDV(),
144
NORMALIZE_TRIM, //HexBinaryDV(),
145
NORMALIZE_NONE, //Base64BinaryDV(), // Base64 know how to deal with spaces
146
NORMALIZE_TRIM, //AnyURIDV(),
147
NORMALIZE_TRIM, //QNameDV(),
148
NORMALIZE_TRIM, //PrecisionDecimalDV() (Schema 1.1)
149
NORMALIZE_TRIM, //QNameDV(), // notation
150
NORMALIZE_TRIM, //IDDV(),
151
NORMALIZE_TRIM, //IDREFDV(),
152
NORMALIZE_TRIM, //EntityDV(),
153
NORMALIZE_TRIM, //IntegerDV(),
154
NORMALIZE_FULL, //ListDV(),
155
NORMALIZE_NONE, //UnionDV(),
156
NORMALIZE_TRIM, //YearMonthDurationDV() (Schema 1.1)
157
NORMALIZE_TRIM, //DayTimeDurationDV() (Schema 1.1)
158
NORMALIZE_NONE, //AnyAtomicDV() (Schema 1.1)
159
};
160     
161     static final short SPECIAL_PATTERN_NONE = 0;
162     static final short SPECIAL_PATTERN_NMTOKEN = 1;
163     static final short SPECIAL_PATTERN_NAME = 2;
164     static final short SPECIAL_PATTERN_NCNAME = 3;
165     
166     static final String JavaDoc[] SPECIAL_PATTERN_STRING = {
167             "NONE", "NMTOKEN", "Name", "NCName"
168     };
169     
170     static final String JavaDoc[] WS_FACET_STRING = {
171             "preserve", "replace", "collapse"
172     };
173     
174     static final String JavaDoc URI_SCHEMAFORSCHEMA = "http://www.w3.org/2001/XMLSchema";
175     static final String JavaDoc ANY_TYPE = "anyType";
176     
177     // XML Schema 1.1 type constants
178
public static final short YEARMONTHDURATION_DT = 46;
179     public static final short DAYTIMEDURATION_DT = 47;
180     public static final short PRECISIONDECIMAL_DT = 48;
181     public static final short ANYATOMICTYPE_DT = 49;
182     
183     // DOM Level 3 TypeInfo Derivation Method constants
184
static final int DERIVATION_ANY = 0;
185     static final int DERIVATION_RESTRICTION = 1;
186     static final int DERIVATION_EXTENSION = 2;
187     static final int DERIVATION_UNION = 4;
188     static final int DERIVATION_LIST = 8;
189     
190     static final ValidationContext fEmptyContext = new ValidationContext() {
191         public boolean needFacetChecking() {
192             return true;
193         }
194         public boolean needExtraChecking() {
195             return false;
196         }
197         public boolean needToNormalize() {
198             return true;
199         }
200         public boolean useNamespaces () {
201             return true;
202         }
203         public boolean isEntityDeclared (String JavaDoc name) {
204             return false;
205         }
206         public boolean isEntityUnparsed (String JavaDoc name) {
207             return false;
208         }
209         public boolean isIdDeclared (String JavaDoc name) {
210             return false;
211         }
212         public void addId(String JavaDoc name) {
213         }
214         public void addIdRef(String JavaDoc name) {
215         }
216         public String JavaDoc getSymbol (String JavaDoc symbol) {
217             return symbol.intern();
218         }
219         public String JavaDoc getURI(String JavaDoc prefix) {
220             return null;
221         }
222     };
223     
224     // this will be true if this is a static XSSimpleTypeDecl
225
// and hence must remain immutable (i.e., applyFacets
226
// may not be permitted to have any effect).
227
private boolean fIsImmutable = false;
228     
229     private XSSimpleTypeDecl fItemType;
230     private XSSimpleTypeDecl[] fMemberTypes;
231     // The most specific built-in type kind.
232
private short fBuiltInKind;
233     
234     private String JavaDoc fTypeName;
235     private String JavaDoc fTargetNamespace;
236     private short fFinalSet = 0;
237     private XSSimpleTypeDecl fBase;
238     private short fVariety = -1;
239     private short fValidationDV = -1;
240     
241     private short fFacetsDefined = 0;
242     private short fFixedFacet = 0;
243     
244     //for constraining facets
245
private short fWhiteSpace = 0;
246     private int fLength = -1;
247     private int fMinLength = -1;
248     private int fMaxLength = -1;
249     private int fTotalDigits = -1;
250     private int fFractionDigits = -1;
251     private Vector JavaDoc fPattern;
252     private Vector JavaDoc fPatternStr;
253     private Vector JavaDoc fEnumeration;
254     private short[] fEnumerationType;
255     private ShortList[] fEnumerationItemType; // used in case fenumerationType value is LIST or LISTOFUNION
256
private ShortList fEnumerationTypeList;
257     private ObjectList fEnumerationItemTypeList;
258     private StringList fLexicalPattern;
259     private StringList fLexicalEnumeration;
260     private ObjectList fActualEnumeration;
261     private Object JavaDoc fMaxInclusive;
262     private Object JavaDoc fMaxExclusive;
263     private Object JavaDoc fMinExclusive;
264     private Object JavaDoc fMinInclusive;
265     
266     // annotations for constraining facets
267
public XSAnnotation lengthAnnotation;
268     public XSAnnotation minLengthAnnotation;
269     public XSAnnotation maxLengthAnnotation;
270     public XSAnnotation whiteSpaceAnnotation;
271     public XSAnnotation totalDigitsAnnotation;
272     public XSAnnotation fractionDigitsAnnotation;
273     public XSObjectListImpl patternAnnotations;
274     public XSObjectList enumerationAnnotations;
275     public XSAnnotation maxInclusiveAnnotation;
276     public XSAnnotation maxExclusiveAnnotation;
277     public XSAnnotation minInclusiveAnnotation;
278     public XSAnnotation minExclusiveAnnotation;
279     
280     // facets as objects
281
private XSObjectListImpl fFacets;
282     
283     // enumeration and pattern facets
284
private XSObjectListImpl fMultiValueFacets;
285     
286     // simpleType annotations
287
private XSObjectList fAnnotations = null;
288     
289     private short fPatternType = SPECIAL_PATTERN_NONE;
290     
291     // for fundamental facets
292
private short fOrdered;
293     private boolean fFinite;
294     private boolean fBounded;
295     private boolean fNumeric;
296     
297     // default constructor
298
public XSSimpleTypeDecl(){}
299     
300     //Create a new built-in primitive types (and id/idref/entity/integer/yearMonthDuration)
301
protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String JavaDoc name, short validateDV,
302             short ordered, boolean bounded, boolean finite,
303             boolean numeric, boolean isImmutable, short builtInKind) {
304         fIsImmutable = isImmutable;
305         fBase = base;
306         fTypeName = name;
307         fTargetNamespace = URI_SCHEMAFORSCHEMA;
308         // To simplify the code for anySimpleType, we treat it as an atomic type
309
fVariety = VARIETY_ATOMIC;
310         fValidationDV = validateDV;
311         fFacetsDefined = FACET_WHITESPACE;
312         if (validateDV == DV_STRING) {
313             fWhiteSpace = WS_PRESERVE;
314         } else {
315             fWhiteSpace = WS_COLLAPSE;
316             fFixedFacet = FACET_WHITESPACE;
317         }
318         this.fOrdered = ordered;
319         this.fBounded = bounded;
320         this.fFinite = finite;
321         this.fNumeric = numeric;
322         fAnnotations = null;
323         
324         // Specify the build in kind for this primitive type
325
fBuiltInKind = builtInKind;
326     }
327     
328     //Create a new simple type for restriction for built-in types
329
protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String JavaDoc name, String JavaDoc uri, short finalSet, boolean isImmutable,
330             XSObjectList annotations, short builtInKind) {
331         this(base, name, uri, finalSet, isImmutable, annotations);
332         // Specify the build in kind for this built-in type
333
fBuiltInKind = builtInKind;
334     }
335     
336     //Create a new simple type for restriction.
337
protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String JavaDoc name, String JavaDoc uri, short finalSet, boolean isImmutable,
338             XSObjectList annotations) {
339         fBase = base;
340         fTypeName = name;
341         fTargetNamespace = uri;
342         fFinalSet = finalSet;
343         fAnnotations = annotations;
344         
345         fVariety = fBase.fVariety;
346         fValidationDV = fBase.fValidationDV;
347         switch (fVariety) {
348         case VARIETY_ATOMIC:
349             break;
350         case VARIETY_LIST:
351             fItemType = fBase.fItemType;
352             break;
353         case VARIETY_UNION:
354             fMemberTypes = fBase.fMemberTypes;
355             break;
356         }
357         
358         // always inherit facets from the base.
359
// in case a type is created, but applyFacets is not called
360
fLength = fBase.fLength;
361         fMinLength = fBase.fMinLength;
362         fMaxLength = fBase.fMaxLength;
363         fPattern = fBase.fPattern;
364         fPatternStr = fBase.fPatternStr;
365         fEnumeration = fBase.fEnumeration;
366         fEnumerationType = fBase.fEnumerationType;
367         fEnumerationItemType = fBase.fEnumerationItemType;
368         fWhiteSpace = fBase.fWhiteSpace;
369         fMaxExclusive = fBase.fMaxExclusive;
370         fMaxInclusive = fBase.fMaxInclusive;
371         fMinExclusive = fBase.fMinExclusive;
372         fMinInclusive = fBase.fMinInclusive;
373         fTotalDigits = fBase.fTotalDigits;
374         fFractionDigits = fBase.fFractionDigits;
375         fPatternType = fBase.fPatternType;
376         fFixedFacet = fBase.fFixedFacet;
377         fFacetsDefined = fBase.fFacetsDefined;
378         
379         //we also set fundamental facets information in case applyFacets is not called.
380
caclFundamentalFacets();
381         fIsImmutable = isImmutable;
382         
383         // Inherit from the base type
384
fBuiltInKind = base.fBuiltInKind;
385     }
386     
387     //Create a new simple type for list.
388
protected XSSimpleTypeDecl(String JavaDoc name, String JavaDoc uri, short finalSet, XSSimpleTypeDecl itemType, boolean isImmutable,
389             XSObjectList annotations) {
390         fBase = fAnySimpleType;
391         fTypeName = name;
392         fTargetNamespace = uri;
393         fFinalSet = finalSet;
394         fAnnotations = annotations;
395         
396         fVariety = VARIETY_LIST;
397         fItemType = (XSSimpleTypeDecl)itemType;
398         fValidationDV = DV_LIST;
399         fFacetsDefined = FACET_WHITESPACE;
400         fFixedFacet = FACET_WHITESPACE;
401         fWhiteSpace = WS_COLLAPSE;
402         
403         //setting fundamental facets
404
caclFundamentalFacets();
405         fIsImmutable = isImmutable;
406         
407         // Values of this type are lists
408
fBuiltInKind = XSConstants.LIST_DT;
409     }
410     
411     //Create a new simple type for union.
412
protected XSSimpleTypeDecl(String JavaDoc name, String JavaDoc uri, short finalSet, XSSimpleTypeDecl[] memberTypes,
413             XSObjectList annotations) {
414         fBase = fAnySimpleType;
415         fTypeName = name;
416         fTargetNamespace = uri;
417         fFinalSet = finalSet;
418         fAnnotations = annotations;
419         
420         fVariety = VARIETY_UNION;
421         fMemberTypes = memberTypes;
422         fValidationDV = DV_UNION;
423         // even for union, we set whitespace to something
424
// this will never be used, but we can use fFacetsDefined to check
425
// whether applyFacets() is allwwed: it's not allowed
426
// if fFacetsDefined != 0
427
fFacetsDefined = FACET_WHITESPACE;
428         fWhiteSpace = WS_COLLAPSE;
429         
430         //setting fundamental facets
431
caclFundamentalFacets();
432         // none of the schema-defined types are unions, so just set
433
// fIsImmutable to false.
434
fIsImmutable = false;
435         
436         // No value can be of this type, so it's unavailable.
437
fBuiltInKind = XSConstants.UNAVAILABLE_DT;
438     }
439     
440     //set values for restriction.
441
protected XSSimpleTypeDecl setRestrictionValues(XSSimpleTypeDecl base, String JavaDoc name, String JavaDoc uri, short finalSet,
442             XSObjectList annotations) {
443         //decline to do anything if the object is immutable.
444
if(fIsImmutable) return null;
445         fBase = base;
446         fTypeName = name;
447         fTargetNamespace = uri;
448         fFinalSet = finalSet;
449         fAnnotations = annotations;
450         
451         fVariety = fBase.fVariety;
452         fValidationDV = fBase.fValidationDV;
453         switch (fVariety) {
454         case VARIETY_ATOMIC:
455             break;
456         case VARIETY_LIST:
457             fItemType = fBase.fItemType;
458             break;
459         case VARIETY_UNION:
460             fMemberTypes = fBase.fMemberTypes;
461             break;
462         }
463         
464         // always inherit facets from the base.
465
// in case a type is created, but applyFacets is not called
466
fLength = fBase.fLength;
467         fMinLength = fBase.fMinLength;
468         fMaxLength = fBase.fMaxLength;
469         fPattern = fBase.fPattern;
470         fPatternStr = fBase.fPatternStr;
471         fEnumeration = fBase.fEnumeration;
472         fEnumerationType = fBase.fEnumerationType;
473         fEnumerationItemType = fBase.fEnumerationItemType;
474         fWhiteSpace = fBase.fWhiteSpace;
475         fMaxExclusive = fBase.fMaxExclusive;
476         fMaxInclusive = fBase.fMaxInclusive;
477         fMinExclusive = fBase.fMinExclusive;
478         fMinInclusive = fBase.fMinInclusive;
479         fTotalDigits = fBase.fTotalDigits;
480         fFractionDigits = fBase.fFractionDigits;
481         fPatternType = fBase.fPatternType;
482         fFixedFacet = fBase.fFixedFacet;
483         fFacetsDefined = fBase.fFacetsDefined;
484         
485         //we also set fundamental facets information in case applyFacets is not called.
486
caclFundamentalFacets();
487         
488         // Inherit from the base type
489
fBuiltInKind = base.fBuiltInKind;
490         
491         return this;
492     }
493     
494     //set values for list.
495
protected XSSimpleTypeDecl setListValues(String JavaDoc name, String JavaDoc uri, short finalSet, XSSimpleTypeDecl itemType,
496             XSObjectList annotations) {
497         //decline to do anything if the object is immutable.
498
if(fIsImmutable) return null;
499         fBase = fAnySimpleType;
500         fTypeName = name;
501         fTargetNamespace = uri;
502         fFinalSet = finalSet;
503         fAnnotations = annotations;
504         
505         fVariety = VARIETY_LIST;
506         fItemType = (XSSimpleTypeDecl)itemType;
507         fValidationDV = DV_LIST;
508         fFacetsDefined = FACET_WHITESPACE;
509         fFixedFacet = FACET_WHITESPACE;
510         fWhiteSpace = WS_COLLAPSE;
511         
512         //setting fundamental facets
513
caclFundamentalFacets();
514         
515         // Values of this type are lists
516
fBuiltInKind = XSConstants.LIST_DT;
517         
518         return this;
519     }
520     
521     //set values for union.
522
protected XSSimpleTypeDecl setUnionValues(String JavaDoc name, String JavaDoc uri, short finalSet, XSSimpleTypeDecl[] memberTypes,
523             XSObjectList annotations) {
524         //decline to do anything if the object is immutable.
525
if(fIsImmutable) return null;
526         fBase = fAnySimpleType;
527         fTypeName = name;
528         fTargetNamespace = uri;
529         fFinalSet = finalSet;
530         fAnnotations = annotations;
531         
532         fVariety = VARIETY_UNION;
533         fMemberTypes = memberTypes;
534         fValidationDV = DV_UNION;
535         // even for union, we set whitespace to something
536
// this will never be used, but we can use fFacetsDefined to check
537
// whether applyFacets() is allwwed: it's not allowed
538
// if fFacetsDefined != 0
539
fFacetsDefined = FACET_WHITESPACE;
540         fWhiteSpace = WS_COLLAPSE;
541         
542         //setting fundamental facets
543
caclFundamentalFacets();
544         
545         // No value can be of this type, so it's unavailable.
546
fBuiltInKind = XSConstants.UNAVAILABLE_DT;
547         
548         return this;
549     }
550     
551     public short getType () {
552         return XSConstants.TYPE_DEFINITION;
553     }
554     
555     public short getTypeCategory () {
556         return SIMPLE_TYPE;
557     }
558     
559     public String JavaDoc getName() {
560         return getAnonymous()?null:fTypeName;
561     }
562     
563     public String JavaDoc getTypeName() {
564         return fTypeName;
565     }
566     
567     public String JavaDoc getNamespace() {
568         return fTargetNamespace;
569     }
570     
571     public short getFinal(){
572         return fFinalSet;
573     }
574     
575     public boolean isFinal(short derivation) {
576         return (fFinalSet & derivation) != 0;
577     }
578     
579     public XSTypeDefinition getBaseType(){
580         return fBase;
581     }
582     
583     public boolean getAnonymous() {
584         return fAnonymous || (fTypeName == null);
585     }
586     
587     public short getVariety(){
588         // for anySimpleType, return absent variaty
589
return fValidationDV == DV_ANYSIMPLETYPE ? VARIETY_ABSENT : fVariety;
590     }
591     
592     public boolean isIDType(){
593         switch (fVariety) {
594         case VARIETY_ATOMIC:
595             return fValidationDV == DV_ID;
596         case VARIETY_LIST:
597             return fItemType.isIDType();
598         case VARIETY_UNION:
599             for (int i = 0; i < fMemberTypes.length; i++) {
600                 if (fMemberTypes[i].isIDType())
601                     return true;
602             }
603         }
604         return false;
605     }
606     
607     public short getWhitespace() throws DatatypeException{
608         if (fVariety == VARIETY_UNION) {
609             throw new DatatypeException("dt-whitespace", new Object JavaDoc[]{fTypeName});
610         }
611         return fWhiteSpace;
612     }
613     
614     public short getPrimitiveKind() {
615         if (fVariety == VARIETY_ATOMIC && fValidationDV != DV_ANYSIMPLETYPE) {
616             if (fValidationDV == DV_ID || fValidationDV == DV_IDREF || fValidationDV == DV_ENTITY) {
617                 return DV_STRING;
618             }
619             else if (fValidationDV == DV_INTEGER) {
620                 return DV_DECIMAL;
621             }
622             else if (Constants.SCHEMA_1_1_SUPPORT && (fValidationDV == DV_YEARMONTHDURATION || fValidationDV == DV_DAYTIMEDURATION)) {
623                 return DV_DURATION;
624             }
625             else {
626                 return fValidationDV;
627             }
628         }
629         else {
630             // REVISIT: error situation. runtime exception?
631
return (short)0;
632         }
633     }
634     
635     /**
636      * Returns the closest built-in type category this type represents or
637      * derived from. For example, if this simple type is a built-in derived
638      * type integer the <code>INTEGER_DV</code> is returned.
639      */

640     public short getBuiltInKind() {
641         return this.fBuiltInKind;
642     }
643     
644     /**
645      * If variety is <code>atomic</code> the primitive type definition (a
646      * built-in primitive datatype definition or the simple ur-type
647      * definition) is available, otherwise <code>null</code>.
648      */

649     public XSSimpleTypeDefinition getPrimitiveType() {
650         if (fVariety == VARIETY_ATOMIC && fValidationDV != DV_ANYSIMPLETYPE) {
651             XSSimpleTypeDecl pri = this;
652             // recursively get base, until we reach anySimpleType
653
while (pri.fBase != fAnySimpleType)
654                 pri = pri.fBase;
655             return pri;
656         }
657         else {
658             // REVISIT: error situation. runtime exception?
659
return null;
660         }
661     }
662     
663     /**
664      * If variety is <code>list</code> the item type definition (an atomic or
665      * union simple type definition) is available, otherwise
666      * <code>null</code>.
667      */

668     public XSSimpleTypeDefinition getItemType() {
669         if (fVariety == VARIETY_LIST) {
670             return fItemType;
671         }
672         else {
673             // REVISIT: error situation. runtime exception?
674
return null;
675         }
676     }
677     
678     /**
679      * If variety is <code>union</code> the list of member type definitions (a
680      * non-empty sequence of simple type definitions) is available,
681      * otherwise an empty <code>XSObjectList</code>.
682      */

683     public XSObjectList getMemberTypes() {
684         if (fVariety == VARIETY_UNION) {
685             return new XSObjectListImpl(fMemberTypes, fMemberTypes.length);
686         }
687         else {
688             return XSObjectListImpl.EMPTY_LIST;
689         }
690     }
691     
692     /**
693      * If <restriction> is chosen
694      */

695     public void applyFacets(XSFacets facets, short presentFacet, short fixedFacet, ValidationContext context)
696     throws InvalidDatatypeFacetException {
697         applyFacets(facets, presentFacet, fixedFacet, SPECIAL_PATTERN_NONE, context);
698     }
699     
700     /**
701      * built-in derived types by restriction
702      */

703     void applyFacets1(XSFacets facets, short presentFacet, short fixedFacet) {
704         
705         try {
706             applyFacets(facets, presentFacet, fixedFacet, SPECIAL_PATTERN_NONE, fDummyContext);
707         } catch (InvalidDatatypeFacetException e) {
708             // should never gets here, internel error
709
throw new RuntimeException JavaDoc("internal error");
710         }
711         // we've now applied facets; so lock this object:
712
fIsImmutable = true;
713     }
714     
715     /**
716      * built-in derived types by restriction
717      */

718     void applyFacets1(XSFacets facets, short presentFacet, short fixedFacet, short patternType) {
719         
720         try {
721             applyFacets(facets, presentFacet, fixedFacet, patternType, fDummyContext);
722         } catch (InvalidDatatypeFacetException e) {
723             // should never gets here, internel error
724
throw new RuntimeException JavaDoc("internal error");
725         }
726         // we've now applied facets; so lock this object:
727
fIsImmutable = true;
728     }
729     
730     /**
731      * If <restriction> is chosen, or built-in derived types by restriction
732      */

733     void applyFacets(XSFacets facets, short presentFacet, short fixedFacet, short patternType, ValidationContext context)
734     throws InvalidDatatypeFacetException {
735         
736         // if the object is immutable, should not apply facets...
737
if(fIsImmutable) return;
738         ValidatedInfo tempInfo = new ValidatedInfo();
739         
740         // clear facets. because we always inherit facets in the constructor
741
// REVISIT: in fact, we don't need to clear them.
742
// we can convert 5 string values (4 bounds + 1 enum) to actual values,
743
// store them somewhere, then do facet checking at once, instead of
744
// going through the following steps. (lots of checking are redundant:
745
// for example, ((presentFacet & FACET_XXX) != 0))
746

747         fFacetsDefined = 0;
748         fFixedFacet = 0;
749         
750         int result = 0 ;
751         
752         // step 1: parse present facets
753
short allowedFacet = fDVs[fValidationDV].getAllowedFacets();
754         
755         // length
756
if ((presentFacet & FACET_LENGTH) != 0) {
757             if ((allowedFacet & FACET_LENGTH) == 0) {
758                 reportError("cos-applicable-facets", new Object JavaDoc[]{"length", fTypeName});
759             } else {
760                 fLength = facets.length;
761                 lengthAnnotation = facets.lengthAnnotation;
762                 fFacetsDefined |= FACET_LENGTH;
763                 if ((fixedFacet & FACET_LENGTH) != 0)
764                     fFixedFacet |= FACET_LENGTH;
765             }
766         }
767         // minLength
768
if ((presentFacet & FACET_MINLENGTH) != 0) {
769             if ((allowedFacet & FACET_MINLENGTH) == 0) {
770                 reportError("cos-applicable-facets", new Object JavaDoc[]{"minLength", fTypeName});
771             } else {
772                 fMinLength = facets.minLength;
773                 minLengthAnnotation = facets.minLengthAnnotation;
774                 fFacetsDefined |= FACET_MINLENGTH;
775                 if ((fixedFacet & FACET_MINLENGTH) != 0)
776                     fFixedFacet |= FACET_MINLENGTH;
777             }
778         }
779         // maxLength
780
if ((presentFacet & FACET_MAXLENGTH) != 0) {
781             if ((allowedFacet & FACET_MAXLENGTH) == 0) {
782                 reportError("cos-applicable-facets", new Object JavaDoc[]{"maxLength", fTypeName});
783             } else {
784                 fMaxLength = facets.maxLength;
785                 maxLengthAnnotation = facets.maxLengthAnnotation;
786                 fFacetsDefined |= FACET_MAXLENGTH;
787                 if ((fixedFacet & FACET_MAXLENGTH) != 0)
788                     fFixedFacet |= FACET_MAXLENGTH;
789             }
790         }
791         // pattern
792
if ((presentFacet & FACET_PATTERN) != 0) {
793             if ((allowedFacet & FACET_PATTERN) == 0) {
794                 reportError("cos-applicable-facets", new Object JavaDoc[]{"pattern", fTypeName});
795             } else {
796                 patternAnnotations = facets.patternAnnotations;
797                 RegularExpression regex = null;
798                 try {
799                     regex = new RegularExpression(facets.pattern, "X");
800                 } catch (Exception JavaDoc e) {
801                     reportError("InvalidRegex", new Object JavaDoc[]{facets.pattern, e.getLocalizedMessage()});
802                 }
803                 if (regex != null) {
804                     fPattern = new Vector JavaDoc();
805                     fPattern.addElement(regex);
806                     fPatternStr = new Vector JavaDoc();
807                     fPatternStr.addElement(facets.pattern);
808                     fFacetsDefined |= FACET_PATTERN;
809                     if ((fixedFacet & FACET_PATTERN) != 0)
810                         fFixedFacet |= FACET_PATTERN;
811                 }
812             }
813         }
814         
815         // enumeration
816
if ((presentFacet & FACET_ENUMERATION) != 0) {
817             if ((allowedFacet & FACET_ENUMERATION) == 0) {
818                 reportError("cos-applicable-facets", new Object JavaDoc[]{"enumeration", fTypeName});
819             } else {
820                 fEnumeration = new Vector JavaDoc();
821                 Vector JavaDoc enumVals = facets.enumeration;
822                 fEnumerationType = new short[enumVals.size()];
823                 fEnumerationItemType = new ShortList[enumVals.size()];
824                 Vector JavaDoc enumNSDecls = facets.enumNSDecls;
825                 ValidationContextImpl ctx = new ValidationContextImpl(context);
826                 enumerationAnnotations = facets.enumAnnotations;
827                 for (int i = 0; i < enumVals.size(); i++) {
828                     if (enumNSDecls != null)
829                         ctx.setNSContext((NamespaceContext)enumNSDecls.elementAt(i));
830                     try {
831                         ValidatedInfo info = this.fBase.validateWithInfo((String JavaDoc)enumVals.elementAt(i), ctx, tempInfo);
832                         // check 4.3.5.c0 must: enumeration values from the value space of base
833
fEnumeration.addElement(info.actualValue);
834                         fEnumerationType[i] = info.actualValueType;
835                         fEnumerationItemType[i] = info.itemValueTypes;
836                     } catch (InvalidDatatypeValueException ide) {
837                         reportError("enumeration-valid-restriction", new Object JavaDoc[]{enumVals.elementAt(i), this.getBaseType().getName()});
838                     }
839                 }
840                 fFacetsDefined |= FACET_ENUMERATION;
841                 if ((fixedFacet & FACET_ENUMERATION) != 0)
842                     fFixedFacet |= FACET_ENUMERATION;
843             }
844         }
845         // whiteSpace
846
if ((presentFacet & FACET_WHITESPACE) != 0) {
847             if ((allowedFacet & FACET_WHITESPACE) == 0) {
848                 reportError("cos-applicable-facets", new Object JavaDoc[]{"whiteSpace", fTypeName});
849             } else {
850                 fWhiteSpace = facets.whiteSpace;
851                 whiteSpaceAnnotation = facets.whiteSpaceAnnotation;
852                 fFacetsDefined |= FACET_WHITESPACE;
853                 if ((fixedFacet & FACET_WHITESPACE) != 0)
854                     fFixedFacet |= FACET_WHITESPACE;
855             }
856         }
857         
858         // maxInclusive
859
if ((presentFacet & FACET_MAXINCLUSIVE) != 0) {
860             if ((allowedFacet & FACET_MAXINCLUSIVE) == 0) {
861                 reportError("cos-applicable-facets", new Object JavaDoc[]{"maxInclusive", fTypeName});
862             } else {
863                 maxInclusiveAnnotation = facets.maxInclusiveAnnotation;
864                 try {
865                     fMaxInclusive = fBase.getActualValue(facets.maxInclusive, context, tempInfo, true);
866                     fFacetsDefined |= FACET_MAXINCLUSIVE;
867                     if ((fixedFacet & FACET_MAXINCLUSIVE) != 0)
868                         fFixedFacet |= FACET_MAXINCLUSIVE;
869                 } catch (InvalidDatatypeValueException ide) {
870                     reportError(ide.getKey(), ide.getArgs());
871                     reportError("FacetValueFromBase", new Object JavaDoc[]{fTypeName, facets.maxInclusive,
872                             "maxInclusive", fBase.getName()});
873                 }
874                 
875                 // check against fixed value in base
876
if (((fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
877                     if ((fBase.fFixedFacet & FACET_MAXINCLUSIVE) != 0) {
878                         if (fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMaxInclusive) != 0)
879                             reportError( "FixedFacetValue", new Object JavaDoc[]{"maxInclusive", fMaxInclusive, fBase.fMaxInclusive, fTypeName});
880                     }
881                 }
882                 // maxInclusive from base
883
try {
884                     fBase.validate(context, tempInfo);
885                 } catch (InvalidDatatypeValueException ide) {
886                     reportError(ide.getKey(), ide.getArgs());
887                     reportError("FacetValueFromBase", new Object JavaDoc[]{fTypeName, facets.maxInclusive,
888                             "maxInclusive", fBase.getName()});
889                 }
890             }
891         }
892         
893         // maxExclusive
894
boolean needCheckBase = true;
895         if ((presentFacet & FACET_MAXEXCLUSIVE) != 0) {
896             if ((allowedFacet & FACET_MAXEXCLUSIVE) == 0) {
897                 reportError("cos-applicable-facets", new Object JavaDoc[]{"maxExclusive", fTypeName});
898             } else {
899                 maxExclusiveAnnotation = facets.maxExclusiveAnnotation;
900                 try {
901                     fMaxExclusive = fBase.getActualValue(facets.maxExclusive, context, tempInfo, true);
902                     fFacetsDefined |= FACET_MAXEXCLUSIVE;
903                     if ((fixedFacet & FACET_MAXEXCLUSIVE) != 0)
904                         fFixedFacet |= FACET_MAXEXCLUSIVE;
905                 } catch (InvalidDatatypeValueException ide) {
906                     reportError(ide.getKey(), ide.getArgs());
907                     reportError("FacetValueFromBase", new Object JavaDoc[]{fTypeName, facets.maxExclusive,
908                             "maxExclusive", fBase.getName()});
909                 }
910                 
911                 // check against fixed value in base
912
if (((fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) {
913                     result = fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMaxExclusive);
914                     if ((fBase.fFixedFacet & FACET_MAXEXCLUSIVE) != 0 && result != 0) {
915                         reportError( "FixedFacetValue", new Object JavaDoc[]{"maxExclusive", facets.maxExclusive, fBase.fMaxExclusive, fTypeName});
916                     }
917                     if (result == 0) {
918                         needCheckBase = false;
919                     }
920                 }
921                 // maxExclusive from base
922
if (needCheckBase) {
923                     try {
924                         fBase.validate(context, tempInfo);
925                     } catch (InvalidDatatypeValueException ide) {
926                         reportError(ide.getKey(), ide.getArgs());
927                         reportError("FacetValueFromBase", new Object JavaDoc[]{fTypeName, facets.maxExclusive,
928                                 "maxExclusive", fBase.getName()});
929                     }
930                 }
931                 // If maxExclusive == base.maxExclusive, then we only need to check
932
// maxExclusive <= base.maxInclusive
933
else if (((fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
934                     if (fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMaxInclusive) > 0) {
935                         reportError( "maxExclusive-valid-restriction.2", new Object JavaDoc[]{facets.maxExclusive, fBase.fMaxInclusive});
936                     }
937                 }
938             }
939         }
940         // minExclusive
941
needCheckBase = true;
942         if ((presentFacet & FACET_MINEXCLUSIVE) != 0) {
943             if ((allowedFacet & FACET_MINEXCLUSIVE) == 0) {
944                 reportError("cos-applicable-facets", new Object JavaDoc[]{"minExclusive", fTypeName});
945             } else {
946                 minExclusiveAnnotation = facets.minExclusiveAnnotation;
947                 try {
948                     fMinExclusive = fBase.getActualValue(facets.minExclusive, context, tempInfo, true);
949                     fFacetsDefined |= FACET_MINEXCLUSIVE;
950                     if ((fixedFacet & FACET_MINEXCLUSIVE) != 0)
951                         fFixedFacet |= FACET_MINEXCLUSIVE;
952                 } catch (InvalidDatatypeValueException ide) {
953                     reportError(ide.getKey(), ide.getArgs());
954                     reportError("FacetValueFromBase", new Object JavaDoc[]{fTypeName, facets.minExclusive,
955                             "minExclusive", fBase.getName()});
956                 }
957                 
958                 // check against fixed value in base
959
if (((fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
960                     result = fDVs[fValidationDV].compare(fMinExclusive, fBase.fMinExclusive);
961                     if ((fBase.fFixedFacet & FACET_MINEXCLUSIVE) != 0 && result != 0) {
962                         reportError( "FixedFacetValue", new Object JavaDoc[]{"minExclusive", facets.minExclusive, fBase.fMinExclusive, fTypeName});
963                     }
964                     if (result == 0) {
965                         needCheckBase = false;
966                     }
967                 }
968                 // minExclusive from base
969
if (needCheckBase) {
970                     try {
971                         fBase.validate(context, tempInfo);
972                     } catch (InvalidDatatypeValueException ide) {
973                         reportError(ide.getKey(), ide.getArgs());
974                         reportError("FacetValueFromBase", new Object JavaDoc[]{fTypeName, facets.minExclusive,
975                                 "minExclusive", fBase.getName()});
976                     }
977                 }
978                 // If minExclusive == base.minExclusive, then we only need to check
979
// minExclusive >= base.minInclusive
980
else if (((fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
981                     if (fDVs[fValidationDV].compare(fMinExclusive, fBase.fMinInclusive) < 0) {
982                         reportError( "minExclusive-valid-restriction.3", new Object JavaDoc[]{facets.minExclusive, fBase.fMinInclusive});
983                     }
984                 }
985             }
986         }
987         // minInclusive
988
if ((presentFacet & FACET_MININCLUSIVE) != 0) {
989             if ((allowedFacet & FACET_MININCLUSIVE) == 0) {
990                 reportError("cos-applicable-facets", new Object JavaDoc[]{"minInclusive", fTypeName});
991             } else {
992                 minInclusiveAnnotation = facets.minInclusiveAnnotation;
993                 try {
994                     fMinInclusive = fBase.getActualValue(facets.minInclusive, context, tempInfo, true);
995                     fFacetsDefined |= FACET_MININCLUSIVE;
996                     if ((fixedFacet & FACET_MININCLUSIVE) != 0)
997                         fFixedFacet |= FACET_MININCLUSIVE;
998                 } catch (InvalidDatatypeValueException ide) {
999                     reportError(ide.getKey(), ide.getArgs());
1000                    reportError("FacetValueFromBase", new Object JavaDoc[]{fTypeName, facets.minInclusive,
1001                            "minInclusive", fBase.getName()});
1002                }
1003                
1004                // check against fixed value in base
1005
if (((fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1006                    if ((fBase.fFixedFacet & FACET_MININCLUSIVE) != 0) {
1007                        if (fDVs[fValidationDV].compare(fMinInclusive, fBase.fMinInclusive) != 0)
1008                            reportError( "FixedFacetValue", new Object JavaDoc[]{"minInclusive", facets.minInclusive, fBase.fMinInclusive, fTypeName});
1009                    }
1010                }
1011                // minInclusive from base
1012
try {
1013                    fBase.validate(context, tempInfo);
1014                } catch (InvalidDatatypeValueException ide) {
1015                    reportError(ide.getKey(), ide.getArgs());
1016                    reportError("FacetValueFromBase", new Object JavaDoc[]{fTypeName, facets.minInclusive,
1017                            "minInclusive", fBase.getName()});
1018                }
1019            }
1020        }
1021        
1022        // totalDigits
1023
if ((presentFacet & FACET_TOTALDIGITS) != 0) {
1024            if ((allowedFacet & FACET_TOTALDIGITS) == 0) {
1025                reportError("cos-applicable-facets", new Object JavaDoc[]{"totalDigits", fTypeName});
1026            } else {
1027                totalDigitsAnnotation = facets.totalDigitsAnnotation;
1028                fTotalDigits = facets.totalDigits;
1029                fFacetsDefined |= FACET_TOTALDIGITS;
1030                if ((fixedFacet & FACET_TOTALDIGITS) != 0)
1031                    fFixedFacet |= FACET_TOTALDIGITS;
1032            }
1033        }
1034        // fractionDigits
1035
if ((presentFacet & FACET_FRACTIONDIGITS) != 0) {
1036            if ((allowedFacet & FACET_FRACTIONDIGITS) == 0) {
1037                reportError("cos-applicable-facets", new Object JavaDoc[]{"fractionDigits", fTypeName});
1038            } else {
1039                fFractionDigits = facets.fractionDigits;
1040                fractionDigitsAnnotation = facets.fractionDigitsAnnotation;
1041                fFacetsDefined |= FACET_FRACTIONDIGITS;
1042                if ((fixedFacet & FACET_FRACTIONDIGITS) != 0)
1043                    fFixedFacet |= FACET_FRACTIONDIGITS;
1044            }
1045        }
1046        
1047        // token type: internal use, so do less checking
1048
if (patternType != SPECIAL_PATTERN_NONE) {
1049            fPatternType = patternType;
1050        }
1051        
1052        // step 2: check facets against each other: length, bounds
1053
if(fFacetsDefined != 0) {
1054            
1055            // check 4.3.1.c1 error: length & (maxLength | minLength)
1056
if((fFacetsDefined & FACET_LENGTH) != 0 ){
1057                if ((fFacetsDefined & FACET_MINLENGTH) != 0) {
1058                    if ((fFacetsDefined & FACET_MAXLENGTH) != 0) {
1059                        // length, minLength and maxLength defined
1060
reportError("length-minLength-maxLength.a", new Object JavaDoc[]{fTypeName, Integer.toString(fLength), Integer.toString(fMinLength), Integer.toString(fMaxLength)});
1061                    }
1062                    else {
1063                        // length and minLength defined
1064
reportError("length-minLength-maxLength.b", new Object JavaDoc[]{fTypeName, Integer.toString(fLength), Integer.toString(fMinLength)});
1065                    }
1066                }
1067                else if ((fFacetsDefined & FACET_MAXLENGTH) != 0) {
1068                    // length and maxLength defined
1069
reportError("length-minLength-maxLength.c", new Object JavaDoc[]{fTypeName, Integer.toString(fLength), Integer.toString(fMaxLength)});
1070                }
1071            }
1072            
1073            // check 4.3.2.c1 must: minLength <= maxLength
1074
if(((fFacetsDefined & FACET_MINLENGTH ) != 0 ) && ((fFacetsDefined & FACET_MAXLENGTH) != 0))
1075            {
1076                if(fMinLength > fMaxLength)
1077                    reportError("minLength-less-than-equal-to-maxLength", new Object JavaDoc[]{Integer.toString(fMinLength), Integer.toString(fMaxLength), fTypeName});
1078            }
1079            
1080            // check 4.3.8.c1 error: maxInclusive + maxExclusive
1081
if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && ((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1082                reportError( "maxInclusive-maxExclusive", new Object JavaDoc[]{fMaxInclusive, fMaxExclusive, fTypeName});
1083            }
1084            
1085            // check 4.3.9.c1 error: minInclusive + minExclusive
1086
if (((fFacetsDefined & FACET_MINEXCLUSIVE) != 0) && ((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1087                reportError("minInclusive-minExclusive", new Object JavaDoc[]{fMinInclusive, fMinExclusive, fTypeName});
1088            }
1089            
1090            // check 4.3.7.c1 must: minInclusive <= maxInclusive
1091
if (((fFacetsDefined & FACET_MAXINCLUSIVE) != 0) && ((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1092                result = fDVs[fValidationDV].compare(fMinInclusive, fMaxInclusive);
1093                if (result != -1 && result != 0)
1094                    reportError("minInclusive-less-than-equal-to-maxInclusive", new Object JavaDoc[]{fMinInclusive, fMaxInclusive, fTypeName});
1095            }
1096            
1097            // check 4.3.8.c2 must: minExclusive <= maxExclusive ??? minExclusive < maxExclusive
1098
if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && ((fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
1099                result = fDVs[fValidationDV].compare(fMinExclusive, fMaxExclusive);
1100                if (result != -1 && result != 0)
1101                    reportError( "minExclusive-less-than-equal-to-maxExclusive", new Object JavaDoc[]{fMinExclusive, fMaxExclusive, fTypeName});
1102            }
1103            
1104            // check 4.3.9.c2 must: minExclusive < maxInclusive
1105
if (((fFacetsDefined & FACET_MAXINCLUSIVE) != 0) && ((fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
1106                if (fDVs[fValidationDV].compare(fMinExclusive, fMaxInclusive) != -1)
1107                    reportError( "minExclusive-less-than-maxInclusive", new Object JavaDoc[]{fMinExclusive, fMaxInclusive, fTypeName});
1108            }
1109            
1110            // check 4.3.10.c1 must: minInclusive < maxExclusive
1111
if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && ((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1112                if (fDVs[fValidationDV].compare(fMinInclusive, fMaxExclusive) != -1)
1113                    reportError( "minInclusive-less-than-maxExclusive", new Object JavaDoc[]{fMinInclusive, fMaxExclusive, fTypeName});
1114            }
1115            
1116            // check 4.3.12.c1 must: fractionDigits <= totalDigits
1117
if (((fFacetsDefined & FACET_FRACTIONDIGITS) != 0) &&
1118                    ((fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
1119                if (fFractionDigits > fTotalDigits)
1120                    reportError( "fractionDigits-totalDigits", new Object JavaDoc[]{Integer.toString(fFractionDigits), Integer.toString(fTotalDigits), fTypeName});
1121            }
1122            
1123            // step 3: check facets against base
1124
// check 4.3.1.c1 error: length & (fBase.maxLength | fBase.minLength)
1125
if((fFacetsDefined & FACET_LENGTH) != 0 ){
1126                if ((fBase.fFacetsDefined & FACET_MINLENGTH) != 0 &&
1127                        fLength < fBase.fMinLength) {
1128                    // length, fBase.minLength and fBase.maxLength defined
1129
reportError("length-minLength-maxLength.d", new Object JavaDoc[]{fTypeName, Integer.toString(fLength), Integer.toString(fBase.fMinLength)});
1130                }
1131                if ((fBase.fFacetsDefined & FACET_MAXLENGTH) != 0 &&
1132                        fLength > fBase.fMaxLength) {
1133                    // length and fBase.maxLength defined
1134
reportError("length-minLength-maxLength.e", new Object JavaDoc[]{fTypeName, Integer.toString(fLength), Integer.toString(fBase.fMaxLength)});
1135                }
1136                if ( (fBase.fFacetsDefined & FACET_LENGTH) != 0 ) {
1137                    // check 4.3.1.c2 error: length != fBase.length
1138
if ( fLength != fBase.fLength )
1139                        reportError( "length-valid-restriction", new Object JavaDoc[]{Integer.toString(fLength), Integer.toString(fBase.fLength), fTypeName});
1140                }
1141            }
1142            
1143            // check 4.3.1.c1 error: fBase.length & (maxLength | minLength)
1144
else if((fBase.fFacetsDefined & FACET_LENGTH) != 0 ){
1145                if ((fFacetsDefined & FACET_MINLENGTH) != 0 &&
1146                        fBase.fLength < fMinLength) {
1147                    // fBase.length, minLength and maxLength defined
1148
reportError("length-minLength-maxLength.d", new Object JavaDoc[]{fTypeName, Integer.toString(fBase.fLength), Integer.toString(fMinLength)});
1149                }
1150                if ((fFacetsDefined & FACET_MAXLENGTH) != 0 &&
1151                        fBase.fLength > fMaxLength) {
1152                    // fBase.length and maxLength defined
1153
reportError("length-minLength-maxLength.e", new Object JavaDoc[]{this, Integer.toString(fBase.fLength), Integer.toString(fMaxLength)});
1154                }
1155            }
1156            
1157            // check 4.3.2.c1 must: minLength <= fBase.maxLength
1158
if ( ((fFacetsDefined & FACET_MINLENGTH ) != 0 ) ) {
1159                if ( (fBase.fFacetsDefined & FACET_MAXLENGTH ) != 0 ) {
1160                    if ( fMinLength > fBase.fMaxLength ) {
1161                        reportError("minLength-less-than-equal-to-maxLength", new Object JavaDoc[]{Integer.toString(fMinLength), Integer.toString(fBase.fMaxLength), fTypeName});
1162                    }
1163                }
1164                else if ( (fBase.fFacetsDefined & FACET_MINLENGTH) != 0 ) {
1165                    if ( (fBase.fFixedFacet & FACET_MINLENGTH) != 0 && fMinLength != fBase.fMinLength ) {
1166                        reportError( "FixedFacetValue", new Object JavaDoc[]{"minLength", Integer.toString(fMinLength), Integer.toString(fBase.fMinLength), fTypeName});
1167                    }
1168                    
1169                    // check 4.3.2.c2 error: minLength < fBase.minLength
1170
if ( fMinLength < fBase.fMinLength ) {
1171                        reportError( "minLength-valid-restriction", new Object JavaDoc[]{Integer.toString(fMinLength), Integer.toString(fBase.fMinLength), fTypeName});
1172                    }
1173                }
1174            }
1175            
1176            
1177            // check 4.3.2.c1 must: maxLength < fBase.minLength
1178
if ( ((fFacetsDefined & FACET_MAXLENGTH ) != 0 ) && ((fBase.fFacetsDefined & FACET_MINLENGTH ) != 0 )) {
1179                if ( fMaxLength < fBase.fMinLength) {
1180                    reportError("minLength-less-than-equal-to-maxLength", new Object JavaDoc[]{Integer.toString(fBase.fMinLength), Integer.toString(fMaxLength)});
1181                }
1182            }
1183            
1184            // check 4.3.3.c1 error: maxLength > fBase.maxLength
1185
if ( (fFacetsDefined & FACET_MAXLENGTH) != 0 ) {
1186                if ( (fBase.fFacetsDefined & FACET_MAXLENGTH) != 0 ){
1187                    if(( (fBase.fFixedFacet & FACET_MAXLENGTH) != 0 )&& fMaxLength != fBase.fMaxLength ) {
1188                        reportError( "FixedFacetValue", new Object JavaDoc[]{"maxLength", Integer.toString(fMaxLength), Integer.toString(fBase.fMaxLength), fTypeName});
1189                    }
1190                    if ( fMaxLength > fBase.fMaxLength ) {
1191                        reportError( "maxLength-valid-restriction", new Object JavaDoc[]{Integer.toString(fMaxLength), Integer.toString(fBase.fMaxLength), fTypeName});
1192                    }
1193                }
1194            }
1195            
1196            /* // check 4.3.7.c2 error:
1197             // maxInclusive > fBase.maxInclusive
1198              // maxInclusive >= fBase.maxExclusive
1199               // maxInclusive < fBase.minInclusive
1200                // maxInclusive <= fBase.minExclusive
1201                 
1202                 if (((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1203                 if (((fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1204                 result = fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMaxInclusive);
1205                 if ((fBase.fFixedFacet & FACET_MAXINCLUSIVE) != 0 && result != 0) {
1206                 reportError( "FixedFacetValue", new Object[]{"maxInclusive", fMaxInclusive, fBase.fMaxInclusive, fTypeName});
1207                 }
1208                 if (result != -1 && result != 0) {
1209                 reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMaxInclusive, fTypeName});
1210                 }
1211                 }
1212                 if (((fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) &&
1213                 fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMaxExclusive) != -1){
1214                 reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMaxExclusive, fTypeName});
1215                 }
1216                 
1217                 if ((( fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1218                 result = fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMinInclusive);
1219                 if (result != 1 && result != 0) {
1220                 reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMinInclusive, fTypeName});
1221                 }
1222                 }
1223                 
1224                 if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0) &&
1225                 fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMinExclusive ) != 1)
1226                 reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMinExclusive, fTypeName});
1227                 }
1228                 
1229                 // check 4.3.8.c3 error:
1230                  // maxExclusive > fBase.maxExclusive
1231                   // maxExclusive > fBase.maxInclusive
1232                    // maxExclusive <= fBase.minInclusive
1233                     // maxExclusive <= fBase.minExclusive
1234                      if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) {
1235                      if ((( fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) {
1236                      result= fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMaxExclusive);
1237                      if ((fBase.fFixedFacet & FACET_MAXEXCLUSIVE) != 0 && result != 0) {
1238                      reportError( "FixedFacetValue", new Object[]{"maxExclusive", fMaxExclusive, fBase.fMaxExclusive, fTypeName});
1239                      }
1240                      if (result != -1 && result != 0) {
1241                      reportError( "maxExclusive-valid-restriction.1", new Object[]{fMaxExclusive, fBase.fMaxExclusive, fTypeName});
1242                      }
1243                      }
1244                      
1245                      if ((( fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1246                      result= fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMaxInclusive);
1247                      if (result != -1 && result != 0) {
1248                      reportError( "maxExclusive-valid-restriction.2", new Object[]{fMaxExclusive, fBase.fMaxInclusive, fTypeName});
1249                      }
1250                      }
1251                      
1252                      if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0) &&
1253                      fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMinExclusive ) != 1)
1254                      reportError( "maxExclusive-valid-restriction.3", new Object[]{fMaxExclusive, fBase.fMinExclusive, fTypeName});
1255                      
1256                      if ((( fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0) &&
1257                      fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMinInclusive) != 1)
1258                      reportError( "maxExclusive-valid-restriction.4", new Object[]{fMaxExclusive, fBase.fMinInclusive, fTypeName});
1259                      }
1260                      
1261                      // check 4.3.9.c3 error:
1262                       // minExclusive < fBase.minExclusive
1263                        // minExclusive > fBase.maxInclusive
1264                         // minExclusive < fBase.minInclusive
1265                          // minExclusive >= fBase.maxExclusive
1266                           if (((fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
1267                           if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
1268                           result= fDVs[fValidationDV].compare(fMinExclusive, fBase.fMinExclusive);
1269                           if ((fBase.fFixedFacet & FACET_MINEXCLUSIVE) != 0 && result != 0) {
1270                           reportError( "FixedFacetValue", new Object[]{"minExclusive", fMinExclusive, fBase.fMinExclusive, fTypeName});
1271                           }
1272                           if (result != 1 && result != 0) {
1273                           reportError( "minExclusive-valid-restriction.1", new Object[]{fMinExclusive, fBase.fMinExclusive, fTypeName});
1274                           }
1275                           }
1276                           
1277                           if ((( fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1278                           result=fDVs[fValidationDV].compare(fMinExclusive, fBase.fMaxInclusive);
1279                           
1280                           if (result != -1 && result != 0) {
1281                           reportError( "minExclusive-valid-restriction.2", new Object[]{fMinExclusive, fBase.fMaxInclusive, fTypeName});
1282                           }
1283                           }
1284                           
1285                           if ((( fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1286                           result = fDVs[fValidationDV].compare(fMinExclusive, fBase.fMinInclusive);
1287                           
1288                           if (result != 1 && result != 0) {
1289                           reportError( "minExclusive-valid-restriction.3", new Object[]{fMinExclusive, fBase.fMinInclusive, fTypeName});
1290                           }
1291                           }
1292                           
1293                           if ((( fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) &&
1294                           fDVs[fValidationDV].compare(fMinExclusive, fBase.fMaxExclusive) != -1)
1295                           reportError( "minExclusive-valid-restriction.4", new Object[]{fMinExclusive, fBase.fMaxExclusive, fTypeName});
1296                           }
1297                           
1298                           // check 4.3.10.c2 error:
1299                            // minInclusive < fBase.minInclusive
1300                             // minInclusive > fBase.maxInclusive
1301                              // minInclusive <= fBase.minExclusive
1302                               // minInclusive >= fBase.maxExclusive
1303                                if (((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1304                                if (((fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1305                                result = fDVs[fValidationDV].compare(fMinInclusive, fBase.fMinInclusive);
1306                                
1307                                if ((fBase.fFixedFacet & FACET_MININCLUSIVE) != 0 && result != 0) {
1308                                reportError( "FixedFacetValue", new Object[]{"minInclusive", fMinInclusive, fBase.fMinInclusive, fTypeName});
1309                                }
1310                                if (result != 1 && result != 0) {
1311                                reportError( "minInclusive-valid-restriction.1", new Object[]{fMinInclusive, fBase.fMinInclusive, fTypeName});
1312                                }
1313                                }
1314                                if ((( fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1315                                result=fDVs[fValidationDV].compare(fMinInclusive, fBase.fMaxInclusive);
1316                                if (result != -1 && result != 0) {
1317                                reportError( "minInclusive-valid-restriction.2", new Object[]{fMinInclusive, fBase.fMaxInclusive, fTypeName});
1318                                }
1319                                }
1320                                if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0) &&
1321                                fDVs[fValidationDV].compare(fMinInclusive, fBase.fMinExclusive ) != 1)
1322                                reportError( "minInclusive-valid-restriction.3", new Object[]{fMinInclusive, fBase.fMinExclusive, fTypeName});
1323                                if ((( fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) &&
1324                                fDVs[fValidationDV].compare(fMinInclusive, fBase.fMaxExclusive) != -1)
1325                                reportError( "minInclusive-valid-restriction.4", new Object[]{fMinInclusive, fBase.fMaxExclusive, fTypeName});
1326                                }
1327                                */

1328            // check 4.3.11.c1 error: totalDigits > fBase.totalDigits
1329
if (((fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
1330                if ((( fBase.fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
1331                    if ((fBase.fFixedFacet & FACET_TOTALDIGITS) != 0 && fTotalDigits != fBase.fTotalDigits) {
1332                        reportError("FixedFacetValue", new Object JavaDoc[]{"totalDigits", Integer.toString(fTotalDigits), Integer.toString(fBase.fTotalDigits), fTypeName});
1333                    }
1334                    if (fTotalDigits > fBase.fTotalDigits) {
1335                        reportError( "totalDigits-valid-restriction", new Object JavaDoc[]{Integer.toString(fTotalDigits), Integer.toString(fBase.fTotalDigits), fTypeName});
1336                    }
1337                }
1338            }
1339            
1340            // check 4.3.12.c1 must: fractionDigits <= base.totalDigits
1341
if ((fFacetsDefined & FACET_FRACTIONDIGITS) != 0) {
1342                if ((fBase.fFacetsDefined & FACET_TOTALDIGITS) != 0) {
1343                    if (fFractionDigits > fBase.fTotalDigits)
1344                        reportError( "fractionDigits-totalDigits", new Object JavaDoc[]{Integer.toString(fFractionDigits), Integer.toString(fTotalDigits), fTypeName});
1345                }
1346            }
1347            
1348            // check 4.3.12.c2 error: fractionDigits > fBase.fractionDigits
1349
// check fixed value for fractionDigits
1350
if (((fFacetsDefined & FACET_FRACTIONDIGITS) != 0)) {
1351                if ((( fBase.fFacetsDefined & FACET_FRACTIONDIGITS) != 0)) {
1352                    if ((fBase.fFixedFacet & FACET_FRACTIONDIGITS) != 0 && fFractionDigits != fBase.fFractionDigits) {
1353                        reportError("FixedFacetValue", new Object JavaDoc[]{"fractionDigits", Integer.toString(fFractionDigits), Integer.toString(fBase.fFractionDigits), fTypeName});
1354                    }
1355                    if (fFractionDigits > fBase.fFractionDigits) {
1356                        reportError( "fractionDigits-valid-restriction", new Object JavaDoc[]{Integer.toString(fFractionDigits), Integer.toString(fBase.fFractionDigits), fTypeName});
1357                    }
1358                }
1359            }
1360            
1361            // check 4.3.6.c1 error:
1362
// (whiteSpace = preserve || whiteSpace = replace) && fBase.whiteSpace = collapese or
1363
// whiteSpace = preserve && fBase.whiteSpace = replace
1364

1365            if ( (fFacetsDefined & FACET_WHITESPACE) != 0 && (fBase.fFacetsDefined & FACET_WHITESPACE) != 0 ){
1366                if ( (fBase.fFixedFacet & FACET_WHITESPACE) != 0 && fWhiteSpace != fBase.fWhiteSpace ) {
1367                    reportError( "FixedFacetValue", new Object JavaDoc[]{"whiteSpace", whiteSpaceValue(fWhiteSpace), whiteSpaceValue(fBase.fWhiteSpace), fTypeName});
1368                }
1369                
1370                if ( fWhiteSpace == WS_PRESERVE && fBase.fWhiteSpace == WS_COLLAPSE ){
1371                    reportError( "whiteSpace-valid-restriction.1", new Object JavaDoc[]{fTypeName, "preserve"});
1372                }
1373                if ( fWhiteSpace == WS_REPLACE && fBase.fWhiteSpace == WS_COLLAPSE ){
1374                    reportError( "whiteSpace-valid-restriction.1", new Object JavaDoc[]{fTypeName, "replace"});
1375                }
1376                if ( fWhiteSpace == WS_PRESERVE && fBase.fWhiteSpace == WS_REPLACE ){
1377                    reportError( "whiteSpace-valid-restriction.2", new Object JavaDoc[]{fTypeName});
1378                }
1379            }
1380        }//fFacetsDefined != null
1381

1382        // step 4: inherit other facets from base (including fTokeyType)
1383

1384        // inherit length
1385
if ( (fFacetsDefined & FACET_LENGTH) == 0 && (fBase.fFacetsDefined & FACET_LENGTH) != 0 ) {
1386            fFacetsDefined |= FACET_LENGTH;
1387            fLength = fBase.fLength;
1388            lengthAnnotation = fBase.lengthAnnotation;
1389        }
1390        // inherit minLength
1391
if ( (fFacetsDefined & FACET_MINLENGTH) == 0 && (fBase.fFacetsDefined & FACET_MINLENGTH) != 0 ) {
1392            fFacetsDefined |= FACET_MINLENGTH;
1393            fMinLength = fBase.fMinLength;
1394            minLengthAnnotation = fBase.minLengthAnnotation;
1395        }
1396        // inherit maxLength
1397
if ((fFacetsDefined & FACET_MAXLENGTH) == 0 && (fBase.fFacetsDefined & FACET_MAXLENGTH) != 0 ) {
1398            fFacetsDefined |= FACET_MAXLENGTH;
1399            fMaxLength = fBase.fMaxLength;
1400            maxLengthAnnotation = fBase.maxLengthAnnotation;
1401        }
1402        // inherit pattern
1403
if ( (fBase.fFacetsDefined & FACET_PATTERN) != 0 ) {
1404            if ((fFacetsDefined & FACET_PATTERN) == 0) {
1405                fPattern = fBase.fPattern;
1406                fPatternStr = fBase.fPatternStr;
1407                fFacetsDefined |= FACET_PATTERN;
1408            }
1409            else {
1410                for (int i = fBase.fPattern.size()-1; i >= 0; i--) {
1411                    fPattern.addElement(fBase.fPattern.elementAt(i));
1412                    fPatternStr.addElement(fBase.fPatternStr.elementAt(i));
1413                }
1414                if (fBase.patternAnnotations != null){
1415                    for (int i = fBase.patternAnnotations.getLength()-1;i>=0;i--){
1416                        patternAnnotations.add(fBase.patternAnnotations.item(i));
1417                    }
1418                }
1419            }
1420        }
1421        // inherit whiteSpace
1422
if ( (fFacetsDefined & FACET_WHITESPACE) == 0 && (fBase.fFacetsDefined & FACET_WHITESPACE) != 0 ) {
1423            fFacetsDefined |= FACET_WHITESPACE;
1424            fWhiteSpace = fBase.fWhiteSpace;
1425            whiteSpaceAnnotation = fBase.whiteSpaceAnnotation;
1426        }
1427        // inherit enumeration
1428
if ((fFacetsDefined & FACET_ENUMERATION) == 0 && (fBase.fFacetsDefined & FACET_ENUMERATION) != 0) {
1429            fFacetsDefined |= FACET_ENUMERATION;
1430            fEnumeration = fBase.fEnumeration;
1431            enumerationAnnotations = fBase.enumerationAnnotations;
1432        }
1433        // inherit maxExclusive
1434
if ((( fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) &&
1435                !((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && !((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1436            fFacetsDefined |= FACET_MAXEXCLUSIVE;
1437            fMaxExclusive = fBase.fMaxExclusive;
1438            maxExclusiveAnnotation = fBase.maxExclusiveAnnotation;
1439        }
1440        // inherit maxInclusive
1441
if ((( fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0) &&
1442                !((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && !((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1443            fFacetsDefined |= FACET_MAXINCLUSIVE;
1444            fMaxInclusive = fBase.fMaxInclusive;
1445            maxInclusiveAnnotation = fBase.maxInclusiveAnnotation;
1446        }
1447        // inherit minExclusive
1448
if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0) &&
1449                !((fFacetsDefined & FACET_MINEXCLUSIVE) != 0) && !((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1450            fFacetsDefined |= FACET_MINEXCLUSIVE;
1451            fMinExclusive = fBase.fMinExclusive;
1452            minExclusiveAnnotation = fBase.minExclusiveAnnotation;
1453        }
1454        // inherit minExclusive
1455
if ((( fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0) &&
1456                !((fFacetsDefined & FACET_MINEXCLUSIVE) != 0) && !((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1457            fFacetsDefined |= FACET_MININCLUSIVE;
1458            fMinInclusive = fBase.fMinInclusive;
1459            minInclusiveAnnotation = fBase.minInclusiveAnnotation;
1460        }
1461        // inherit totalDigits
1462
if ((( fBase.fFacetsDefined & FACET_TOTALDIGITS) != 0) &&
1463                !((fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
1464            fFacetsDefined |= FACET_TOTALDIGITS;
1465            fTotalDigits = fBase.fTotalDigits;
1466            totalDigitsAnnotation = fBase.totalDigitsAnnotation;
1467        }
1468        // inherit fractionDigits
1469
if ((( fBase.fFacetsDefined & FACET_FRACTIONDIGITS) != 0)
1470                && !((fFacetsDefined & FACET_FRACTIONDIGITS) != 0)) {
1471            fFacetsDefined |= FACET_FRACTIONDIGITS;
1472            fFractionDigits = fBase.fFractionDigits;
1473            fractionDigitsAnnotation = fBase.fractionDigitsAnnotation;
1474        }
1475        //inherit tokeytype
1476
if ((fPatternType == SPECIAL_PATTERN_NONE ) && (fBase.fPatternType != SPECIAL_PATTERN_NONE)) {
1477            fPatternType = fBase.fPatternType ;
1478        }
1479        
1480        // step 5: mark fixed values
1481
fFixedFacet |= fBase.fFixedFacet;
1482        
1483        //step 6: setting fundamental facets
1484
caclFundamentalFacets();
1485        
1486    } //applyFacets()
1487

1488    /**
1489     * validate a value, and return the compiled form
1490     */

1491    public Object JavaDoc validate(String JavaDoc content, ValidationContext context, ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {
1492        
1493        if (context == null)
1494            context = fEmptyContext;
1495        
1496        if (validatedInfo == null)
1497            validatedInfo = new ValidatedInfo();
1498        else
1499            validatedInfo.memberType = null;
1500        
1501        // first normalize string value, and convert it to actual value
1502
boolean needNormalize = context==null||context.needToNormalize();
1503        Object JavaDoc ob = getActualValue(content, context, validatedInfo, needNormalize);
1504        
1505        validate(context, validatedInfo);
1506        
1507        return ob;
1508        
1509    }
1510    
1511    /**
1512     * validate a value, and return the compiled form
1513     */

1514    public ValidatedInfo validateWithInfo(String JavaDoc content, ValidationContext context, ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {
1515        
1516        if (context == null)
1517            context = fEmptyContext;
1518        
1519        if (validatedInfo == null)
1520            validatedInfo = new ValidatedInfo();
1521        else
1522            validatedInfo.memberType = null;
1523        
1524        // first normalize string value, and convert it to actual value
1525
boolean needNormalize = context==null||context.needToNormalize();
1526        getActualValue(content, context, validatedInfo, needNormalize);
1527        
1528        validate(context, validatedInfo);
1529        
1530        return validatedInfo;
1531        
1532    }
1533    
1534    /**
1535     * validate a value, and return the compiled form
1536     */

1537    public Object JavaDoc validate(Object JavaDoc content, ValidationContext context, ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {
1538        
1539        if (context == null)
1540            context = fEmptyContext;
1541        
1542        if (validatedInfo == null)
1543            validatedInfo = new ValidatedInfo();
1544        else
1545            validatedInfo.memberType = null;
1546        
1547        // first normalize string value, and convert it to actual value
1548
boolean needNormalize = context==null||context.needToNormalize();
1549        Object JavaDoc ob = getActualValue(content, context, validatedInfo, needNormalize);
1550        
1551        validate(context, validatedInfo);
1552        
1553        return ob;
1554        
1555    }
1556    
1557    /**
1558     * validate an actual value against this DV
1559     *
1560     * @param context the validation context
1561     * @param validatedInfo used to provide the actual value and member types
1562     */

1563    public void validate(ValidationContext context, ValidatedInfo validatedInfo)
1564    throws InvalidDatatypeValueException {
1565        
1566        if (context == null)
1567            context = fEmptyContext;
1568        
1569        // then validate the actual value against the facets
1570
if (context.needFacetChecking() &&
1571                (fFacetsDefined != 0 && fFacetsDefined != FACET_WHITESPACE)) {
1572            checkFacets(validatedInfo);
1573        }
1574        
1575        // now check extra rules: for ID/IDREF/ENTITY
1576
if (context.needExtraChecking()) {
1577            checkExtraRules(context, validatedInfo);
1578        }
1579        
1580    }
1581    
1582    private void checkFacets(ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {
1583        
1584        Object JavaDoc ob = validatedInfo.actualValue;
1585        String JavaDoc content = validatedInfo.normalizedValue;
1586        short type = validatedInfo.actualValueType;
1587        ShortList itemType = validatedInfo.itemValueTypes;
1588        
1589        // For QName and NOTATION types, we don't check length facets
1590
if (fValidationDV != DV_QNAME && fValidationDV != DV_NOTATION) {
1591            int length = fDVs[fValidationDV].getDataLength(ob);
1592            
1593            // maxLength
1594
if ( (fFacetsDefined & FACET_MAXLENGTH) != 0 ) {
1595                if ( length > fMaxLength ) {
1596                    throw new InvalidDatatypeValueException("cvc-maxLength-valid",
1597                            new Object JavaDoc[]{content, Integer.toString(length), Integer.toString(fMaxLength), fTypeName});
1598                }
1599            }
1600            
1601            //minLength
1602
if ( (fFacetsDefined & FACET_MINLENGTH) != 0 ) {
1603                if ( length < fMinLength ) {
1604                    throw new InvalidDatatypeValueException("cvc-minLength-valid",
1605                            new Object JavaDoc[]{content, Integer.toString(length), Integer.toString(fMinLength), fTypeName});
1606                }
1607            }
1608            
1609            //length
1610
if ( (fFacetsDefined & FACET_LENGTH) != 0 ) {
1611                if ( length != fLength ) {
1612                    throw new InvalidDatatypeValueException("cvc-length-valid",
1613                            new Object JavaDoc[]{content, Integer.toString(length), Integer.toString(fLength), fTypeName});
1614                }
1615            }
1616        }
1617        
1618        //enumeration
1619
if ( ((fFacetsDefined & FACET_ENUMERATION) != 0 ) ) {
1620            boolean present = false;
1621            final int enumSize = fEnumeration.size();
1622            final short primitiveType1 = convertToPrimitiveKind(type);
1623            for (int i = 0; i < enumSize; i++) {
1624                final short primitiveType2 = convertToPrimitiveKind(fEnumerationType[i]);
1625                if ((primitiveType1 == primitiveType2 ||
1626                     primitiveType1 == XSConstants.ANYSIMPLETYPE_DT && primitiveType2 == XSConstants.STRING_DT ||
1627                     primitiveType1 == XSConstants.STRING_DT && primitiveType2 == XSConstants.ANYSIMPLETYPE_DT)
1628                     && fEnumeration.elementAt(i).equals(ob)) {
1629                    if (primitiveType1 == XSConstants.LIST_DT || primitiveType1 == XSConstants.LISTOFUNION_DT) {
1630                        ShortList enumItemType = fEnumerationItemType[i];
1631                        final int typeList1Length = itemType != null ? itemType.getLength() : 0;
1632                        final int typeList2Length = enumItemType != null ? enumItemType.getLength() : 0;
1633                        if (typeList1Length == typeList2Length) {
1634                            int j;
1635                            for (j = 0; j < typeList1Length; ++j) {
1636                                final short primitiveItem1 = convertToPrimitiveKind(itemType.item(j));
1637                                final short primitiveItem2 = convertToPrimitiveKind(enumItemType.item(j));
1638                                if (primitiveItem1 != primitiveItem2) {
1639                                    if (primitiveItem1 == XSConstants.ANYSIMPLETYPE_DT && primitiveItem2 == XSConstants.STRING_DT ||
1640                                        primitiveItem1 == XSConstants.STRING_DT && primitiveItem2 == XSConstants.ANYSIMPLETYPE_DT) {
1641                                        continue;
1642                                    }
1643                                    break;
1644                                }
1645                            }
1646                            if (j == typeList1Length) {
1647                                present = true;
1648                                break;
1649                            }
1650                        }
1651                    }
1652                    else {
1653                        present = true;
1654                        break;
1655                    }
1656                }
1657            }
1658            if(!present){
1659                throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1660                        new Object JavaDoc [] {content, fEnumeration.toString()});
1661            }
1662        }
1663        
1664        //fractionDigits
1665
if ((fFacetsDefined & FACET_FRACTIONDIGITS) != 0) {
1666            int scale = fDVs[fValidationDV].getFractionDigits(ob);
1667            if (scale > fFractionDigits) {
1668                throw new InvalidDatatypeValueException("cvc-fractionDigits-valid",
1669                        new Object JavaDoc[] {content, Integer.toString(scale), Integer.toString(fFractionDigits)});
1670            }
1671        }
1672        
1673        //totalDigits
1674
if ((fFacetsDefined & FACET_TOTALDIGITS)!=0) {
1675            int totalDigits = fDVs[fValidationDV].getTotalDigits(ob);
1676            if (totalDigits > fTotalDigits) {
1677                throw new InvalidDatatypeValueException("cvc-totalDigits-valid",
1678                        new Object JavaDoc[] {content, Integer.toString(totalDigits), Integer.toString(fTotalDigits)});
1679            }
1680        }
1681        
1682        int compare;
1683        
1684        //maxinclusive
1685
if ( (fFacetsDefined & FACET_MAXINCLUSIVE) != 0 ) {
1686            compare = fDVs[fValidationDV].compare(ob, fMaxInclusive);
1687            if (compare != -1 && compare != 0) {
1688                throw new InvalidDatatypeValueException("cvc-maxInclusive-valid",
1689                        new Object JavaDoc[] {content, fMaxInclusive, fTypeName});
1690            }
1691        }
1692        
1693        //maxExclusive
1694
if ( (fFacetsDefined & FACET_MAXEXCLUSIVE) != 0 ) {
1695            compare = fDVs[fValidationDV].compare(ob, fMaxExclusive );
1696            if (compare != -1) {
1697                throw new InvalidDatatypeValueException("cvc-maxExclusive-valid",
1698                        new Object JavaDoc[] {content, fMaxExclusive, fTypeName});
1699            }
1700        }
1701        
1702        //minInclusive
1703
if ( (fFacetsDefined & FACET_MININCLUSIVE) != 0 ) {
1704            compare = fDVs[fValidationDV].compare(ob, fMinInclusive);
1705            if (compare != 1 && compare != 0) {
1706                throw new InvalidDatatypeValueException("cvc-minInclusive-valid",
1707                        new Object JavaDoc[] {content, fMinInclusive, fTypeName});
1708            }
1709        }
1710        
1711        //minExclusive
1712
if ( (fFacetsDefined & FACET_MINEXCLUSIVE) != 0 ) {
1713            compare = fDVs[fValidationDV].compare(ob, fMinExclusive);
1714            if (compare != 1) {
1715                throw new InvalidDatatypeValueException("cvc-minExclusive-valid",
1716                        new Object JavaDoc[] {content, fMinExclusive, fTypeName});
1717            }
1718        }
1719        
1720    }
1721    
1722    private void checkExtraRules(ValidationContext context, ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {
1723        
1724        Object JavaDoc ob = validatedInfo.actualValue;
1725        
1726        if (fVariety == VARIETY_ATOMIC) {
1727            
1728            fDVs[fValidationDV].checkExtraRules(ob, context);
1729            
1730        } else if (fVariety == VARIETY_LIST) {
1731            
1732            ListDV.ListData values = (ListDV.ListData)ob;
1733            int len = values.getLength();
1734            if (fItemType.fVariety == VARIETY_UNION) {
1735                XSSimpleTypeDecl[] memberTypes = (XSSimpleTypeDecl[])validatedInfo.memberTypes;
1736                XSSimpleType memberType = validatedInfo.memberType;
1737                for (int i = len-1; i >= 0; i--) {
1738                    validatedInfo.actualValue = values.item(i);
1739                    validatedInfo.memberType = memberTypes[i];
1740                    fItemType.checkExtraRules(context, validatedInfo);
1741                }
1742                validatedInfo.memberType = memberType;
1743            } else { // (fVariety == VARIETY_ATOMIC)
1744
for (int i = len-1; i >= 0; i--) {
1745                    validatedInfo.actualValue = values.item(i);
1746                    fItemType.checkExtraRules(context, validatedInfo);
1747                }
1748            }
1749            validatedInfo.actualValue = values;
1750            
1751        } else { // (fVariety == VARIETY_UNION)
1752

1753            ((XSSimpleTypeDecl)validatedInfo.memberType).checkExtraRules(context, validatedInfo);
1754            
1755        }
1756        
1757    }// checkExtraRules()
1758

1759    //we can still return object for internal use.
1760
private Object JavaDoc getActualValue(Object JavaDoc content, ValidationContext context,
1761            ValidatedInfo validatedInfo, boolean needNormalize)
1762    throws InvalidDatatypeValueException{
1763        
1764        String JavaDoc nvalue;
1765        if (needNormalize) {
1766            nvalue = normalize(content, fWhiteSpace);
1767        } else {
1768            nvalue = content.toString();
1769        }
1770        if ( (fFacetsDefined & FACET_PATTERN ) != 0 ) {
1771            RegularExpression regex;
1772            for (int idx = fPattern.size()-1; idx >= 0; idx--) {
1773                regex = (RegularExpression)fPattern.elementAt(idx);
1774                if (!regex.matches(nvalue)){
1775                    throw new InvalidDatatypeValueException("cvc-pattern-valid",
1776                            new Object JavaDoc[]{content,
1777                            fPatternStr.elementAt(idx),
1778                            
1779                            fTypeName});
1780                }
1781            }
1782        }
1783        
1784        if (fVariety == VARIETY_ATOMIC) {
1785            
1786            // validate special kinds of token, in place of old pattern matching
1787
if (fPatternType != SPECIAL_PATTERN_NONE) {
1788                
1789                boolean seenErr = false;
1790                if (fPatternType == SPECIAL_PATTERN_NMTOKEN) {
1791                    // PATTERN "\\c+"
1792
seenErr = !XMLChar.isValidNmtoken(nvalue);
1793                }
1794                else if (fPatternType == SPECIAL_PATTERN_NAME) {
1795                    // PATTERN "\\i\\c*"
1796
seenErr = !XMLChar.isValidName(nvalue);
1797                }
1798                else if (fPatternType == SPECIAL_PATTERN_NCNAME) {
1799                    // PATTERN "[\\i-[:]][\\c-[:]]*"
1800
seenErr = !XMLChar.isValidNCName(nvalue);
1801                }
1802                if (seenErr) {
1803                    throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1",
1804                            new Object JavaDoc[]{nvalue, SPECIAL_PATTERN_STRING[fPatternType]});
1805                }
1806            }
1807            
1808            validatedInfo.normalizedValue = nvalue;
1809            Object JavaDoc avalue = fDVs[fValidationDV].getActualValue(nvalue, context);
1810            validatedInfo.actualValue = avalue;
1811            validatedInfo.actualValueType = fBuiltInKind;
1812            
1813            return avalue;
1814            
1815        } else if (fVariety == VARIETY_LIST) {
1816            
1817            StringTokenizer JavaDoc parsedList = new StringTokenizer JavaDoc(nvalue, " ");
1818            int countOfTokens = parsedList.countTokens() ;
1819            Object JavaDoc[] avalue = new Object JavaDoc[countOfTokens];
1820            boolean isUnion = fItemType.getVariety() == VARIETY_UNION;
1821            short[] itemTypes = new short[isUnion ? countOfTokens : 1];
1822            if (!isUnion)
1823                itemTypes[0] = fItemType.fBuiltInKind;
1824            XSSimpleTypeDecl[] memberTypes = new XSSimpleTypeDecl[countOfTokens];
1825            for(int i = 0 ; i < countOfTokens ; i ++){
1826                // we can't call fItemType.validate(), otherwise checkExtraRules()
1827
// will be called twice: once in fItemType.validate, once in
1828
// validate method of this type.
1829
// so we take two steps to get the actual value:
1830
// 1. fItemType.getActualValue()
1831
// 2. fItemType.chekcFacets()
1832
avalue[i] = fItemType.getActualValue(parsedList.nextToken(), context, validatedInfo, false);
1833                if (context.needFacetChecking() &&
1834                        (fItemType.fFacetsDefined != 0 && fItemType.fFacetsDefined != FACET_WHITESPACE)) {
1835                    fItemType.checkFacets(validatedInfo);
1836                }
1837                memberTypes[i] = (XSSimpleTypeDecl)validatedInfo.memberType;
1838                if (isUnion)
1839                    itemTypes[i] = memberTypes[i].fBuiltInKind;
1840            }
1841            
1842            ListDV.ListData v = new ListDV.ListData(avalue);
1843            validatedInfo.actualValue = v;
1844            validatedInfo.actualValueType = isUnion ? XSConstants.LISTOFUNION_DT : XSConstants.LIST_DT;
1845            validatedInfo.memberType = null;
1846            validatedInfo.memberTypes = memberTypes;
1847            validatedInfo.itemValueTypes = new ShortListImpl(itemTypes, itemTypes.length);
1848            validatedInfo.normalizedValue = nvalue;
1849            
1850            return v;
1851            
1852        } else { // (fVariety == VARIETY_UNION)
1853
for(int i = 0 ; i < fMemberTypes.length; i++) {
1854                try {
1855                    // we can't call fMemberType[i].validate(), otherwise checkExtraRules()
1856
// will be called twice: once in fMemberType[i].validate, once in
1857
// validate method of this type.
1858
// so we take two steps to get the actual value:
1859
// 1. fMemberType[i].getActualValue()
1860
// 2. fMemberType[i].chekcFacets()
1861
Object JavaDoc aValue = fMemberTypes[i].getActualValue(content, context, validatedInfo, true);
1862                    if (context.needFacetChecking() &&
1863                            (fMemberTypes[i].fFacetsDefined != 0 && fMemberTypes[i].fFacetsDefined != FACET_WHITESPACE)) {
1864                        fMemberTypes[i].checkFacets(validatedInfo);
1865                    }
1866                    validatedInfo.memberType = fMemberTypes[i];
1867                    return aValue;
1868                } catch(InvalidDatatypeValueException invalidValue) {
1869                }
1870            }
1871            StringBuffer JavaDoc typesBuffer = new StringBuffer JavaDoc();
1872            XSSimpleTypeDecl decl;
1873            for(int i = 0;i < fMemberTypes.length; i++) {
1874                if(i != 0)
1875                    typesBuffer.append(" | ");
1876                decl = fMemberTypes[i];
1877                if(decl.fTargetNamespace != null) {
1878                    typesBuffer.append('{');
1879                    typesBuffer.append(decl.fTargetNamespace);
1880                    typesBuffer.append('}');
1881                }
1882                typesBuffer.append(decl.fTypeName);
1883                if(decl.fEnumeration != null) {
1884                    Vector JavaDoc v = decl.fEnumeration;
1885                    typesBuffer.append(" : [");
1886                    for(int j = 0;j < v.size(); j++) {
1887                        if(j != 0)
1888                            typesBuffer.append(',');
1889                        typesBuffer.append(v.elementAt(j));
1890                    }
1891                    typesBuffer.append(']');
1892                }
1893            }
1894            throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3",
1895                    new Object JavaDoc[]{content, fTypeName, typesBuffer.toString()});
1896        }
1897        
1898    }//getActualValue()
1899

1900    public boolean isEqual(Object JavaDoc value1, Object JavaDoc value2) {
1901        if (value1 == null) {
1902            return false;
1903        }
1904        return value1.equals(value2);
1905    }//isEqual()
1906

1907    // determine whether the two values are identical
1908
public boolean isIdentical (Object JavaDoc value1, Object JavaDoc value2) {
1909        if (value1 == null) {
1910            return false;
1911        }
1912        return fDVs[fValidationDV].isIdentical(value1, value2);
1913    }//isIdentical()
1914

1915    // normalize the string according to the whiteSpace facet
1916
public static String JavaDoc normalize(String JavaDoc content, short ws) {
1917        int len = content == null ? 0 : content.length();
1918        if (len == 0 || ws == WS_PRESERVE)
1919            return content;
1920        
1921        StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1922        if (ws == WS_REPLACE) {
1923            char ch;
1924            // when it's replace, just replace #x9, #xa, #xd by #x20
1925
for (int i = 0; i < len; i++) {
1926                ch = content.charAt(i);
1927                if (ch != 0x9 && ch != 0xa && ch != 0xd)
1928                    sb.append(ch);
1929                else
1930                    sb.append((char)0x20);
1931            }
1932        } else {
1933            char ch;
1934            int i;
1935            boolean isLeading = true;
1936            // when it's collapse
1937
for (i = 0; i < len; i++) {
1938                ch = content.charAt(i);
1939                // append real characters, so we passed leading ws
1940
if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) {
1941                    sb.append(ch);
1942                    isLeading = false;
1943                }
1944                else {
1945                    // for whitespaces, we skip all following ws
1946
for (; i < len-1; i++) {
1947                        ch = content.charAt(i+1);
1948                        if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20)
1949                            break;
1950                    }
1951                    // if it's not a leading or tailing ws, then append a space
1952
if (i < len - 1 && !isLeading)
1953                        sb.append((char)0x20);
1954                }
1955            }
1956        }
1957        
1958        return sb.toString();
1959    }
1960    
1961    // normalize the string according to the whiteSpace facet
1962
protected String JavaDoc normalize(Object JavaDoc content, short ws) {
1963        if (content == null)
1964            return null;
1965        
1966        // If pattern is not defined, we can skip some of the normalization.
1967
// Otherwise we have to normalize the data for correct result of
1968
// pattern validation.
1969
if ( (fFacetsDefined & FACET_PATTERN ) == 0 ) {
1970            short norm_type = fDVNormalizeType[fValidationDV];
1971            if (norm_type == NORMALIZE_NONE) {
1972                return content.toString();
1973            }
1974            else if (norm_type == NORMALIZE_TRIM) {
1975                return content.toString().trim();
1976            }
1977        }
1978        
1979        if (!(content instanceof StringBuffer JavaDoc)) {
1980            String JavaDoc strContent = content.toString();
1981            return normalize(strContent, ws);
1982        }
1983        
1984        StringBuffer JavaDoc sb = (StringBuffer JavaDoc)content;
1985        int len = sb.length();
1986        if (len == 0)
1987            return "";
1988        if (ws == WS_PRESERVE)
1989            return sb.toString();
1990        
1991        if (ws == WS_REPLACE) {
1992            char ch;
1993            // when it's replace, just replace #x9, #xa, #xd by #x20
1994
for (int i = 0; i < len; i++) {
1995                ch = sb.charAt(i);
1996                if (ch == 0x9 || ch == 0xa || ch == 0xd)
1997                    sb.setCharAt(i, (char)0x20);
1998            }
1999        } else {
2000            char ch;
2001            int i, j = 0;
2002            boolean isLeading = true;
2003            // when it's collapse
2004
for (i = 0; i < len; i++) {
2005                ch = sb.charAt(i);
2006                // append real characters, so we passed leading ws
2007
if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) {
2008                    sb.setCharAt(j++, ch);
2009                    isLeading = false;
2010                }
2011                else {
2012                    // for whitespaces, we skip all following ws
2013
for (; i < len-1; i++) {
2014                        ch = sb.charAt(i+1);
2015                        if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20)
2016                            break;
2017                    }
2018                    // if it's not a leading or tailing ws, then append a space
2019
if (i < len - 1 && !isLeading)
2020                        sb.setCharAt(j++, (char)0x20);
2021                }
2022            }
2023            sb.setLength(j);
2024        }
2025        
2026        return sb.toString();
2027    }
2028    
2029    void reportError(String JavaDoc key, Object JavaDoc[] args) throws InvalidDatatypeFacetException {
2030        throw new InvalidDatatypeFacetException(key, args);
2031    }
2032    
2033    
2034    private String JavaDoc whiteSpaceValue(short ws){
2035        return WS_FACET_STRING[ws];
2036    }
2037    
2038    /**
2039     * Fundamental Facet: ordered.
2040     */

2041    public short getOrdered() {
2042        return fOrdered;
2043    }
2044    
2045    /**
2046     * Fundamental Facet: bounded.
2047     */

2048    public boolean getBounded(){
2049        return fBounded;
2050    }
2051    
2052    /**
2053     * Fundamental Facet: cardinality.
2054     */

2055    public boolean getFinite(){
2056        return fFinite;
2057    }
2058    
2059    /**
2060     * Fundamental Facet: numeric.
2061     */

2062    public boolean getNumeric(){
2063        return fNumeric;
2064    }
2065    
2066    /**
2067     * Convenience method. [Facets]: check whether a facet is defined on this
2068     * type.
2069     * @param facetName The name of the facet.
2070     * @return True if the facet is defined, false otherwise.
2071     */

2072    public boolean isDefinedFacet(short facetName) {
2073        if ((fFacetsDefined & facetName) != 0)
2074            return true;
2075        if (fPatternType != SPECIAL_PATTERN_NONE)
2076            return facetName == FACET_PATTERN;
2077        if (fValidationDV == DV_INTEGER)
2078            return facetName == FACET_PATTERN || facetName == FACET_FRACTIONDIGITS;
2079        return false;
2080    }
2081    
2082    /**
2083     * [facets]: all facets defined on this type. The value is a bit
2084     * combination of FACET_XXX constants of all defined facets.
2085     */

2086    public short getDefinedFacets() {
2087        if (fPatternType != SPECIAL_PATTERN_NONE)
2088            return (short)(fFacetsDefined | FACET_PATTERN);
2089        if (fValidationDV == DV_INTEGER)
2090            return (short)(fFacetsDefined | FACET_PATTERN | FACET_FRACTIONDIGITS);
2091        return fFacetsDefined;
2092    }
2093    
2094    /**
2095     * Convenience method. [Facets]: check whether a facet is defined and
2096     * fixed on this type.
2097     * @param facetName The name of the facet.
2098     * @return True if the facet is fixed, false otherwise.
2099     */

2100    public boolean isFixedFacet(short facetName) {
2101        if ((fFixedFacet & facetName) != 0)
2102            return true;
2103        if (fValidationDV == DV_INTEGER)
2104            return facetName == FACET_FRACTIONDIGITS;
2105        return false;
2106    }
2107    
2108    /**
2109     * [facets]: all defined facets for this type which are fixed.
2110     */

2111    public short getFixedFacets() {
2112        if (fValidationDV == DV_INTEGER)
2113            return (short)(fFixedFacet | FACET_FRACTIONDIGITS);
2114        return fFixedFacet;
2115    }
2116    
2117    /**
2118     * Convenience method. Returns a value of a single constraining facet for
2119     * this simple type definition. This method must not be used to retrieve
2120     * values for <code>enumeration</code> and <code>pattern</code> facets.
2121     * @param facetName The name of the facet, i.e.
2122     * <code>FACET_LENGTH, FACET_TOTALDIGITS </code> (see
2123     * <code>XSConstants</code>). To retrieve the value for a pattern or
2124     * an enumeration, see <code>enumeration</code> and
2125     * <code>pattern</code>.
2126     * @return A value of the facet specified in <code>facetName</code> for
2127     * this simple type definition or <code>null</code>.
2128     */

2129    public String JavaDoc getLexicalFacetValue(short facetName) {
2130        switch (facetName) {
2131        case FACET_LENGTH:
2132            return (fLength == -1)?null:Integer.toString(fLength);
2133        case FACET_MINLENGTH:
2134            return (fMinLength == -1)?null:Integer.toString(fMinLength);
2135        case FACET_MAXLENGTH:
2136            return (fMaxLength == -1)?null:Integer.toString(fMaxLength);
2137        case FACET_WHITESPACE:
2138            return WS_FACET_STRING[fWhiteSpace];
2139        case FACET_MAXINCLUSIVE:
2140            return (fMaxInclusive == null)?null:fMaxInclusive.toString();
2141        case FACET_MAXEXCLUSIVE:
2142            return (fMaxExclusive == null)?null:fMaxExclusive.toString();
2143        case FACET_MINEXCLUSIVE:
2144            return (fMinExclusive == null)?null:fMinExclusive.toString();
2145        case FACET_MININCLUSIVE:
2146            return (fMinInclusive == null)?null:fMinInclusive.toString();
2147        case FACET_TOTALDIGITS:
2148            if (fValidationDV == DV_INTEGER)
2149                return "0";
2150            return (fTotalDigits == -1)?null:Integer.toString(fTotalDigits);
2151        case FACET_FRACTIONDIGITS:
2152            return (fFractionDigits == -1)?null:Integer.toString(fFractionDigits);
2153        }
2154        return null;
2155    }
2156    
2157    /**
2158     * A list of enumeration values if it exists, otherwise an empty
2159     * <code>StringList</code>.
2160     */

2161    public StringList getLexicalEnumeration() {
2162        if (fLexicalEnumeration == null){
2163            if (fEnumeration == null)
2164                return StringListImpl.EMPTY_LIST;
2165            int size = fEnumeration.size();
2166            String JavaDoc[] strs = new String JavaDoc[size];
2167            for (int i = 0; i < size; i++)
2168                strs[i] = fEnumeration.elementAt(i).toString();
2169            fLexicalEnumeration = new StringListImpl(strs, size);
2170        }
2171        return fLexicalEnumeration;
2172    }
2173    
2174    /**
2175     * A list of actual enumeration values if it exists, otherwise an empty
2176     * <code>ObjectList</code>.
2177     */

2178    public ObjectList getActualEnumeration() {
2179        if (fActualEnumeration == null) {
2180            fActualEnumeration = new ObjectList () {
2181                public int getLength() {
2182                    return (fEnumeration != null) ? fEnumeration.size() : 0;
2183                }
2184                public boolean contains(Object JavaDoc item) {
2185                    return (fEnumeration != null && fEnumeration.contains(item));
2186                }
2187                public Object JavaDoc item(int index) {
2188                    if (index < 0 || index >= getLength()) {
2189                        return null;
2190                    }
2191                    return fEnumeration.elementAt(index);
2192                }
2193            };
2194        }
2195        return fActualEnumeration;
2196    }
2197    
2198    /**
2199     * A list of enumeration type values (as a list of ShortList objects) if it exists, otherwise returns
2200     * null
2201     */

2202    public ObjectList getEnumerationItemTypeList() {
2203        if (fEnumerationItemTypeList == null) {
2204            if(fEnumerationItemType == null)
2205                return null;
2206            fEnumerationItemTypeList = new ObjectList () {
2207                public int getLength() {
2208                    return (fEnumerationItemType != null) ? fEnumerationItemType.length : 0;
2209                }
2210                public boolean contains(Object JavaDoc item) {
2211                   if(fEnumerationItemType == null || !(item instanceof ShortList))
2212                       return false;
2213                   for(int i = 0;i < fEnumerationItemType.length; i++)
2214                       if(fEnumerationItemType[i] == item)
2215                           return true;
2216                   return false;
2217                }
2218                public Object JavaDoc item(int index) {
2219                    if (index < 0 || index >= getLength()) {
2220                        return null;
2221                    }
2222                    return fEnumerationItemType[index];
2223                }
2224            };
2225        }
2226        return fEnumerationItemTypeList;
2227    }
2228    
2229    public ShortList getEnumerationTypeList() {
2230        if (fEnumerationTypeList == null) {
2231            if (fEnumerationType == null)
2232                return null;
2233            fEnumerationTypeList = new ShortListImpl (fEnumerationType, fEnumerationType.length);
2234        }
2235        return fEnumerationTypeList;
2236    }
2237    
2238    /**
2239     * A list of pattern values if it exists, otherwise an empty
2240     * <code>StringList</code>.
2241     */

2242    public StringList getLexicalPattern() {
2243        if (fPatternType == SPECIAL_PATTERN_NONE && fValidationDV != DV_INTEGER && fPatternStr == null)
2244            return StringListImpl.EMPTY_LIST;
2245        if (fLexicalPattern == null){
2246            int size = fPatternStr == null ? 0 : fPatternStr.size();
2247            String JavaDoc[] strs;
2248            if (fPatternType == SPECIAL_PATTERN_NMTOKEN) {
2249                strs = new String JavaDoc[size+1];
2250                strs[size] = "\\c+";
2251            }
2252            else if (fPatternType == SPECIAL_PATTERN_NAME) {
2253                strs = new String JavaDoc[size+1];
2254                strs[size] = "\\i\\c*";
2255            }
2256            else if (fPatternType == SPECIAL_PATTERN_NCNAME) {
2257                strs = new String JavaDoc[size+2];
2258                strs[size] = "\\i\\c*";
2259                strs[size+1] = "[\\i-[:]][\\c-[:]]*";
2260            }
2261            else if (fValidationDV == DV_INTEGER) {
2262                strs = new String JavaDoc[size+1];
2263                strs[size] = "[\\-+]?[0-9]+";
2264            }
2265            else {
2266                strs = new String JavaDoc[size];
2267            }
2268            for (int i = 0; i < size; i++)
2269                strs[i] = (String JavaDoc)fPatternStr.elementAt(i);
2270            fLexicalPattern = new StringListImpl(strs, strs.length);
2271        }
2272        return fLexicalPattern;
2273    }
2274    
2275    /**
2276     * [annotations]: a set of annotations for this simple type component if
2277     * it exists, otherwise an empty <code>XSObjectList</code>.
2278     */

2279    public XSObjectList getAnnotations() {
2280        return (fAnnotations != null) ? fAnnotations : XSObjectListImpl.EMPTY_LIST;
2281    }
2282    
2283    private void caclFundamentalFacets() {
2284        setOrdered();
2285        setNumeric();
2286        setBounded();
2287        setCardinality();
2288    }
2289    
2290    private void setOrdered(){
2291        
2292        // When {variety} is atomic, {value} is inherited from {value} of {base type definition}. For all "primitive" types {value} is as specified in the table in Fundamental Facets (C.1).
2293
if(fVariety == VARIETY_ATOMIC){
2294            this.fOrdered = fBase.fOrdered;
2295        }
2296        
2297        // When {variety} is list, {value} is false.
2298
else if(fVariety == VARIETY_LIST){
2299            this.fOrdered = ORDERED_FALSE;
2300        }
2301        
2302        // When {variety} is union, the {value} is partial unless one of the following:
2303
// 1. If every member of {member type definitions} is derived from a common ancestor other than the simple ur-type, then {value} is the same as that ancestor's ordered facet.
2304
// 2. If every member of {member type definitions} has a {value} of false for the ordered facet, then {value} is false.
2305
else if(fVariety == VARIETY_UNION){
2306            int length = fMemberTypes.length;
2307            // REVISIT: is the length possible to be 0?
2308
if (length == 0) {
2309                this.fOrdered = ORDERED_PARTIAL;
2310                return;
2311            }
2312            // we need to process the first member type before entering the loop
2313
short ancestorId = getPrimitiveDV(fMemberTypes[0].fValidationDV);
2314            boolean commonAnc = ancestorId != DV_ANYSIMPLETYPE;
2315            boolean allFalse = fMemberTypes[0].fOrdered == ORDERED_FALSE;
2316            // for the other member types, check whether the value is false
2317
// and whether they have the same ancestor as the first one
2318
for (int i = 1; i < fMemberTypes.length && (commonAnc || allFalse); i++) {
2319                if (commonAnc)
2320                    commonAnc = ancestorId == getPrimitiveDV(fMemberTypes[i].fValidationDV);
2321                if (allFalse)
2322                    allFalse = fMemberTypes[i].fOrdered == ORDERED_FALSE;
2323            }
2324            if (commonAnc) {
2325                // REVISIT: all member types should have the same ordered value
2326
// just use the first one. Can we assume this?
2327
this.fOrdered = fMemberTypes[0].fOrdered;
2328            } else if (allFalse) {
2329                this.fOrdered = ORDERED_FALSE;
2330            } else {
2331                this.fOrdered = ORDERED_PARTIAL;
2332            }
2333        }
2334        
2335    }//setOrdered
2336

2337    private void setNumeric(){
2338        if(fVariety == VARIETY_ATOMIC){
2339            this.fNumeric = fBase.fNumeric;
2340        }
2341        else if(fVariety == VARIETY_LIST){
2342            this.fNumeric = false;
2343        }
2344        else if(fVariety == VARIETY_UNION){
2345            XSSimpleType[] memberTypes = fMemberTypes;
2346            for(int i = 0 ; i < memberTypes.length ; i++){
2347                if(!memberTypes[i].getNumeric() ){
2348                    this.fNumeric = false;
2349                    return;
2350                }
2351            }
2352            this.fNumeric = true;
2353        }
2354        
2355    }//setNumeric
2356

2357    private void setBounded(){
2358        if(fVariety == VARIETY_ATOMIC){
2359            if( (((this.fFacetsDefined & FACET_MININCLUSIVE) != 0) || ((this.fFacetsDefined & FACET_MINEXCLUSIVE) != 0))
2360                    && (((this.fFacetsDefined & FACET_MAXINCLUSIVE) != 0) || ((this.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) ){
2361                this.fBounded = true;
2362            }
2363            else{
2364                this.fBounded = false;
2365            }
2366        }
2367        else if(fVariety == VARIETY_LIST){
2368            if( ((this.fFacetsDefined & FACET_LENGTH) != 0 ) || ( ((this.fFacetsDefined & FACET_MINLENGTH) != 0 )
2369                    && ((this.fFacetsDefined & FACET_MAXLENGTH) != 0 )) ){
2370                this.fBounded = true;
2371            }
2372            else{
2373                this.fBounded = false;
2374            }
2375            
2376        }
2377        else if(fVariety == VARIETY_UNION){
2378            
2379            XSSimpleTypeDecl [] memberTypes = this.fMemberTypes;
2380            short ancestorId = 0 ;
2381            
2382            if(memberTypes.length > 0){
2383                ancestorId = getPrimitiveDV(memberTypes[0].fValidationDV);
2384            }
2385            
2386            for(int i = 0 ; i < memberTypes.length ; i++){
2387                if(!memberTypes[i].getBounded() || (ancestorId != getPrimitiveDV(memberTypes[i].fValidationDV)) ){
2388                    this.fBounded = false;
2389                    return;
2390                }
2391            }
2392            this.fBounded = true;
2393        }
2394        
2395    }//setBounded
2396

2397    private boolean specialCardinalityCheck(){
2398        if( (fBase.fValidationDV == XSSimpleTypeDecl.DV_DATE) || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GYEARMONTH)
2399                || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GYEAR) || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GMONTHDAY)
2400                || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GDAY) || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GMONTH) ){
2401            return true;
2402        }
2403        return false;
2404        
2405    } //specialCardinalityCheck()
2406

2407    private void setCardinality(){
2408        if(fVariety == VARIETY_ATOMIC){
2409            if(fBase.fFinite){
2410                this.fFinite = true;
2411            }
2412            else {// (!fBase.fFinite)
2413
if ( ((this.fFacetsDefined & FACET_LENGTH) != 0 ) || ((this.fFacetsDefined & FACET_MAXLENGTH) != 0 )
2414                        || ((this.fFacetsDefined & FACET_TOTALDIGITS) != 0 ) ){
2415                    this.fFinite = true;
2416                }
2417                else if( (((this.fFacetsDefined & FACET_MININCLUSIVE) != 0 ) || ((this.fFacetsDefined & FACET_MINEXCLUSIVE) != 0 ))
2418                        && (((this.fFacetsDefined & FACET_MAXINCLUSIVE) != 0 ) || ((this.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0 )) ){
2419                    if( ((this.fFacetsDefined & FACET_FRACTIONDIGITS) != 0 ) || specialCardinalityCheck()){
2420                        this.fFinite = true;
2421                    }
2422                    else{
2423                        this.fFinite = false;
2424                    }
2425                }
2426                else{
2427                    this.fFinite = false;
2428                }
2429            }
2430        }
2431        else if(fVariety == VARIETY_LIST){
2432            if( ((this.fFacetsDefined & FACET_LENGTH) != 0 ) || ( ((this.fFacetsDefined & FACET_MINLENGTH) != 0 )
2433                    && ((this.fFacetsDefined & FACET_MAXLENGTH) != 0 )) ){
2434                this.fFinite = true;
2435            }
2436            else{
2437                this.fFinite = false;
2438            }
2439            
2440        }
2441        else if(fVariety == VARIETY_UNION){
2442            XSSimpleType [] memberTypes = fMemberTypes;
2443            for(int i = 0 ; i < memberTypes.length ; i++){
2444                if(!(memberTypes[i].getFinite()) ){
2445                    this.fFinite = false;
2446                    return;
2447                }
2448            }
2449            this.fFinite = true;
2450        }
2451        
2452    }//setCardinality
2453

2454    private short getPrimitiveDV(short validationDV){
2455        
2456        if (validationDV == DV_ID || validationDV == DV_IDREF || validationDV == DV_ENTITY){
2457            return DV_STRING;
2458        }
2459        else if (validationDV == DV_INTEGER) {
2460            return DV_DECIMAL;
2461        }
2462        else if (Constants.SCHEMA_1_1_SUPPORT && (validationDV == DV_YEARMONTHDURATION || validationDV == DV_DAYTIMEDURATION)) {
2463            return DV_DURATION;
2464        }
2465        else {
2466            return validationDV;
2467        }
2468        
2469    }//getPrimitiveDV()
2470

2471    public boolean derivedFromType(XSTypeDefinition ancestor, short derivation) {
2472        // REVISIT: implement according to derivation
2473

2474        // ancestor is null, retur false
2475
if (ancestor == null)
2476            return false;
2477        // ancestor is anyType, return true
2478
// anyType is the only type whose base type is itself
2479
if (ancestor.getBaseType() == ancestor)
2480            return true;
2481        // recursively get base, and compare it with ancestor
2482
XSTypeDefinition type = this;
2483        while (type != ancestor && // compare with ancestor
2484
type != fAnySimpleType) { // reached anySimpleType
2485
type = type.getBaseType();
2486        }
2487        
2488        return type == ancestor;
2489    }
2490    
2491    public boolean derivedFrom(String JavaDoc ancestorNS, String JavaDoc ancestorName, short derivation) {
2492        // REVISIT: implement according to derivation
2493

2494        // ancestor is null, retur false
2495
if (ancestorName == null)
2496            return false;
2497        // ancestor is anyType, return true
2498
if (URI_SCHEMAFORSCHEMA.equals(ancestorNS) &&
2499                ANY_TYPE.equals(ancestorName)) {
2500            return true;
2501        }
2502        
2503        // recursively get base, and compare it with ancestor
2504
XSTypeDefinition type = this;
2505        while (!(ancestorName.equals(type.getName()) &&
2506                ((ancestorNS == null && type.getNamespace() == null) ||
2507                        (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) && // compare with ancestor
2508
type != fAnySimpleType) { // reached anySimpleType
2509
type = (XSTypeDefinition)type.getBaseType();
2510        }
2511        
2512        return type != fAnySimpleType;
2513    }
2514    
2515    /**
2516     * Checks if a type is derived from another by restriction, given the name
2517     * and namespace. See:
2518     * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
2519     *
2520     * @param ancestorNS
2521     * The namspace of the ancestor type declaration
2522     * @param ancestorName
2523     * The name of the ancestor type declaration
2524     * @param derivationMethod
2525     * The derivation method
2526     *
2527     * @return boolean True if the ancestor type is derived from the reference type by the specifiied derivation method.
2528     */

2529    public boolean isDOMDerivedFrom(String JavaDoc ancestorNS, String JavaDoc ancestorName, int derivationMethod) {
2530        
2531        // ancestor is null, return false
2532
if (ancestorName == null)
2533            return false;
2534        
2535        // ancestor is anyType, return true
2536
if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(ancestorNS)
2537                && SchemaSymbols.ATTVAL_ANYTYPE.equals(ancestorName)
2538                && (((derivationMethod & DERIVATION_RESTRICTION) != 0)
2539                        || (derivationMethod == DERIVATION_ANY))) {
2540            return true;
2541        }
2542        
2543        // restriction
2544
if ((derivationMethod & DERIVATION_RESTRICTION) != 0) {
2545            if (isDerivedByRestriction(ancestorNS, ancestorName, this)) {
2546                return true;
2547            }
2548        }
2549        
2550        // list
2551
if ((derivationMethod & DERIVATION_LIST) != 0) {
2552            if (isDerivedByList(ancestorNS, ancestorName, this)) {
2553                return true;
2554            }
2555        }
2556        
2557        // union
2558
if ((derivationMethod & DERIVATION_UNION) != 0) {
2559            if (isDerivedByUnion(ancestorNS, ancestorName, this)) {
2560                return true;
2561            }
2562        }
2563        
2564        // extension
2565
if (((derivationMethod & DERIVATION_EXTENSION) != 0)
2566                && (((derivationMethod & DERIVATION_RESTRICTION) == 0)
2567                        && ((derivationMethod & DERIVATION_LIST) == 0)
2568                        && ((derivationMethod & DERIVATION_UNION) == 0))) {
2569            return false;
2570        }
2571        
2572        // If the value of the parameter is 0 i.e. no bit (corresponding to
2573
// restriction, list, extension or union) is set to 1 for the
2574
// derivationMethod parameter.
2575
if (((derivationMethod & DERIVATION_EXTENSION) == 0)
2576                && (((derivationMethod & DERIVATION_RESTRICTION) == 0)
2577                        && ((derivationMethod & DERIVATION_LIST) == 0)
2578                        && ((derivationMethod & DERIVATION_UNION) == 0))) {
2579            return isDerivedByAny(ancestorNS, ancestorName, this);
2580        }
2581        
2582        return false;
2583    }
2584    
2585    
2586    /**
2587     * Checks if a type is derived from another by any combination of restriction, list ir union. See:
2588     * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
2589     *
2590     * @param ancestorNS
2591     * The namspace of the ancestor type declaration
2592     * @param ancestorName
2593     * The name of the ancestor type declaration
2594     * @param type
2595     * The reference type definition
2596     *
2597     * @return boolean True if the type is derived by restriciton for the reference type
2598     */

2599    private boolean isDerivedByAny(String JavaDoc ancestorNS, String JavaDoc ancestorName,
2600            XSTypeDefinition type) {
2601        
2602        boolean derivedFrom = false;
2603        XSTypeDefinition oldType = null;
2604        // for each base, item or member type
2605
while (type != null && type != oldType) {
2606            
2607            // If the ancestor type is reached or is the same as this type.
2608
if ((ancestorName.equals(type.getName()))
2609                    && ((ancestorNS == null && type.getNamespace() == null)
2610                            || (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) {
2611                derivedFrom = true;
2612                break;
2613            }
2614            
2615            // check if derived by restriction or list or union
2616
if (isDerivedByRestriction(ancestorNS, ancestorName, type)) {
2617                return true;
2618            } else if (isDerivedByList(ancestorNS, ancestorName, type)) {
2619                return true;
2620            } else if (isDerivedByUnion(ancestorNS, ancestorName, type)) {
2621                return true;
2622            }
2623            oldType = type;
2624            // get the base, item or member type depending on the variety
2625
if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_ABSENT
2626                    || ((XSSimpleTypeDecl) type).getVariety() == VARIETY_ATOMIC) {
2627                type = type.getBaseType();
2628            } else if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_UNION) {
2629                for (int i = 0; i < ((XSSimpleTypeDecl) type).getMemberTypes().getLength(); i++) {
2630                    return isDerivedByAny(ancestorNS, ancestorName,
2631                            (XSTypeDefinition) ((XSSimpleTypeDecl) type)
2632                            .getMemberTypes().item(i));
2633                }
2634            } else if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_LIST) {
2635                type = ((XSSimpleTypeDecl) type).getItemType();
2636            }
2637        }
2638        
2639        return derivedFrom;
2640    }
2641    
2642    /**
2643     * DOM Level 3
2644     * Checks if a type is derived from another by restriction. See:
2645     * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
2646     *
2647     * @param ancestorNS
2648     * The namspace of the ancestor type declaration
2649     * @param ancestorName
2650     * The name of the ancestor type declaration
2651     * @param type
2652     * The reference type definition
2653     *
2654     * @return boolean True if the type is derived by restriciton for the
2655     * reference type
2656     */

2657    private boolean isDerivedByRestriction (String JavaDoc ancestorNS, String JavaDoc ancestorName, XSTypeDefinition type) {
2658        XSTypeDefinition oldType = null;
2659        while (type != null && type != oldType) {
2660            if ((ancestorName.equals(type.getName()))
2661                    && ((ancestorNS != null && ancestorNS.equals(type.getNamespace()))
2662                            || (type.getNamespace() == null && ancestorNS == null))) {
2663                
2664                return true;
2665            }
2666            oldType = type;
2667            type = type.getBaseType();
2668        }
2669        
2670        return false;
2671    }
2672    
2673    /**
2674     * Checks if a type is derived from another by list. See:
2675     * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
2676     *
2677     * @param ancestorNS
2678     * The namspace of the ancestor type declaration
2679     * @param ancestorName
2680     * The name of the ancestor type declaration
2681     * @param type
2682     * The reference type definition
2683     *
2684     * @return boolean True if the type is derived by list for the reference type
2685     */

2686    private boolean isDerivedByList (String JavaDoc ancestorNS, String JavaDoc ancestorName, XSTypeDefinition type) {
2687        // If the variety is union
2688
if (type !=null && ((XSSimpleTypeDefinition)type).getVariety() == VARIETY_LIST) {
2689            
2690            // get the {item type}
2691
XSTypeDefinition itemType = ((XSSimpleTypeDefinition)type).getItemType();
2692            
2693            // T2 is the {item type definition}
2694
if (itemType != null) {
2695                
2696                // T2 is derived from the other type definition by DERIVATION_RESTRICTION
2697
if (isDerivedByRestriction(ancestorNS, ancestorName, itemType)) {
2698                    return true;
2699                }
2700            }
2701        }
2702        return false;
2703    }
2704    
2705    /**
2706     * Checks if a type is derived from another by union. See:
2707     * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
2708     *
2709     * @param ancestorNS
2710     * The namspace of the ancestor type declaration
2711     * @param ancestorName
2712     * The name of the ancestor type declaration
2713     * @param type
2714     * The reference type definition
2715     *
2716     * @return boolean True if the type is derived by union for the reference type
2717     */

2718    private boolean isDerivedByUnion (String JavaDoc ancestorNS, String JavaDoc ancestorName, XSTypeDefinition type) {
2719        
2720        // If the variety is union
2721
if (type !=null && ((XSSimpleTypeDefinition)type).getVariety() == VARIETY_UNION) {
2722            
2723            // get member types
2724
XSObjectList memberTypes = ((XSSimpleTypeDefinition)type).getMemberTypes();
2725            
2726            for (int i = 0; i < memberTypes.getLength(); i++) {
2727                // One of the {member type definitions} is T2.
2728
if (memberTypes.item(i) != null) {
2729                    // T2 is derived from the other type definition by DERIVATION_RESTRICTION
2730
if (isDerivedByRestriction(ancestorNS, ancestorName,(XSSimpleTypeDefinition)memberTypes.item(i))) {
2731                        return true;
2732                    }
2733                }
2734            }
2735        }
2736        return false;
2737    }
2738    
2739    
2740    static final XSSimpleTypeDecl fAnySimpleType = new XSSimpleTypeDecl(null, "anySimpleType", DV_ANYSIMPLETYPE, ORDERED_FALSE, false, true, false, true, XSConstants.ANYSIMPLETYPE_DT);
2741    
2742    static final XSSimpleTypeDecl fAnyAtomicType = new XSSimpleTypeDecl(fAnySimpleType, "anyAtomicType", DV_ANYATOMICTYPE, ORDERED_FALSE, false, true, false, true, XSSimpleTypeDecl.ANYATOMICTYPE_DT);
2743    
2744    /**
2745     * Validation context used to validate facet values.
2746     */

2747    static final ValidationContext fDummyContext = new ValidationContext() {
2748        public boolean needFacetChecking() {
2749            return true;
2750        }
2751        
2752        public boolean needExtraChecking() {
2753            return false;
2754        }
2755        public boolean needToNormalize() {
2756            return false;
2757        }
2758        public boolean useNamespaces() {
2759            return true;
2760        }
2761        
2762        public boolean isEntityDeclared(String JavaDoc name) {
2763            return false;
2764        }
2765        
2766        public boolean isEntityUnparsed(String JavaDoc name) {
2767            return false;
2768        }
2769        
2770        public boolean isIdDeclared(String JavaDoc name) {
2771            return false;
2772        }
2773        
2774        public void addId(String JavaDoc name) {
2775        }
2776        
2777        public void addIdRef(String JavaDoc name) {
2778        }
2779        
2780        public String JavaDoc getSymbol (String JavaDoc symbol) {
2781            return symbol.intern();
2782        }
2783        
2784        public String JavaDoc getURI(String JavaDoc prefix) {
2785            return null;
2786        }
2787    };
2788    
2789    private boolean fAnonymous = false;
2790    
2791    /**
2792     * A wrapper of ValidationContext, to provide a way of switching to a
2793     * different Namespace declaration context.
2794     */

2795    class ValidationContextImpl implements ValidationContext {
2796        ValidationContext fExternal;
2797        ValidationContextImpl(ValidationContext external) {
2798            fExternal = external;
2799        }
2800        
2801        NamespaceContext fNSContext;
2802        void setNSContext(NamespaceContext nsContext) {
2803            fNSContext = nsContext;
2804        }
2805        
2806        public boolean needFacetChecking() {
2807            return fExternal.needFacetChecking();
2808        }
2809        
2810        public boolean needExtraChecking() {
2811            return fExternal.needExtraChecking();
2812        }
2813        public boolean needToNormalize() {
2814            return fExternal.needToNormalize();
2815        }
2816        // schema validation is predicated upon namespaces
2817
public boolean useNamespaces() {
2818            return true;
2819        }
2820        
2821        public boolean isEntityDeclared (String JavaDoc name) {
2822            return fExternal.isEntityDeclared(name);
2823        }
2824        
2825        public boolean isEntityUnparsed (String JavaDoc name) {
2826            return fExternal.isEntityUnparsed(name);
2827        }
2828        
2829        public boolean isIdDeclared (String JavaDoc name) {
2830            return fExternal.isIdDeclared(name);
2831        }
2832        
2833        public void addId(String JavaDoc name) {
2834            fExternal.addId(name);
2835        }
2836        
2837        public void addIdRef(String JavaDoc name) {
2838            fExternal.addIdRef(name);
2839        }
2840        
2841        public String JavaDoc getSymbol (String JavaDoc symbol) {
2842            return fExternal.getSymbol(symbol);
2843        }
2844        
2845        public String JavaDoc getURI(String JavaDoc prefix) {
2846            if (fNSContext == null)
2847                return fExternal.getURI(prefix);
2848            else
2849                return fNSContext.getURI(prefix);
2850        }
2851    }
2852    
2853    public void reset(){
2854        
2855        // if it's immutable, can't be reset:
2856
if (fIsImmutable) return;
2857        fItemType = null;
2858        fMemberTypes = null;
2859        
2860        fTypeName = null;
2861        fTargetNamespace = null;
2862        fFinalSet = 0;
2863        fBase = null;
2864        fVariety = -1;
2865        fValidationDV = -1;
2866        
2867        fFacetsDefined = 0;
2868        fFixedFacet = 0;
2869        
2870        //for constraining facets
2871
fWhiteSpace = 0;
2872        fLength = -1;
2873        fMinLength = -1;
2874        fMaxLength = -1;
2875        fTotalDigits = -1;
2876        fFractionDigits = -1;
2877        fPattern = null;
2878        fPatternStr = null;
2879        fEnumeration = null;
2880        fEnumerationType = null;
2881        fEnumerationItemType = null;
2882        fLexicalPattern = null;
2883        fLexicalEnumeration = null;
2884        fMaxInclusive = null;
2885        fMaxExclusive = null;
2886        fMinExclusive = null;
2887        fMinInclusive = null;
2888        lengthAnnotation = null;
2889        minLengthAnnotation = null;
2890        maxLengthAnnotation = null;
2891        whiteSpaceAnnotation = null;
2892        totalDigitsAnnotation = null;
2893        fractionDigitsAnnotation = null;
2894        patternAnnotations = null;
2895        enumerationAnnotations = null;
2896        maxInclusiveAnnotation = null;
2897        maxExclusiveAnnotation = null;
2898        minInclusiveAnnotation = null;
2899        minExclusiveAnnotation = null;
2900        
2901        fPatternType = SPECIAL_PATTERN_NONE;
2902        fAnnotations = null;
2903        fFacets = null;
2904        
2905        // REVISIT: reset for fundamental facets
2906
}
2907    /**
2908     * @see org.apache.xerces.xs.XSObject#getNamespaceItem()
2909     */

2910    public XSNamespaceItem getNamespaceItem() {
2911        // REVISIT: implement
2912
return null;
2913    }
2914    
2915    /**
2916     * @see java.lang.Object#toString()
2917     */

2918    public String JavaDoc toString() {
2919        return this.fTargetNamespace+"," +this.fTypeName;
2920    }
2921    
2922    /**
2923     * A list of constraining facets if it exists, otherwise an empty
2924     * <code>XSObjectList</code>. Note: This method must not be used to
2925     * retrieve values for <code>enumeration</code> and <code>pattern</code>
2926     * facets.
2927     */

2928    public XSObjectList getFacets() {
2929        if (fFacets == null &&
2930                (fFacetsDefined != 0 || fValidationDV == DV_INTEGER)) {
2931            
2932            XSFacetImpl[] facets = new XSFacetImpl[10];
2933            int count = 0;
2934            if ((fFacetsDefined & FACET_WHITESPACE) != 0) {
2935                facets[count] =
2936                    new XSFacetImpl(
2937                            FACET_WHITESPACE,
2938                            WS_FACET_STRING[fWhiteSpace],
2939                            (fFixedFacet & FACET_WHITESPACE) != 0,
2940                            whiteSpaceAnnotation);
2941                count++;
2942            }
2943            if (fLength != -1) {
2944                facets[count] =
2945                    new XSFacetImpl(
2946                            FACET_LENGTH,
2947                            Integer.toString(fLength),
2948                            (fFixedFacet & FACET_LENGTH) != 0,
2949                            lengthAnnotation);
2950                count++;
2951            }
2952            if (fMinLength != -1) {
2953                facets[count] =
2954                    new XSFacetImpl(
2955                            FACET_MINLENGTH,
2956                            Integer.toString(fMinLength),
2957                            (fFixedFacet & FACET_MINLENGTH) != 0,
2958                            minLengthAnnotation);
2959                count++;
2960            }
2961            if (fMaxLength != -1) {
2962                facets[count] =
2963                    new XSFacetImpl(
2964                            FACET_MAXLENGTH,
2965                            Integer.toString(fMaxLength),
2966                            (fFixedFacet & FACET_MAXLENGTH) != 0,
2967                            maxLengthAnnotation);
2968                count++;
2969            }
2970            if (fTotalDigits != -1) {
2971                facets[count] =
2972                    new XSFacetImpl(
2973                            FACET_TOTALDIGITS,
2974                            Integer.toString(fTotalDigits),
2975                            (fFixedFacet & FACET_TOTALDIGITS) != 0,
2976                            totalDigitsAnnotation);
2977                count++;
2978            }
2979            if (fValidationDV == DV_INTEGER) {
2980                facets[count] =
2981                    new XSFacetImpl(
2982                            FACET_FRACTIONDIGITS,
2983                            "0",
2984                            true,
2985                            null);
2986                count++;
2987            }
2988            if (fFractionDigits != -1) {
2989                facets[count] =
2990                    new XSFacetImpl(
2991                            FACET_FRACTIONDIGITS,
2992                            Integer.toString(fFractionDigits),
2993                            (fFixedFacet & FACET_FRACTIONDIGITS) != 0,
2994                            fractionDigitsAnnotation);
2995                count++;
2996            }
2997            if (fMaxInclusive != null) {
2998                facets[count] =
2999                    new XSFacetImpl(
3000                            FACET_MAXINCLUSIVE,
3001                            fMaxInclusive.toString(),
3002                            (fFixedFacet & FACET_MAXINCLUSIVE) != 0,
3003                            maxInclusiveAnnotation);
3004                count++;
3005            }
3006            if (fMaxExclusive != null) {
3007                facets[count] =
3008                    new XSFacetImpl(
3009                            FACET_MAXEXCLUSIVE,
3010                            fMaxExclusive.toString(),
3011                            (fFixedFacet & FACET_MAXEXCLUSIVE) != 0,
3012                            maxExclusiveAnnotation);
3013                count++;
3014            }
3015            if (fMinExclusive != null) {
3016                facets[count] =
3017                    new XSFacetImpl(
3018                            FACET_MINEXCLUSIVE,
3019                            fMinExclusive.toString(),
3020                            (fFixedFacet & FACET_MINEXCLUSIVE) != 0,
3021                            minExclusiveAnnotation);
3022                count++;
3023            }
3024            if (fMinInclusive != null) {
3025                facets[count] =
3026                    new XSFacetImpl(
3027                            FACET_MININCLUSIVE,
3028                            fMinInclusive.toString(),
3029                            (fFixedFacet & FACET_MININCLUSIVE) != 0,
3030                            minInclusiveAnnotation);
3031                count++;
3032            }
3033            fFacets = new XSObjectListImpl(facets, count);
3034        }
3035        return (fFacets != null) ? fFacets : XSObjectListImpl.EMPTY_LIST;
3036    }
3037    
3038    /**
3039     * A list of enumeration and pattern constraining facets if it exists,
3040     * otherwise an empty <code>XSObjectList</code>.
3041     */

3042    public XSObjectList getMultiValueFacets() {
3043        if (fMultiValueFacets == null &&
3044                ((fFacetsDefined & FACET_ENUMERATION) != 0 ||
3045                        (fFacetsDefined & FACET_PATTERN) != 0 ||
3046                        fPatternType != SPECIAL_PATTERN_NONE ||
3047                        fValidationDV == DV_INTEGER)) {
3048            
3049            XSMVFacetImpl[] facets = new XSMVFacetImpl[2];
3050            int count = 0;
3051            if ((fFacetsDefined & FACET_PATTERN) != 0 ||
3052                    fPatternType != SPECIAL_PATTERN_NONE ||
3053                    fValidationDV == DV_INTEGER) {
3054                facets[count] =
3055                    new XSMVFacetImpl(
3056                            FACET_PATTERN,
3057                            this.getLexicalPattern(),
3058                            patternAnnotations);
3059                count++;
3060            }
3061            if (fEnumeration != null) {
3062                facets[count] =
3063                    new XSMVFacetImpl(
3064                            FACET_ENUMERATION,
3065                            this.getLexicalEnumeration(),
3066                            enumerationAnnotations);
3067                count++;
3068            }
3069            fMultiValueFacets = new XSObjectListImpl(facets, count);
3070        }
3071        return (fMultiValueFacets != null) ?
3072                fMultiValueFacets : XSObjectListImpl.EMPTY_LIST;
3073    }
3074    
3075    public Object JavaDoc getMinInclusiveValue() {
3076        return fMinInclusive;
3077    }
3078    
3079    public Object JavaDoc getMinExclusiveValue() {
3080        return fMinExclusive;
3081    }
3082    
3083    public Object JavaDoc getMaxInclusiveValue() {
3084        return fMaxInclusive;
3085    }
3086    
3087    public Object JavaDoc getMaxExclusiveValue() {
3088        return fMaxExclusive;
3089    }
3090    
3091    public void setAnonymous(boolean anon) {
3092        fAnonymous = anon;
3093    }
3094    
3095    private static final class XSFacetImpl implements XSFacet {
3096        final short kind;
3097        final String JavaDoc value;
3098        final boolean fixed;
3099        final XSAnnotation annotation;
3100        
3101        public XSFacetImpl(short kind, String JavaDoc value, boolean fixed, XSAnnotation annotation) {
3102            this.kind = kind;
3103            this.value = value;
3104            this.fixed = fixed;
3105            this.annotation = annotation;
3106        }
3107        /* (non-Javadoc)
3108         * @see org.apache.xerces.xs.XSFacet#getAnnotation()
3109         */

3110        public XSAnnotation getAnnotation() {
3111            return annotation;
3112        }
3113        
3114        /* (non-Javadoc)
3115         * @see org.apache.xerces.xs.XSFacet#getFacetKind()
3116         */

3117        public short getFacetKind() {
3118            return kind;
3119        }
3120        
3121        /* (non-Javadoc)
3122         * @see org.apache.xerces.xs.XSFacet#getLexicalFacetValue()
3123         */

3124        public String JavaDoc getLexicalFacetValue() {
3125            return value;
3126        }
3127        
3128        /* (non-Javadoc)
3129         * @see org.apache.xerces.xs.XSFacet#isFixed()
3130         */

3131        public boolean getFixed() {
3132            return fixed;
3133        }
3134        
3135        /* (non-Javadoc)
3136         * @see org.apache.xerces.xs.XSObject#getName()
3137         */

3138        public String JavaDoc getName() {
3139            return null;
3140        }
3141        
3142        /* (non-Javadoc)
3143         * @see org.apache.xerces.xs.XSObject#getNamespace()
3144         */

3145        public String JavaDoc getNamespace() {
3146            return null;
3147        }
3148        
3149        /* (non-Javadoc)
3150         * @see org.apache.xerces.xs.XSObject#getNamespaceItem()
3151         */

3152        public XSNamespaceItem getNamespaceItem() {
3153            // REVISIT: implement
3154
return null;
3155        }
3156        
3157        /* (non-Javadoc)
3158         * @see org.apache.xerces.xs.XSObject#getType()
3159         */

3160        public short getType() {
3161            return XSConstants.FACET;
3162        }
3163        
3164    }
3165    
3166    private static final class XSMVFacetImpl implements XSMultiValueFacet {
3167        final short kind;
3168        XSObjectList annotations;
3169        StringList values;
3170        
3171        public XSMVFacetImpl(short kind, StringList values, XSObjectList annotations) {
3172            this.kind = kind;
3173            this.values = values;
3174            this.annotations = annotations;
3175        }
3176        
3177        
3178        /* (non-Javadoc)
3179         * @see org.apache.xerces.xs.XSFacet#getFacetKind()
3180         */

3181        public short getFacetKind() {
3182            return kind;
3183        }
3184        
3185        
3186        /* (non-Javadoc)
3187         * @see org.apache.xerces.xs.XSMultiValueFacet#getAnnotations()
3188         */

3189        public XSObjectList getAnnotations() {
3190            return annotations;
3191        }
3192        
3193        /* (non-Javadoc)
3194         * @see org.apache.xerces.xs.XSMultiValueFacet#getLexicalFacetValues()
3195         */

3196        public StringList getLexicalFacetValues() {
3197            return values;
3198        }
3199        
3200        /* (non-Javadoc)
3201         * @see org.apache.xerces.xs.XSObject#getName()
3202         */

3203        public String JavaDoc getName() {
3204            return null;
3205        }
3206        
3207        /* (non-Javadoc)
3208         * @see org.apache.xerces.xs.XSObject#getNamespace()
3209         */

3210        public String JavaDoc getNamespace() {
3211            return null;
3212        }
3213        
3214        /* (non-Javadoc)
3215         * @see org.apache.xerces.xs.XSObject#getNamespaceItem()
3216         */

3217        public XSNamespaceItem getNamespaceItem() {
3218            // REVISIT: implement
3219
return null;
3220        }
3221        
3222        /* (non-Javadoc)
3223         * @see org.apache.xerces.xs.XSObject#getType()
3224         */

3225        public short getType() {
3226            return XSConstants.MULTIVALUE_FACET;
3227        }
3228    }
3229
3230    public String JavaDoc getTypeNamespace() {
3231        return getNamespace();
3232    }
3233
3234    public boolean isDerivedFrom(String JavaDoc typeNamespaceArg, String JavaDoc typeNameArg, int derivationMethod) {
3235        return isDOMDerivedFrom(typeNamespaceArg, typeNameArg, derivationMethod);
3236    }
3237    
3238    private short convertToPrimitiveKind(short valueType) {
3239        /** Primitive datatypes. */
3240        if (valueType <= XSConstants.NOTATION_DT) {
3241            return valueType;
3242        }
3243        /** Types derived from string. */
3244        if (valueType <= XSConstants.ENTITY_DT) {
3245            return XSConstants.STRING_DT;
3246        }
3247        /** Types derived from decimal. */
3248        if (valueType <= XSConstants.POSITIVEINTEGER_DT) {
3249            return XSConstants.DECIMAL_DT;
3250        }
3251        /** Other types. */
3252        return valueType;
3253    }
3254    
3255} // class XSSimpleTypeDecl
3256

3257
Popular Tags