1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Copyright 2001-2005 The Apache Software Foundation.
   7  *
   8  * Licensed under the Apache License, Version 2.0 (the "License");
   9  * you may not use this file except in compliance with the License.
  10  * You may obtain a copy of the License at
  11  *
  12  *      http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 
  21 package com.sun.org.apache.xerces.internal.impl.dv.xs;
  22 
  23 import java.util.AbstractList;
  24 import java.util.Locale;
  25 import java.util.StringTokenizer;
  26 import java.util.Vector;
  27 
  28 import com.sun.org.apache.xerces.internal.impl.Constants;
  29 import com.sun.org.apache.xerces.internal.impl.dv.DatatypeException;
  30 import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeFacetException;
  31 import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException;
  32 import com.sun.org.apache.xerces.internal.impl.dv.ValidatedInfo;
  33 import com.sun.org.apache.xerces.internal.impl.dv.ValidationContext;
  34 import com.sun.org.apache.xerces.internal.impl.dv.XSFacets;
  35 import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
  36 import com.sun.org.apache.xerces.internal.impl.xpath.regex.RegularExpression;
  37 import com.sun.org.apache.xerces.internal.impl.xpath.regex.ParseException;
  38 import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
  39 import com.sun.org.apache.xerces.internal.impl.xs.util.ShortListImpl;
  40 import com.sun.org.apache.xerces.internal.impl.xs.util.StringListImpl;
  41 import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl;
  42 import com.sun.org.apache.xerces.internal.util.XMLChar;
  43 import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
  44 import com.sun.org.apache.xerces.internal.xs.ShortList;
  45 import com.sun.org.apache.xerces.internal.xs.StringList;
  46 import com.sun.org.apache.xerces.internal.xs.XSAnnotation;
  47 import com.sun.org.apache.xerces.internal.xs.XSConstants;
  48 import com.sun.org.apache.xerces.internal.xs.XSFacet;
  49 import com.sun.org.apache.xerces.internal.xs.XSMultiValueFacet;
  50 import com.sun.org.apache.xerces.internal.xs.XSNamespaceItem;
  51 import com.sun.org.apache.xerces.internal.xs.XSObjectList;
  52 import com.sun.org.apache.xerces.internal.xs.XSSimpleTypeDefinition;
  53 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
  54 import com.sun.org.apache.xerces.internal.xs.datatypes.ObjectList;
  55 import org.w3c.dom.TypeInfo;
  56 
  57 /**
  58  * @xerces.internal
  59  *
  60  * @author Sandy Gao, IBM
  61  * @author Neeraj Bajaj, Sun Microsystems, inc.
  62  *
  63  * @version $Id: XSSimpleTypeDecl.java 3029 2011-04-24 17:50:18Z joehw $
  64  */
  65 public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo {
  66 
  67     protected static final short DV_STRING        = PRIMITIVE_STRING;
  68     protected static final short DV_BOOLEAN       = PRIMITIVE_BOOLEAN;
  69     protected static final short DV_DECIMAL       = PRIMITIVE_DECIMAL;
  70     protected static final short DV_FLOAT         = PRIMITIVE_FLOAT;
  71     protected static final short DV_DOUBLE        = PRIMITIVE_DOUBLE;
  72     protected static final short DV_DURATION      = PRIMITIVE_DURATION;
  73     protected static final short DV_DATETIME      = PRIMITIVE_DATETIME;
  74     protected static final short DV_TIME          = PRIMITIVE_TIME;
  75     protected static final short DV_DATE          = PRIMITIVE_DATE;
  76     protected static final short DV_GYEARMONTH    = PRIMITIVE_GYEARMONTH;
  77     protected static final short DV_GYEAR         = PRIMITIVE_GYEAR;
  78     protected static final short DV_GMONTHDAY     = PRIMITIVE_GMONTHDAY;
  79     protected static final short DV_GDAY          = PRIMITIVE_GDAY;
  80     protected static final short DV_GMONTH        = PRIMITIVE_GMONTH;
  81     protected static final short DV_HEXBINARY     = PRIMITIVE_HEXBINARY;
  82     protected static final short DV_BASE64BINARY  = PRIMITIVE_BASE64BINARY;
  83     protected static final short DV_ANYURI        = PRIMITIVE_ANYURI;
  84     protected static final short DV_QNAME         = PRIMITIVE_QNAME;
  85     protected static final short DV_PRECISIONDECIMAL = PRIMITIVE_PRECISIONDECIMAL;
  86     protected static final short DV_NOTATION      = PRIMITIVE_NOTATION;
  87 
  88     protected static final short DV_ANYSIMPLETYPE = 0;
  89     protected static final short DV_ID            = DV_NOTATION + 1;
  90     protected static final short DV_IDREF         = DV_NOTATION + 2;
  91     protected static final short DV_ENTITY        = DV_NOTATION + 3;
  92     protected static final short DV_INTEGER       = DV_NOTATION + 4;
  93     protected static final short DV_LIST          = DV_NOTATION + 5;
  94     protected static final short DV_UNION         = DV_NOTATION + 6;
  95     protected static final short DV_YEARMONTHDURATION = DV_NOTATION + 7;
  96     protected static final short DV_DAYTIMEDURATION     = DV_NOTATION + 8;
  97     protected static final short DV_ANYATOMICTYPE = DV_NOTATION + 9;
  98 
  99     private static final TypeValidator[] gDVs = {
 100         new AnySimpleDV(),
 101         new StringDV(),
 102         new BooleanDV(),
 103         new DecimalDV(),
 104         new FloatDV(),
 105         new DoubleDV(),
 106         new DurationDV(),
 107         new DateTimeDV(),
 108         new TimeDV(),
 109         new DateDV(),
 110         new YearMonthDV(),
 111         new YearDV(),
 112         new MonthDayDV(),
 113         new DayDV(),
 114         new MonthDV(),
 115         new HexBinaryDV(),
 116         new Base64BinaryDV(),
 117         new AnyURIDV(),
 118         new QNameDV(),
 119         new PrecisionDecimalDV(), // XML Schema 1.1 type
 120         new QNameDV(),   // notation use the same one as qname
 121         new IDDV(),
 122         new IDREFDV(),
 123         new EntityDV(),
 124         new IntegerDV(),
 125         new ListDV(),
 126         new UnionDV(),
 127         new YearMonthDurationDV(), // XML Schema 1.1 type
 128         new DayTimeDurationDV(), // XML Schema 1.1 type
 129         new AnyAtomicDV() // XML Schema 1.1 type
 130     };
 131 
 132     static final short NORMALIZE_NONE = 0;
 133     static final short NORMALIZE_TRIM = 1;
 134     static final short NORMALIZE_FULL = 2;
 135     static final short[] fDVNormalizeType = {
 136         NORMALIZE_NONE, //AnySimpleDV(),
 137         NORMALIZE_FULL, //StringDV(),
 138         NORMALIZE_TRIM, //BooleanDV(),
 139         NORMALIZE_TRIM, //DecimalDV(),
 140         NORMALIZE_TRIM, //FloatDV(),
 141         NORMALIZE_TRIM, //DoubleDV(),
 142         NORMALIZE_TRIM, //DurationDV(),
 143         NORMALIZE_TRIM, //DateTimeDV(),
 144         NORMALIZE_TRIM, //TimeDV(),
 145         NORMALIZE_TRIM, //DateDV(),
 146         NORMALIZE_TRIM, //YearMonthDV(),
 147         NORMALIZE_TRIM, //YearDV(),
 148         NORMALIZE_TRIM, //MonthDayDV(),
 149         NORMALIZE_TRIM, //DayDV(),
 150         NORMALIZE_TRIM, //MonthDV(),
 151         NORMALIZE_TRIM, //HexBinaryDV(),
 152         NORMALIZE_NONE, //Base64BinaryDV(),  // Base64 know how to deal with spaces
 153         NORMALIZE_TRIM, //AnyURIDV(),
 154         NORMALIZE_TRIM, //QNameDV(),
 155         NORMALIZE_TRIM, //PrecisionDecimalDV() (Schema 1.1)
 156         NORMALIZE_TRIM, //QNameDV(),   // notation
 157         NORMALIZE_TRIM, //IDDV(),
 158         NORMALIZE_TRIM, //IDREFDV(),
 159         NORMALIZE_TRIM, //EntityDV(),
 160         NORMALIZE_TRIM, //IntegerDV(),
 161         NORMALIZE_FULL, //ListDV(),
 162         NORMALIZE_NONE, //UnionDV(),
 163         NORMALIZE_TRIM, //YearMonthDurationDV() (Schema 1.1)
 164         NORMALIZE_TRIM, //DayTimeDurationDV() (Schema 1.1)
 165         NORMALIZE_NONE, //AnyAtomicDV() (Schema 1.1)
 166     };
 167 
 168     static final short SPECIAL_PATTERN_NONE     = 0;
 169     static final short SPECIAL_PATTERN_NMTOKEN  = 1;
 170     static final short SPECIAL_PATTERN_NAME     = 2;
 171     static final short SPECIAL_PATTERN_NCNAME   = 3;
 172 
 173     static final String[] SPECIAL_PATTERN_STRING   = {
 174         "NONE", "NMTOKEN", "Name", "NCName"
 175     };
 176 
 177     static final String[] WS_FACET_STRING = {
 178         "preserve", "replace", "collapse"
 179     };
 180 
 181     static final String URI_SCHEMAFORSCHEMA = "http://www.w3.org/2001/XMLSchema";
 182     static final String ANY_TYPE = "anyType";
 183 
 184     // XML Schema 1.1 type constants
 185     public static final short YEARMONTHDURATION_DT      = 46;
 186     public static final short DAYTIMEDURATION_DT        = 47;
 187     public static final short PRECISIONDECIMAL_DT       = 48;
 188     public static final short ANYATOMICTYPE_DT          = 49;
 189 
 190     // DOM Level 3 TypeInfo Derivation Method constants
 191     static final int DERIVATION_ANY = 0;
 192     static final int DERIVATION_RESTRICTION = 1;
 193     static final int DERIVATION_EXTENSION = 2;
 194     static final int DERIVATION_UNION = 4;
 195     static final int DERIVATION_LIST = 8;
 196 
 197     static final ValidationContext fEmptyContext = new ValidationContext() {
 198         public boolean needFacetChecking() {
 199             return true;
 200         }
 201         public boolean needExtraChecking() {
 202             return false;
 203         }
 204         public boolean needToNormalize() {
 205             return true;
 206         }
 207         public boolean useNamespaces () {
 208             return true;
 209         }
 210         public boolean isEntityDeclared (String name) {
 211             return false;
 212         }
 213         public boolean isEntityUnparsed (String name) {
 214             return false;
 215         }
 216         public boolean isIdDeclared (String name) {
 217             return false;
 218         }
 219         public void addId(String name) {
 220         }
 221         public void addIdRef(String name) {
 222         }
 223         public String getSymbol (String symbol) {
 224             return symbol.intern();
 225         }
 226         public String getURI(String prefix) {
 227             return null;
 228         }
 229         public Locale getLocale() {
 230             return Locale.getDefault();
 231         }
 232     };
 233 
 234     protected static TypeValidator[] getGDVs() {
 235         return (TypeValidator[])gDVs.clone();
 236     }
 237     private TypeValidator[] fDVs = gDVs;
 238     protected void setDVs(TypeValidator[] dvs) {
 239         fDVs = dvs;
 240     }
 241 
 242     // this will be true if this is a static XSSimpleTypeDecl
 243     // and hence must remain immutable (i.e., applyFacets
 244     // may not be permitted to have any effect).
 245     private boolean fIsImmutable = false;
 246 
 247     private XSSimpleTypeDecl fItemType;
 248     private XSSimpleTypeDecl[] fMemberTypes;
 249     // The most specific built-in type kind.
 250     private short fBuiltInKind;
 251 
 252     private String fTypeName;
 253     private String fTargetNamespace;
 254     private short fFinalSet = 0;
 255     private XSSimpleTypeDecl fBase;
 256     private short fVariety = -1;
 257     private short fValidationDV = -1;
 258 
 259     private short fFacetsDefined = 0;
 260     private short fFixedFacet = 0;
 261 
 262     //for constraining facets
 263     private short fWhiteSpace = 0;
 264     private int fLength = -1;
 265     private int fMinLength = -1;
 266     private int fMaxLength = -1;
 267     private int fTotalDigits = -1;
 268     private int fFractionDigits = -1;
 269     private Vector fPattern;
 270     private Vector fPatternStr;
 271     private Vector fEnumeration;
 272     private short[] fEnumerationType;
 273     private ShortList[] fEnumerationItemType;   // used in case fenumerationType value is LIST or LISTOFUNION
 274     private ShortList fEnumerationTypeList;
 275     private ObjectList fEnumerationItemTypeList;
 276     private StringList fLexicalPattern;
 277     private StringList fLexicalEnumeration;
 278     private ObjectList fActualEnumeration;
 279     private Object fMaxInclusive;
 280     private Object fMaxExclusive;
 281     private Object fMinExclusive;
 282     private Object fMinInclusive;
 283 
 284     // annotations for constraining facets
 285     public XSAnnotation lengthAnnotation;
 286     public XSAnnotation minLengthAnnotation;
 287     public XSAnnotation maxLengthAnnotation;
 288     public XSAnnotation whiteSpaceAnnotation;
 289     public XSAnnotation totalDigitsAnnotation;
 290     public XSAnnotation fractionDigitsAnnotation;
 291     public XSObjectListImpl patternAnnotations;
 292     public XSObjectList enumerationAnnotations;
 293     public XSAnnotation maxInclusiveAnnotation;
 294     public XSAnnotation maxExclusiveAnnotation;
 295     public XSAnnotation minInclusiveAnnotation;
 296     public XSAnnotation minExclusiveAnnotation;
 297 
 298     // facets as objects
 299     private XSObjectListImpl fFacets;
 300 
 301     // enumeration and pattern facets
 302     private XSObjectListImpl fMultiValueFacets;
 303 
 304     // simpleType annotations
 305     private XSObjectList fAnnotations = null;
 306 
 307     private short fPatternType = SPECIAL_PATTERN_NONE;
 308 
 309     // for fundamental facets
 310     private short fOrdered;
 311     private boolean fFinite;
 312     private boolean fBounded;
 313     private boolean fNumeric;
 314 
 315     // The namespace schema information item corresponding to the target namespace
 316     // of the simple type definition, if it is globally declared; or null otherwise.
 317     private XSNamespaceItem fNamespaceItem = null;
 318 
 319     // default constructor
 320     public XSSimpleTypeDecl(){}
 321 
 322     //Create a new built-in primitive types (and id/idref/entity/integer/yearMonthDuration)
 323     protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String name, short validateDV,
 324             short ordered, boolean bounded, boolean finite,
 325             boolean numeric, boolean isImmutable, short builtInKind) {
 326         fIsImmutable = isImmutable;
 327         fBase = base;
 328         fTypeName = name;
 329         fTargetNamespace = URI_SCHEMAFORSCHEMA;
 330         // To simplify the code for anySimpleType, we treat it as an atomic type
 331         fVariety = VARIETY_ATOMIC;
 332         fValidationDV = validateDV;
 333         fFacetsDefined = FACET_WHITESPACE;
 334         if (validateDV == DV_ANYSIMPLETYPE ||
 335             validateDV == DV_ANYATOMICTYPE ||
 336             validateDV == DV_STRING) {
 337             fWhiteSpace = WS_PRESERVE;
 338         }
 339         else {
 340             fWhiteSpace = WS_COLLAPSE;
 341             fFixedFacet = FACET_WHITESPACE;
 342         }
 343         this.fOrdered = ordered;
 344         this.fBounded = bounded;
 345         this.fFinite = finite;
 346         this.fNumeric = numeric;
 347         fAnnotations = null;
 348 
 349         // Specify the build in kind for this primitive type
 350         fBuiltInKind = builtInKind;
 351     }
 352 
 353     //Create a new simple type for restriction for built-in types
 354     protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String name, String uri, short finalSet, boolean isImmutable,
 355             XSObjectList annotations, short builtInKind) {
 356         this(base, name, uri, finalSet, isImmutable, annotations);
 357         // Specify the build in kind for this built-in type
 358         fBuiltInKind = builtInKind;
 359     }
 360 
 361     //Create a new simple type for restriction.
 362     protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String name, String uri, short finalSet, boolean isImmutable,
 363             XSObjectList annotations) {
 364         fBase = base;
 365         fTypeName = name;
 366         fTargetNamespace = uri;
 367         fFinalSet = finalSet;
 368         fAnnotations = annotations;
 369 
 370         fVariety = fBase.fVariety;
 371         fValidationDV = fBase.fValidationDV;
 372         switch (fVariety) {
 373             case VARIETY_ATOMIC:
 374                 break;
 375             case VARIETY_LIST:
 376                 fItemType = fBase.fItemType;
 377                 break;
 378             case VARIETY_UNION:
 379                 fMemberTypes = fBase.fMemberTypes;
 380                 break;
 381         }
 382 
 383         // always inherit facets from the base.
 384         // in case a type is created, but applyFacets is not called
 385         fLength = fBase.fLength;
 386         fMinLength = fBase.fMinLength;
 387         fMaxLength = fBase.fMaxLength;
 388         fPattern = fBase.fPattern;
 389         fPatternStr = fBase.fPatternStr;
 390         fEnumeration = fBase.fEnumeration;
 391         fEnumerationType = fBase.fEnumerationType;
 392         fEnumerationItemType = fBase.fEnumerationItemType;
 393         fWhiteSpace = fBase.fWhiteSpace;
 394         fMaxExclusive = fBase.fMaxExclusive;
 395         fMaxInclusive = fBase.fMaxInclusive;
 396         fMinExclusive = fBase.fMinExclusive;
 397         fMinInclusive = fBase.fMinInclusive;
 398         fTotalDigits = fBase.fTotalDigits;
 399         fFractionDigits = fBase.fFractionDigits;
 400         fPatternType = fBase.fPatternType;
 401         fFixedFacet = fBase.fFixedFacet;
 402         fFacetsDefined = fBase.fFacetsDefined;
 403 
 404         // always inherit facet annotations in case applyFacets is not called.
 405         lengthAnnotation = fBase.lengthAnnotation;
 406         minLengthAnnotation = fBase.minLengthAnnotation;
 407         maxLengthAnnotation = fBase.maxLengthAnnotation;
 408         patternAnnotations = fBase.patternAnnotations;
 409         enumerationAnnotations = fBase.enumerationAnnotations;
 410         whiteSpaceAnnotation = fBase.whiteSpaceAnnotation;
 411         maxExclusiveAnnotation = fBase.maxExclusiveAnnotation;
 412         maxInclusiveAnnotation = fBase.maxInclusiveAnnotation;
 413         minExclusiveAnnotation = fBase.minExclusiveAnnotation;
 414         minInclusiveAnnotation = fBase.minInclusiveAnnotation;
 415         totalDigitsAnnotation = fBase.totalDigitsAnnotation;
 416         fractionDigitsAnnotation = fBase.fractionDigitsAnnotation;
 417 
 418         //we also set fundamental facets information in case applyFacets is not called.
 419         calcFundamentalFacets();
 420         fIsImmutable = isImmutable;
 421 
 422         // Inherit from the base type
 423         fBuiltInKind = base.fBuiltInKind;
 424     }
 425 
 426     //Create a new simple type for list.
 427     protected XSSimpleTypeDecl(String name, String uri, short finalSet, XSSimpleTypeDecl itemType, boolean isImmutable,
 428             XSObjectList annotations) {
 429         fBase = fAnySimpleType;
 430         fTypeName = name;
 431         fTargetNamespace = uri;
 432         fFinalSet = finalSet;
 433         fAnnotations = annotations;
 434 
 435         fVariety = VARIETY_LIST;
 436         fItemType = (XSSimpleTypeDecl)itemType;
 437         fValidationDV = DV_LIST;
 438         fFacetsDefined = FACET_WHITESPACE;
 439         fFixedFacet = FACET_WHITESPACE;
 440         fWhiteSpace = WS_COLLAPSE;
 441 
 442         //setting fundamental facets
 443         calcFundamentalFacets();
 444         fIsImmutable = isImmutable;
 445 
 446         // Values of this type are lists
 447         fBuiltInKind = XSConstants.LIST_DT;
 448     }
 449 
 450     //Create a new simple type for union.
 451     protected XSSimpleTypeDecl(String name, String uri, short finalSet, XSSimpleTypeDecl[] memberTypes,
 452             XSObjectList annotations) {
 453         fBase = fAnySimpleType;
 454         fTypeName = name;
 455         fTargetNamespace = uri;
 456         fFinalSet = finalSet;
 457         fAnnotations = annotations;
 458 
 459         fVariety = VARIETY_UNION;
 460         fMemberTypes = memberTypes;
 461         fValidationDV = DV_UNION;
 462         // even for union, we set whitespace to something
 463         // this will never be used, but we can use fFacetsDefined to check
 464         // whether applyFacets() is allwwed: it's not allowed
 465         // if fFacetsDefined != 0
 466         fFacetsDefined = FACET_WHITESPACE;
 467         fWhiteSpace = WS_COLLAPSE;
 468 
 469         //setting fundamental facets
 470         calcFundamentalFacets();
 471         // none of the schema-defined types are unions, so just set
 472         // fIsImmutable to false.
 473         fIsImmutable = false;
 474 
 475         // No value can be of this type, so it's unavailable.
 476         fBuiltInKind = XSConstants.UNAVAILABLE_DT;
 477     }
 478 
 479     //set values for restriction.
 480     protected XSSimpleTypeDecl setRestrictionValues(XSSimpleTypeDecl base, String name, String uri, short finalSet,
 481             XSObjectList annotations) {
 482         //decline to do anything if the object is immutable.
 483         if(fIsImmutable) return null;
 484         fBase = base;
 485         fAnonymous = false;
 486         fTypeName = name;
 487         fTargetNamespace = uri;
 488         fFinalSet = finalSet;
 489         fAnnotations = annotations;
 490 
 491         fVariety = fBase.fVariety;
 492         fValidationDV = fBase.fValidationDV;
 493         switch (fVariety) {
 494             case VARIETY_ATOMIC:
 495                 break;
 496             case VARIETY_LIST:
 497                 fItemType = fBase.fItemType;
 498                 break;
 499             case VARIETY_UNION:
 500                 fMemberTypes = fBase.fMemberTypes;
 501                 break;
 502         }
 503 
 504         // always inherit facets from the base.
 505         // in case a type is created, but applyFacets is not called
 506         fLength = fBase.fLength;
 507         fMinLength = fBase.fMinLength;
 508         fMaxLength = fBase.fMaxLength;
 509         fPattern = fBase.fPattern;
 510         fPatternStr = fBase.fPatternStr;
 511         fEnumeration = fBase.fEnumeration;
 512         fEnumerationType = fBase.fEnumerationType;
 513         fEnumerationItemType = fBase.fEnumerationItemType;
 514         fWhiteSpace = fBase.fWhiteSpace;
 515         fMaxExclusive = fBase.fMaxExclusive;
 516         fMaxInclusive = fBase.fMaxInclusive;
 517         fMinExclusive = fBase.fMinExclusive;
 518         fMinInclusive = fBase.fMinInclusive;
 519         fTotalDigits = fBase.fTotalDigits;
 520         fFractionDigits = fBase.fFractionDigits;
 521         fPatternType = fBase.fPatternType;
 522         fFixedFacet = fBase.fFixedFacet;
 523         fFacetsDefined = fBase.fFacetsDefined;
 524 
 525         //we also set fundamental facets information in case applyFacets is not called.
 526         calcFundamentalFacets();
 527 
 528         // Inherit from the base type
 529         fBuiltInKind = base.fBuiltInKind;
 530 
 531         return this;
 532     }
 533 
 534     //set values for list.
 535     protected XSSimpleTypeDecl setListValues(String name, String uri, short finalSet, XSSimpleTypeDecl itemType,
 536             XSObjectList annotations) {
 537         //decline to do anything if the object is immutable.
 538         if(fIsImmutable) return null;
 539         fBase = fAnySimpleType;
 540         fAnonymous = false;
 541         fTypeName = name;
 542         fTargetNamespace = uri;
 543         fFinalSet = finalSet;
 544         fAnnotations = annotations;
 545 
 546         fVariety = VARIETY_LIST;
 547         fItemType = (XSSimpleTypeDecl)itemType;
 548         fValidationDV = DV_LIST;
 549         fFacetsDefined = FACET_WHITESPACE;
 550         fFixedFacet = FACET_WHITESPACE;
 551         fWhiteSpace = WS_COLLAPSE;
 552 
 553         //setting fundamental facets
 554         calcFundamentalFacets();
 555 
 556         // Values of this type are lists
 557         fBuiltInKind = XSConstants.LIST_DT;
 558 
 559         return this;
 560     }
 561 
 562     //set values for union.
 563     protected XSSimpleTypeDecl setUnionValues(String name, String uri, short finalSet, XSSimpleTypeDecl[] memberTypes,
 564             XSObjectList annotations) {
 565         //decline to do anything if the object is immutable.
 566         if(fIsImmutable) return null;
 567         fBase = fAnySimpleType;
 568         fAnonymous = false;
 569         fTypeName = name;
 570         fTargetNamespace = uri;
 571         fFinalSet = finalSet;
 572         fAnnotations = annotations;
 573 
 574         fVariety = VARIETY_UNION;
 575         fMemberTypes = memberTypes;
 576         fValidationDV = DV_UNION;
 577         // even for union, we set whitespace to something
 578         // this will never be used, but we can use fFacetsDefined to check
 579         // whether applyFacets() is allwwed: it's not allowed
 580         // if fFacetsDefined != 0
 581         fFacetsDefined = FACET_WHITESPACE;
 582         fWhiteSpace = WS_COLLAPSE;
 583 
 584         //setting fundamental facets
 585         calcFundamentalFacets();
 586 
 587         // No value can be of this type, so it's unavailable.
 588         fBuiltInKind = XSConstants.UNAVAILABLE_DT;
 589 
 590         return this;
 591     }
 592 
 593     public short getType () {
 594         return XSConstants.TYPE_DEFINITION;
 595     }
 596 
 597     public short getTypeCategory () {
 598         return SIMPLE_TYPE;
 599     }
 600 
 601     public String getName() {
 602         return getAnonymous()?null:fTypeName;
 603     }
 604 
 605     public String getTypeName() {
 606         return fTypeName;
 607     }
 608 
 609     public String getNamespace() {
 610         return fTargetNamespace;
 611     }
 612 
 613     public short getFinal(){
 614         return fFinalSet;
 615     }
 616 
 617     public boolean isFinal(short derivation) {
 618         return (fFinalSet & derivation) != 0;
 619     }
 620 
 621     public XSTypeDefinition getBaseType(){
 622         return fBase;
 623     }
 624 
 625     public boolean getAnonymous() {
 626         return fAnonymous || (fTypeName == null);
 627     }
 628 
 629     public short getVariety(){
 630         // for anySimpleType, return absent variaty
 631         return fValidationDV == DV_ANYSIMPLETYPE ? VARIETY_ABSENT : fVariety;
 632     }
 633 
 634     public boolean isIDType(){
 635         switch (fVariety) {
 636             case VARIETY_ATOMIC:
 637                 return fValidationDV == DV_ID;
 638             case VARIETY_LIST:
 639                 return fItemType.isIDType();
 640             case VARIETY_UNION:
 641                 for (int i = 0; i < fMemberTypes.length; i++) {
 642                     if (fMemberTypes[i].isIDType())
 643                         return true;
 644                 }
 645         }
 646         return false;
 647     }
 648 
 649     public short getWhitespace() throws DatatypeException{
 650         if (fVariety == VARIETY_UNION) {
 651             throw new DatatypeException("dt-whitespace", new Object[]{fTypeName});
 652         }
 653         return fWhiteSpace;
 654     }
 655 
 656     public short getPrimitiveKind() {
 657         if (fVariety == VARIETY_ATOMIC && fValidationDV != DV_ANYSIMPLETYPE) {
 658             if (fValidationDV == DV_ID || fValidationDV == DV_IDREF || fValidationDV == DV_ENTITY) {
 659                 return DV_STRING;
 660             }
 661             else if (fValidationDV == DV_INTEGER) {
 662                 return DV_DECIMAL;
 663             }
 664             else if (Constants.SCHEMA_1_1_SUPPORT && (fValidationDV == DV_YEARMONTHDURATION || fValidationDV == DV_DAYTIMEDURATION)) {
 665                 return DV_DURATION;
 666             }
 667             else {
 668                 return fValidationDV;
 669             }
 670         }
 671         else {
 672             // REVISIT: error situation. runtime exception?
 673             return (short)0;
 674         }
 675     }
 676 
 677     /**
 678      * Returns the closest built-in type category this type represents or
 679      * derived from. For example, if this simple type is a built-in derived
 680      * type integer the <code>INTEGER_DV</code> is returned.
 681      */
 682     public short getBuiltInKind() {
 683         return this.fBuiltInKind;
 684     }
 685 
 686     /**
 687      * If variety is <code>atomic</code> the primitive type definition (a
 688      * built-in primitive datatype definition or the simple ur-type
 689      * definition) is available, otherwise <code>null</code>.
 690      */
 691     public XSSimpleTypeDefinition getPrimitiveType() {
 692         if (fVariety == VARIETY_ATOMIC && fValidationDV != DV_ANYSIMPLETYPE) {
 693             XSSimpleTypeDecl pri = this;
 694             // recursively get base, until we reach anySimpleType
 695             while (pri.fBase != fAnySimpleType)
 696                 pri = pri.fBase;
 697             return pri;
 698         }
 699         else {
 700             // REVISIT: error situation. runtime exception?
 701             return null;
 702         }
 703     }
 704 
 705     /**
 706      * If variety is <code>list</code> the item type definition (an atomic or
 707      * union simple type definition) is available, otherwise
 708      * <code>null</code>.
 709      */
 710     public XSSimpleTypeDefinition getItemType() {
 711         if (fVariety == VARIETY_LIST) {
 712             return fItemType;
 713         }
 714         else {
 715             // REVISIT: error situation. runtime exception?
 716             return null;
 717         }
 718     }
 719 
 720     /**
 721      * If variety is <code>union</code> the list of member type definitions (a
 722      * non-empty sequence of simple type definitions) is available,
 723      * otherwise an empty <code>XSObjectList</code>.
 724      */
 725     public XSObjectList getMemberTypes() {
 726         if (fVariety == VARIETY_UNION) {
 727             return new XSObjectListImpl(fMemberTypes, fMemberTypes.length);
 728         }
 729         else {
 730             return XSObjectListImpl.EMPTY_LIST;
 731         }
 732     }
 733 
 734     /**
 735      * If <restriction> is chosen
 736      */
 737     public void applyFacets(XSFacets facets, short presentFacet, short fixedFacet, ValidationContext context)
 738     throws InvalidDatatypeFacetException {
 739         if (context == null) {
 740             context = fEmptyContext;
 741         }
 742         applyFacets(facets, presentFacet, fixedFacet, SPECIAL_PATTERN_NONE, context);
 743     }
 744 
 745     /**
 746      * built-in derived types by restriction
 747      */
 748     void applyFacets1(XSFacets facets, short presentFacet, short fixedFacet) {
 749 
 750         try {
 751             applyFacets(facets, presentFacet, fixedFacet, SPECIAL_PATTERN_NONE, fDummyContext);
 752         } catch (InvalidDatatypeFacetException e) {
 753             // should never gets here, internel error
 754             throw new RuntimeException("internal error");
 755         }
 756         // we've now applied facets; so lock this object:
 757         fIsImmutable = true;
 758     }
 759 
 760     /**
 761      * built-in derived types by restriction
 762      */
 763     void applyFacets1(XSFacets facets, short presentFacet, short fixedFacet, short patternType) {
 764 
 765         try {
 766             applyFacets(facets, presentFacet, fixedFacet, patternType, fDummyContext);
 767         } catch (InvalidDatatypeFacetException e) {
 768             // should never gets here, internel error
 769             throw new RuntimeException("internal error");
 770         }
 771         // we've now applied facets; so lock this object:
 772         fIsImmutable = true;
 773     }
 774 
 775     /**
 776      * If <restriction> is chosen, or built-in derived types by restriction
 777      */
 778     void applyFacets(XSFacets facets, short presentFacet, short fixedFacet, short patternType, ValidationContext context)
 779     throws InvalidDatatypeFacetException {
 780 
 781         // if the object is immutable, should not apply facets...
 782         if(fIsImmutable) return;
 783         ValidatedInfo tempInfo = new ValidatedInfo();
 784 
 785         // clear facets. because we always inherit facets in the constructor
 786         // REVISIT: in fact, we don't need to clear them.
 787         // we can convert 5 string values (4 bounds + 1 enum) to actual values,
 788         // store them somewhere, then do facet checking at once, instead of
 789         // going through the following steps. (lots of checking are redundant:
 790         // for example, ((presentFacet & FACET_XXX) != 0))
 791 
 792         fFacetsDefined = 0;
 793         fFixedFacet = 0;
 794 
 795         int result = 0 ;
 796 
 797         // step 1: parse present facets
 798         short allowedFacet = fDVs[fValidationDV].getAllowedFacets();
 799 
 800         // length
 801         if ((presentFacet & FACET_LENGTH) != 0) {
 802             if ((allowedFacet & FACET_LENGTH) == 0) {
 803                 reportError("cos-applicable-facets", new Object[]{"length", fTypeName});
 804             } else {
 805                 fLength = facets.length;
 806                 lengthAnnotation = facets.lengthAnnotation;
 807                 fFacetsDefined |= FACET_LENGTH;
 808                 if ((fixedFacet & FACET_LENGTH) != 0)
 809                     fFixedFacet |= FACET_LENGTH;
 810             }
 811         }
 812         // minLength
 813         if ((presentFacet & FACET_MINLENGTH) != 0) {
 814             if ((allowedFacet & FACET_MINLENGTH) == 0) {
 815                 reportError("cos-applicable-facets", new Object[]{"minLength", fTypeName});
 816             } else {
 817                 fMinLength = facets.minLength;
 818                 minLengthAnnotation = facets.minLengthAnnotation;
 819                 fFacetsDefined |= FACET_MINLENGTH;
 820                 if ((fixedFacet & FACET_MINLENGTH) != 0)
 821                     fFixedFacet |= FACET_MINLENGTH;
 822             }
 823         }
 824         // maxLength
 825         if ((presentFacet & FACET_MAXLENGTH) != 0) {
 826             if ((allowedFacet & FACET_MAXLENGTH) == 0) {
 827                 reportError("cos-applicable-facets", new Object[]{"maxLength", fTypeName});
 828             } else {
 829                 fMaxLength = facets.maxLength;
 830                 maxLengthAnnotation = facets.maxLengthAnnotation;
 831                 fFacetsDefined |= FACET_MAXLENGTH;
 832                 if ((fixedFacet & FACET_MAXLENGTH) != 0)
 833                     fFixedFacet |= FACET_MAXLENGTH;
 834             }
 835         }
 836         // pattern
 837         if ((presentFacet & FACET_PATTERN) != 0) {
 838             if ((allowedFacet & FACET_PATTERN) == 0) {
 839                 reportError("cos-applicable-facets", new Object[]{"pattern", fTypeName});
 840             } else {
 841                 patternAnnotations = facets.patternAnnotations;
 842                 RegularExpression regex = null;
 843                 try {
 844                     regex = new RegularExpression(facets.pattern, "X", context.getLocale());
 845                 } catch (Exception e) {
 846                     reportError("InvalidRegex", new Object[]{facets.pattern, e.getLocalizedMessage()});
 847                 }
 848                 if (regex != null) {
 849                     fPattern = new Vector();
 850                     fPattern.addElement(regex);
 851                     fPatternStr = new Vector();
 852                     fPatternStr.addElement(facets.pattern);
 853                     fFacetsDefined |= FACET_PATTERN;
 854                     if ((fixedFacet & FACET_PATTERN) != 0)
 855                         fFixedFacet |= FACET_PATTERN;
 856                 }
 857             }
 858         }
 859 
 860         // whiteSpace
 861         if ((presentFacet & FACET_WHITESPACE) != 0) {
 862             if ((allowedFacet & FACET_WHITESPACE) == 0) {
 863                 reportError("cos-applicable-facets", new Object[]{"whiteSpace", fTypeName});
 864             } else {
 865                 fWhiteSpace = facets.whiteSpace;
 866                 whiteSpaceAnnotation = facets.whiteSpaceAnnotation;
 867                 fFacetsDefined |= FACET_WHITESPACE;
 868                 if ((fixedFacet & FACET_WHITESPACE) != 0)
 869                     fFixedFacet |= FACET_WHITESPACE;
 870             }
 871         }
 872         // enumeration
 873         if ((presentFacet & FACET_ENUMERATION) != 0) {
 874             if ((allowedFacet & FACET_ENUMERATION) == 0) {
 875                 reportError("cos-applicable-facets", new Object[]{"enumeration", fTypeName});
 876             } else {
 877                 fEnumeration = new Vector();
 878                 Vector enumVals = facets.enumeration;
 879                 fEnumerationType = new short[enumVals.size()];
 880                 fEnumerationItemType = new ShortList[enumVals.size()];
 881                 Vector enumNSDecls = facets.enumNSDecls;
 882                 ValidationContextImpl ctx = new ValidationContextImpl(context);
 883                 enumerationAnnotations = facets.enumAnnotations;
 884                 for (int i = 0; i < enumVals.size(); i++) {
 885                     if (enumNSDecls != null)
 886                         ctx.setNSContext((NamespaceContext)enumNSDecls.elementAt(i));
 887                     try {
 888                         ValidatedInfo info = getActualEnumValue((String)enumVals.elementAt(i), ctx, tempInfo);
 889                         // check 4.3.5.c0 must: enumeration values from the value space of base
 890                         fEnumeration.addElement(info.actualValue);
 891                         fEnumerationType[i] = info.actualValueType;
 892                         fEnumerationItemType[i] = info.itemValueTypes;
 893                     } catch (InvalidDatatypeValueException ide) {
 894                         reportError("enumeration-valid-restriction", new Object[]{enumVals.elementAt(i), this.getBaseType().getName()});
 895                     }
 896                 }
 897                 fFacetsDefined |= FACET_ENUMERATION;
 898                 if ((fixedFacet & FACET_ENUMERATION) != 0)
 899                     fFixedFacet |= FACET_ENUMERATION;
 900             }
 901         }
 902 
 903         // maxInclusive
 904         if ((presentFacet & FACET_MAXINCLUSIVE) != 0) {
 905             if ((allowedFacet & FACET_MAXINCLUSIVE) == 0) {
 906                 reportError("cos-applicable-facets", new Object[]{"maxInclusive", fTypeName});
 907             } else {
 908                 maxInclusiveAnnotation = facets.maxInclusiveAnnotation;
 909                 try {
 910                     fMaxInclusive = fBase.getActualValue(facets.maxInclusive, context, tempInfo, true);
 911                     fFacetsDefined |= FACET_MAXINCLUSIVE;
 912                     if ((fixedFacet & FACET_MAXINCLUSIVE) != 0)
 913                         fFixedFacet |= FACET_MAXINCLUSIVE;
 914                 } catch (InvalidDatatypeValueException ide) {
 915                     reportError(ide.getKey(), ide.getArgs());
 916                     reportError("FacetValueFromBase", new Object[]{fTypeName, facets.maxInclusive,
 917                             "maxInclusive", fBase.getName()});
 918                 }
 919 
 920                 // check against fixed value in base
 921                 if (((fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
 922                     if ((fBase.fFixedFacet & FACET_MAXINCLUSIVE) != 0) {
 923                         if (fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMaxInclusive) != 0)
 924                             reportError( "FixedFacetValue", new Object[]{"maxInclusive", fMaxInclusive, fBase.fMaxInclusive, fTypeName});
 925                     }
 926                 }
 927                 // maxInclusive from base
 928                 try {
 929                     fBase.validate(context, tempInfo);
 930                 } catch (InvalidDatatypeValueException ide) {
 931                     reportError(ide.getKey(), ide.getArgs());
 932                     reportError("FacetValueFromBase", new Object[]{fTypeName, facets.maxInclusive,
 933                             "maxInclusive", fBase.getName()});
 934                 }
 935             }
 936         }
 937 
 938         // maxExclusive
 939         boolean needCheckBase = true;
 940         if ((presentFacet & FACET_MAXEXCLUSIVE) != 0) {
 941             if ((allowedFacet & FACET_MAXEXCLUSIVE) == 0) {
 942                 reportError("cos-applicable-facets", new Object[]{"maxExclusive", fTypeName});
 943             } else {
 944                 maxExclusiveAnnotation = facets.maxExclusiveAnnotation;
 945                 try {
 946                     fMaxExclusive = fBase.getActualValue(facets.maxExclusive, context, tempInfo, true);
 947                     fFacetsDefined |= FACET_MAXEXCLUSIVE;
 948                     if ((fixedFacet & FACET_MAXEXCLUSIVE) != 0)
 949                         fFixedFacet |= FACET_MAXEXCLUSIVE;
 950                 } catch (InvalidDatatypeValueException ide) {
 951                     reportError(ide.getKey(), ide.getArgs());
 952                     reportError("FacetValueFromBase", new Object[]{fTypeName, facets.maxExclusive,
 953                             "maxExclusive", fBase.getName()});
 954                 }
 955 
 956                 // check against fixed value in base
 957                 if (((fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) {
 958                     result = fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMaxExclusive);
 959                     if ((fBase.fFixedFacet & FACET_MAXEXCLUSIVE) != 0 && result != 0) {
 960                         reportError( "FixedFacetValue", new Object[]{"maxExclusive", facets.maxExclusive, fBase.fMaxExclusive, fTypeName});
 961                     }
 962                     if (result == 0) {
 963                         needCheckBase = false;
 964                     }
 965                 }
 966                 // maxExclusive from base
 967                 if (needCheckBase) {
 968                     try {
 969                         fBase.validate(context, tempInfo);
 970                     } catch (InvalidDatatypeValueException ide) {
 971                         reportError(ide.getKey(), ide.getArgs());
 972                         reportError("FacetValueFromBase", new Object[]{fTypeName, facets.maxExclusive,
 973                                 "maxExclusive", fBase.getName()});
 974                     }
 975                 }
 976                 // If maxExclusive == base.maxExclusive, then we only need to check
 977                 // maxExclusive <= base.maxInclusive
 978                 else if (((fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
 979                     if (fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMaxInclusive) > 0) {
 980                         reportError( "maxExclusive-valid-restriction.2", new Object[]{facets.maxExclusive, fBase.fMaxInclusive});
 981                     }
 982                 }
 983             }
 984         }
 985         // minExclusive
 986         needCheckBase = true;
 987         if ((presentFacet & FACET_MINEXCLUSIVE) != 0) {
 988             if ((allowedFacet & FACET_MINEXCLUSIVE) == 0) {
 989                 reportError("cos-applicable-facets", new Object[]{"minExclusive", fTypeName});
 990             } else {
 991                 minExclusiveAnnotation = facets.minExclusiveAnnotation;
 992                 try {
 993                     fMinExclusive = fBase.getActualValue(facets.minExclusive, context, tempInfo, true);
 994                     fFacetsDefined |= FACET_MINEXCLUSIVE;
 995                     if ((fixedFacet & FACET_MINEXCLUSIVE) != 0)
 996                         fFixedFacet |= FACET_MINEXCLUSIVE;
 997                 } catch (InvalidDatatypeValueException ide) {
 998                     reportError(ide.getKey(), ide.getArgs());
 999                     reportError("FacetValueFromBase", new Object[]{fTypeName, facets.minExclusive,
1000                             "minExclusive", fBase.getName()});
1001                 }
1002 
1003                 // check against fixed value in base
1004                 if (((fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
1005                     result = fDVs[fValidationDV].compare(fMinExclusive, fBase.fMinExclusive);
1006                     if ((fBase.fFixedFacet & FACET_MINEXCLUSIVE) != 0 && result != 0) {
1007                         reportError( "FixedFacetValue", new Object[]{"minExclusive", facets.minExclusive, fBase.fMinExclusive, fTypeName});
1008                     }
1009                     if (result == 0) {
1010                         needCheckBase = false;
1011                     }
1012                 }
1013                 // minExclusive from base
1014                 if (needCheckBase) {
1015                     try {
1016                         fBase.validate(context, tempInfo);
1017                     } catch (InvalidDatatypeValueException ide) {
1018                         reportError(ide.getKey(), ide.getArgs());
1019                         reportError("FacetValueFromBase", new Object[]{fTypeName, facets.minExclusive,
1020                                 "minExclusive", fBase.getName()});
1021                     }
1022                 }
1023                 // If minExclusive == base.minExclusive, then we only need to check
1024                 // minExclusive >= base.minInclusive
1025                 else if (((fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1026                     if (fDVs[fValidationDV].compare(fMinExclusive, fBase.fMinInclusive) < 0) {
1027                         reportError( "minExclusive-valid-restriction.3", new Object[]{facets.minExclusive, fBase.fMinInclusive});
1028                     }
1029                 }
1030             }
1031         }
1032         // minInclusive
1033         if ((presentFacet & FACET_MININCLUSIVE) != 0) {
1034             if ((allowedFacet & FACET_MININCLUSIVE) == 0) {
1035                 reportError("cos-applicable-facets", new Object[]{"minInclusive", fTypeName});
1036             } else {
1037                 minInclusiveAnnotation = facets.minInclusiveAnnotation;
1038                 try {
1039                     fMinInclusive = fBase.getActualValue(facets.minInclusive, context, tempInfo, true);
1040                     fFacetsDefined |= FACET_MININCLUSIVE;
1041                     if ((fixedFacet & FACET_MININCLUSIVE) != 0)
1042                         fFixedFacet |= FACET_MININCLUSIVE;
1043                 } catch (InvalidDatatypeValueException ide) {
1044                     reportError(ide.getKey(), ide.getArgs());
1045                     reportError("FacetValueFromBase", new Object[]{fTypeName, facets.minInclusive,
1046                             "minInclusive", fBase.getName()});
1047                 }
1048 
1049                 // check against fixed value in base
1050                 if (((fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1051                     if ((fBase.fFixedFacet & FACET_MININCLUSIVE) != 0) {
1052                         if (fDVs[fValidationDV].compare(fMinInclusive, fBase.fMinInclusive) != 0)
1053                             reportError( "FixedFacetValue", new Object[]{"minInclusive", facets.minInclusive, fBase.fMinInclusive, fTypeName});
1054                     }
1055                 }
1056                 // minInclusive from base
1057                 try {
1058                     fBase.validate(context, tempInfo);
1059                 } catch (InvalidDatatypeValueException ide) {
1060                     reportError(ide.getKey(), ide.getArgs());
1061                     reportError("FacetValueFromBase", new Object[]{fTypeName, facets.minInclusive,
1062                             "minInclusive", fBase.getName()});
1063                 }
1064             }
1065         }
1066 
1067         // totalDigits
1068         if ((presentFacet & FACET_TOTALDIGITS) != 0) {
1069             if ((allowedFacet & FACET_TOTALDIGITS) == 0) {
1070                 reportError("cos-applicable-facets", new Object[]{"totalDigits", fTypeName});
1071             } else {
1072                 totalDigitsAnnotation = facets.totalDigitsAnnotation;
1073                 fTotalDigits = facets.totalDigits;
1074                 fFacetsDefined |= FACET_TOTALDIGITS;
1075                 if ((fixedFacet & FACET_TOTALDIGITS) != 0)
1076                     fFixedFacet |= FACET_TOTALDIGITS;
1077             }
1078         }
1079         // fractionDigits
1080         if ((presentFacet & FACET_FRACTIONDIGITS) != 0) {
1081             if ((allowedFacet & FACET_FRACTIONDIGITS) == 0) {
1082                 reportError("cos-applicable-facets", new Object[]{"fractionDigits", fTypeName});
1083             } else {
1084                 fFractionDigits = facets.fractionDigits;
1085                 fractionDigitsAnnotation = facets.fractionDigitsAnnotation;
1086                 fFacetsDefined |= FACET_FRACTIONDIGITS;
1087                 if ((fixedFacet & FACET_FRACTIONDIGITS) != 0)
1088                     fFixedFacet |= FACET_FRACTIONDIGITS;
1089             }
1090         }
1091 
1092         // token type: internal use, so do less checking
1093         if (patternType != SPECIAL_PATTERN_NONE) {
1094             fPatternType = patternType;
1095         }
1096 
1097         // step 2: check facets against each other: length, bounds
1098         if(fFacetsDefined != 0) {
1099 
1100             // check 4.3.2.c1 must: minLength <= maxLength
1101             if(((fFacetsDefined & FACET_MINLENGTH ) != 0 ) && ((fFacetsDefined & FACET_MAXLENGTH) != 0))
1102             {
1103                 if(fMinLength > fMaxLength)
1104                     reportError("minLength-less-than-equal-to-maxLength", new Object[]{Integer.toString(fMinLength), Integer.toString(fMaxLength), fTypeName});
1105             }
1106 
1107             // check 4.3.8.c1 error: maxInclusive + maxExclusive
1108             if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && ((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1109                 reportError( "maxInclusive-maxExclusive", new Object[]{fMaxInclusive, fMaxExclusive, fTypeName});
1110             }
1111 
1112             // check 4.3.9.c1 error: minInclusive + minExclusive
1113             if (((fFacetsDefined & FACET_MINEXCLUSIVE) != 0) && ((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1114                 reportError("minInclusive-minExclusive", new Object[]{fMinInclusive, fMinExclusive, fTypeName});
1115             }
1116 
1117             // check 4.3.7.c1 must: minInclusive <= maxInclusive
1118             if (((fFacetsDefined &  FACET_MAXINCLUSIVE) != 0) && ((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1119                 result = fDVs[fValidationDV].compare(fMinInclusive, fMaxInclusive);
1120                 if (result != -1 && result != 0)
1121                     reportError("minInclusive-less-than-equal-to-maxInclusive", new Object[]{fMinInclusive, fMaxInclusive, fTypeName});
1122             }
1123 
1124             // check 4.3.8.c2 must: minExclusive <= maxExclusive ??? minExclusive < maxExclusive
1125             if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && ((fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
1126                 result = fDVs[fValidationDV].compare(fMinExclusive, fMaxExclusive);
1127                 if (result != -1 && result != 0)
1128                     reportError( "minExclusive-less-than-equal-to-maxExclusive", new Object[]{fMinExclusive, fMaxExclusive, fTypeName});
1129             }
1130 
1131             // check 4.3.9.c2 must: minExclusive < maxInclusive
1132             if (((fFacetsDefined & FACET_MAXINCLUSIVE) != 0) && ((fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
1133                 if (fDVs[fValidationDV].compare(fMinExclusive, fMaxInclusive) != -1)
1134                     reportError( "minExclusive-less-than-maxInclusive", new Object[]{fMinExclusive, fMaxInclusive, fTypeName});
1135             }
1136 
1137             // check 4.3.10.c1 must: minInclusive < maxExclusive
1138             if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && ((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1139                 if (fDVs[fValidationDV].compare(fMinInclusive, fMaxExclusive) != -1)
1140                     reportError( "minInclusive-less-than-maxExclusive", new Object[]{fMinInclusive, fMaxExclusive, fTypeName});
1141             }
1142 
1143             // check 4.3.12.c1 must: fractionDigits <= totalDigits
1144             if (((fFacetsDefined & FACET_FRACTIONDIGITS) != 0) &&
1145                     ((fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
1146                 if (fFractionDigits > fTotalDigits)
1147                     reportError( "fractionDigits-totalDigits", new Object[]{Integer.toString(fFractionDigits), Integer.toString(fTotalDigits), fTypeName});
1148             }
1149 
1150             // step 3: check facets against base
1151             // check 4.3.1.c1 error: length & (fBase.maxLength | fBase.minLength)
1152             if((fFacetsDefined & FACET_LENGTH) != 0 ){
1153                 if ((fBase.fFacetsDefined & FACET_MINLENGTH) != 0 &&
1154                         fLength < fBase.fMinLength) {
1155                     // length, fBase.minLength and fBase.maxLength defined
1156                     reportError("length-minLength-maxLength.1.1", new Object[]{fTypeName, Integer.toString(fLength), Integer.toString(fBase.fMinLength)});
1157                 }
1158                 if ((fBase.fFacetsDefined & FACET_MAXLENGTH) != 0 &&
1159                         fLength > fBase.fMaxLength) {
1160                     // length and fBase.maxLength defined
1161                     reportError("length-minLength-maxLength.2.1", new Object[]{fTypeName, Integer.toString(fLength), Integer.toString(fBase.fMaxLength)});
1162                 }
1163                 if ( (fBase.fFacetsDefined & FACET_LENGTH) != 0 ) {
1164                     // check 4.3.1.c2 error: length != fBase.length
1165                     if ( fLength != fBase.fLength )
1166                         reportError( "length-valid-restriction", new Object[]{Integer.toString(fLength), Integer.toString(fBase.fLength), fTypeName});
1167                 }
1168             }
1169 
1170             // check 4.3.1.c1 error: fBase.length & (maxLength | minLength)
1171             if((fBase.fFacetsDefined & FACET_LENGTH) != 0 || (fFacetsDefined & FACET_LENGTH) != 0){
1172                 if ((fFacetsDefined & FACET_MINLENGTH) != 0){
1173                     if (fBase.fLength < fMinLength) {
1174                         // fBase.length, minLength and maxLength defined
1175                         reportError("length-minLength-maxLength.1.1", new Object[]{fTypeName, Integer.toString(fBase.fLength), Integer.toString(fMinLength)});
1176                     }
1177                     if ((fBase.fFacetsDefined & FACET_MINLENGTH) == 0){
1178                         reportError("length-minLength-maxLength.1.2.a", new Object[]{fTypeName});
1179                     }
1180                     if (fMinLength != fBase.fMinLength){
1181                         reportError("length-minLength-maxLength.1.2.b", new Object[]{fTypeName, Integer.toString(fMinLength), Integer.toString(fBase.fMinLength)});
1182                     }
1183                 }
1184                 if ((fFacetsDefined & FACET_MAXLENGTH) != 0){
1185                     if (fBase.fLength > fMaxLength) {
1186                         // fBase.length, minLength and maxLength defined
1187                         reportError("length-minLength-maxLength.2.1", new Object[]{fTypeName, Integer.toString(fBase.fLength), Integer.toString(fMaxLength)});
1188                     }
1189                     if ((fBase.fFacetsDefined & FACET_MAXLENGTH) == 0){
1190                         reportError("length-minLength-maxLength.2.2.a", new Object[]{fTypeName});
1191                     }
1192                     if (fMaxLength != fBase.fMaxLength){
1193                         reportError("length-minLength-maxLength.2.2.b", new Object[]{fTypeName, Integer.toString(fMaxLength), Integer.toString(fBase.fBase.fMaxLength)});
1194                     }
1195                 }
1196             }
1197 
1198             // check 4.3.2.c1 must: minLength <= fBase.maxLength
1199             if ( ((fFacetsDefined & FACET_MINLENGTH ) != 0 ) ) {
1200                 if ( (fBase.fFacetsDefined & FACET_MAXLENGTH ) != 0 ) {
1201                     if ( fMinLength > fBase.fMaxLength ) {
1202                         reportError("minLength-less-than-equal-to-maxLength", new Object[]{Integer.toString(fMinLength), Integer.toString(fBase.fMaxLength), fTypeName});
1203                     }
1204                 }
1205                 else if ( (fBase.fFacetsDefined & FACET_MINLENGTH) != 0 ) {
1206                     if ( (fBase.fFixedFacet & FACET_MINLENGTH) != 0 && fMinLength != fBase.fMinLength ) {
1207                         reportError( "FixedFacetValue", new Object[]{"minLength", Integer.toString(fMinLength), Integer.toString(fBase.fMinLength), fTypeName});
1208                     }
1209 
1210                     // check 4.3.2.c2 error: minLength < fBase.minLength
1211                     if ( fMinLength < fBase.fMinLength ) {
1212                         reportError( "minLength-valid-restriction", new Object[]{Integer.toString(fMinLength), Integer.toString(fBase.fMinLength), fTypeName});
1213                     }
1214                 }
1215             }
1216 
1217 
1218             // check 4.3.2.c1 must: maxLength < fBase.minLength
1219             if ( ((fFacetsDefined & FACET_MAXLENGTH ) != 0 ) && ((fBase.fFacetsDefined & FACET_MINLENGTH ) != 0 )) {
1220                 if ( fMaxLength < fBase.fMinLength) {
1221                     reportError("minLength-less-than-equal-to-maxLength", new Object[]{Integer.toString(fBase.fMinLength), Integer.toString(fMaxLength)});
1222                 }
1223             }
1224 
1225             // check 4.3.3.c1 error: maxLength > fBase.maxLength
1226             if ( (fFacetsDefined & FACET_MAXLENGTH) != 0 ) {
1227                 if ( (fBase.fFacetsDefined & FACET_MAXLENGTH) != 0 ){
1228                     if(( (fBase.fFixedFacet & FACET_MAXLENGTH) != 0 )&& fMaxLength != fBase.fMaxLength ) {
1229                         reportError( "FixedFacetValue", new Object[]{"maxLength", Integer.toString(fMaxLength), Integer.toString(fBase.fMaxLength), fTypeName});
1230                     }
1231                     if ( fMaxLength > fBase.fMaxLength ) {
1232                         reportError( "maxLength-valid-restriction", new Object[]{Integer.toString(fMaxLength), Integer.toString(fBase.fMaxLength), fTypeName});
1233                     }
1234                 }
1235             }
1236 
1237             /*          // check 4.3.7.c2 error:
1238                          // maxInclusive > fBase.maxInclusive
1239                           // maxInclusive >= fBase.maxExclusive
1240                            // maxInclusive < fBase.minInclusive
1241                             // maxInclusive <= fBase.minExclusive
1242 
1243                              if (((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1244                              if (((fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1245                              result = fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMaxInclusive);
1246                              if ((fBase.fFixedFacet & FACET_MAXINCLUSIVE) != 0 && result != 0) {
1247                              reportError( "FixedFacetValue", new Object[]{"maxInclusive", fMaxInclusive, fBase.fMaxInclusive, fTypeName});
1248                              }
1249                              if (result != -1 && result != 0) {
1250                              reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMaxInclusive, fTypeName});
1251                              }
1252                              }
1253                              if (((fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) &&
1254                              fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMaxExclusive) != -1){
1255                              reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMaxExclusive, fTypeName});
1256                              }
1257 
1258                              if ((( fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1259                              result = fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMinInclusive);
1260                              if (result != 1 && result != 0) {
1261                              reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMinInclusive, fTypeName});
1262                              }
1263                              }
1264 
1265                              if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0) &&
1266                              fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMinExclusive ) != 1)
1267                              reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMinExclusive, fTypeName});
1268                              }
1269 
1270                              // check 4.3.8.c3 error:
1271                               // maxExclusive > fBase.maxExclusive
1272                                // maxExclusive > fBase.maxInclusive
1273                                 // maxExclusive <= fBase.minInclusive
1274                                  // maxExclusive <= fBase.minExclusive
1275                                   if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) {
1276                                   if ((( fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) {
1277                                   result= fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMaxExclusive);
1278                                   if ((fBase.fFixedFacet & FACET_MAXEXCLUSIVE) != 0 &&  result != 0) {
1279                                   reportError( "FixedFacetValue", new Object[]{"maxExclusive", fMaxExclusive, fBase.fMaxExclusive, fTypeName});
1280                                   }
1281                                   if (result != -1 && result != 0) {
1282                                   reportError( "maxExclusive-valid-restriction.1", new Object[]{fMaxExclusive, fBase.fMaxExclusive, fTypeName});
1283                                   }
1284                                   }
1285 
1286                                   if ((( fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1287                                   result= fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMaxInclusive);
1288                                   if (result != -1 && result != 0) {
1289                                   reportError( "maxExclusive-valid-restriction.2", new Object[]{fMaxExclusive, fBase.fMaxInclusive, fTypeName});
1290                                   }
1291                                   }
1292 
1293                                   if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0) &&
1294                                   fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMinExclusive ) != 1)
1295                                   reportError( "maxExclusive-valid-restriction.3", new Object[]{fMaxExclusive, fBase.fMinExclusive, fTypeName});
1296 
1297                                   if ((( fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0) &&
1298                                   fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMinInclusive) != 1)
1299                                   reportError( "maxExclusive-valid-restriction.4", new Object[]{fMaxExclusive, fBase.fMinInclusive, fTypeName});
1300                                   }
1301 
1302                                   // check 4.3.9.c3 error:
1303                                    // minExclusive < fBase.minExclusive
1304                                     // minExclusive > fBase.maxInclusive
1305                                      // minExclusive < fBase.minInclusive
1306                                       // minExclusive >= fBase.maxExclusive
1307                                        if (((fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
1308                                        if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
1309                                        result= fDVs[fValidationDV].compare(fMinExclusive, fBase.fMinExclusive);
1310                                        if ((fBase.fFixedFacet & FACET_MINEXCLUSIVE) != 0 && result != 0) {
1311                                        reportError( "FixedFacetValue", new Object[]{"minExclusive", fMinExclusive, fBase.fMinExclusive, fTypeName});
1312                                        }
1313                                        if (result != 1 && result != 0) {
1314                                        reportError( "minExclusive-valid-restriction.1", new Object[]{fMinExclusive, fBase.fMinExclusive, fTypeName});
1315                                        }
1316                                        }
1317 
1318                                        if ((( fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1319                                        result=fDVs[fValidationDV].compare(fMinExclusive, fBase.fMaxInclusive);
1320 
1321                                        if (result != -1 && result != 0) {
1322                                        reportError( "minExclusive-valid-restriction.2", new Object[]{fMinExclusive, fBase.fMaxInclusive, fTypeName});
1323                                        }
1324                                        }
1325 
1326                                        if ((( fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1327                                        result = fDVs[fValidationDV].compare(fMinExclusive, fBase.fMinInclusive);
1328 
1329                                        if (result != 1 && result != 0) {
1330                                        reportError( "minExclusive-valid-restriction.3", new Object[]{fMinExclusive, fBase.fMinInclusive, fTypeName});
1331                                        }
1332                                        }
1333 
1334                                        if ((( fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) &&
1335                                        fDVs[fValidationDV].compare(fMinExclusive, fBase.fMaxExclusive) != -1)
1336                                        reportError( "minExclusive-valid-restriction.4", new Object[]{fMinExclusive, fBase.fMaxExclusive, fTypeName});
1337                                        }
1338 
1339                                        // check 4.3.10.c2 error:
1340                                         // minInclusive < fBase.minInclusive
1341                                          // minInclusive > fBase.maxInclusive
1342                                           // minInclusive <= fBase.minExclusive
1343                                            // minInclusive >= fBase.maxExclusive
1344                                             if (((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1345                                             if (((fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1346                                             result = fDVs[fValidationDV].compare(fMinInclusive, fBase.fMinInclusive);
1347 
1348                                             if ((fBase.fFixedFacet & FACET_MININCLUSIVE) != 0 && result != 0) {
1349                                             reportError( "FixedFacetValue", new Object[]{"minInclusive", fMinInclusive, fBase.fMinInclusive, fTypeName});
1350                                             }
1351                                             if (result != 1 && result != 0) {
1352                                             reportError( "minInclusive-valid-restriction.1", new Object[]{fMinInclusive, fBase.fMinInclusive, fTypeName});
1353                                             }
1354                                             }
1355                                             if ((( fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1356                                             result=fDVs[fValidationDV].compare(fMinInclusive, fBase.fMaxInclusive);
1357                                             if (result != -1 && result != 0) {
1358                                             reportError( "minInclusive-valid-restriction.2", new Object[]{fMinInclusive, fBase.fMaxInclusive, fTypeName});
1359                                             }
1360                                             }
1361                                             if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0) &&
1362                                             fDVs[fValidationDV].compare(fMinInclusive, fBase.fMinExclusive ) != 1)
1363                                             reportError( "minInclusive-valid-restriction.3", new Object[]{fMinInclusive, fBase.fMinExclusive, fTypeName});
1364                                             if ((( fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) &&
1365                                             fDVs[fValidationDV].compare(fMinInclusive, fBase.fMaxExclusive) != -1)
1366                                             reportError( "minInclusive-valid-restriction.4", new Object[]{fMinInclusive, fBase.fMaxExclusive, fTypeName});
1367                                             }
1368              */
1369             // check 4.3.11.c1 error: totalDigits > fBase.totalDigits
1370             if (((fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
1371                 if ((( fBase.fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
1372                     if ((fBase.fFixedFacet & FACET_TOTALDIGITS) != 0 && fTotalDigits != fBase.fTotalDigits) {
1373                         reportError("FixedFacetValue", new Object[]{"totalDigits", Integer.toString(fTotalDigits), Integer.toString(fBase.fTotalDigits), fTypeName});
1374                     }
1375                     if (fTotalDigits > fBase.fTotalDigits) {
1376                         reportError( "totalDigits-valid-restriction", new Object[]{Integer.toString(fTotalDigits), Integer.toString(fBase.fTotalDigits), fTypeName});
1377                     }
1378                 }
1379             }
1380 
1381             // check 4.3.12.c1 must: fractionDigits <= base.totalDigits
1382             if ((fFacetsDefined & FACET_FRACTIONDIGITS) != 0) {
1383                 if ((fBase.fFacetsDefined & FACET_TOTALDIGITS) != 0) {
1384                     if (fFractionDigits > fBase.fTotalDigits)
1385                         reportError( "fractionDigits-totalDigits", new Object[]{Integer.toString(fFractionDigits), Integer.toString(fTotalDigits), fTypeName});
1386                 }
1387             }
1388 
1389             // check 4.3.12.c2 error: fractionDigits > fBase.fractionDigits
1390             // check fixed value for fractionDigits
1391             if (((fFacetsDefined & FACET_FRACTIONDIGITS) != 0)) {
1392                 if ((( fBase.fFacetsDefined & FACET_FRACTIONDIGITS) != 0)) {
1393                     if (((fBase.fFixedFacet & FACET_FRACTIONDIGITS) != 0 && fFractionDigits != fBase.fFractionDigits) ||
1394                             (fValidationDV == DV_INTEGER && fFractionDigits != 0)) {
1395                         reportError("FixedFacetValue", new Object[]{"fractionDigits", Integer.toString(fFractionDigits), Integer.toString(fBase.fFractionDigits), fTypeName});
1396                     }
1397                     if (fFractionDigits > fBase.fFractionDigits) {
1398                         reportError( "fractionDigits-valid-restriction", new Object[]{Integer.toString(fFractionDigits), Integer.toString(fBase.fFractionDigits), fTypeName});
1399                     }
1400                 }
1401                 else if (fValidationDV == DV_INTEGER && fFractionDigits != 0) {
1402                     reportError("FixedFacetValue", new Object[]{"fractionDigits", Integer.toString(fFractionDigits), "0", fTypeName});
1403                 }
1404             }
1405 
1406             // check 4.3.6.c1 error:
1407             // (whiteSpace = preserve || whiteSpace = replace) && fBase.whiteSpace = collapese or
1408             // whiteSpace = preserve && fBase.whiteSpace = replace
1409 
1410             if ( (fFacetsDefined & FACET_WHITESPACE) != 0 && (fBase.fFacetsDefined & FACET_WHITESPACE) != 0 ){
1411                 if ( (fBase.fFixedFacet & FACET_WHITESPACE) != 0 &&  fWhiteSpace != fBase.fWhiteSpace ) {
1412                     reportError( "FixedFacetValue", new Object[]{"whiteSpace", whiteSpaceValue(fWhiteSpace), whiteSpaceValue(fBase.fWhiteSpace), fTypeName});
1413                 }
1414 
1415                 if ( fWhiteSpace == WS_PRESERVE &&  fBase.fWhiteSpace == WS_COLLAPSE ){
1416                     reportError( "whiteSpace-valid-restriction.1", new Object[]{fTypeName, "preserve"});
1417                 }
1418                 if ( fWhiteSpace == WS_REPLACE &&  fBase.fWhiteSpace == WS_COLLAPSE ){
1419                     reportError( "whiteSpace-valid-restriction.1", new Object[]{fTypeName, "replace"});
1420                 }
1421                 if ( fWhiteSpace == WS_PRESERVE &&  fBase.fWhiteSpace == WS_REPLACE ){
1422                     reportError( "whiteSpace-valid-restriction.2", new Object[]{fTypeName});
1423                 }
1424             }
1425         }//fFacetsDefined != null
1426 
1427         // step 4: inherit other facets from base (including fTokeyType)
1428 
1429         // inherit length
1430         if ( (fFacetsDefined & FACET_LENGTH) == 0  && (fBase.fFacetsDefined & FACET_LENGTH) != 0 ) {
1431             fFacetsDefined |= FACET_LENGTH;
1432             fLength = fBase.fLength;
1433             lengthAnnotation = fBase.lengthAnnotation;
1434         }
1435         // inherit minLength
1436         if ( (fFacetsDefined & FACET_MINLENGTH) == 0 && (fBase.fFacetsDefined & FACET_MINLENGTH) != 0 ) {
1437             fFacetsDefined |= FACET_MINLENGTH;
1438             fMinLength = fBase.fMinLength;
1439             minLengthAnnotation = fBase.minLengthAnnotation;
1440         }
1441         // inherit maxLength
1442         if ((fFacetsDefined & FACET_MAXLENGTH) == 0 &&  (fBase.fFacetsDefined & FACET_MAXLENGTH) != 0 ) {
1443             fFacetsDefined |= FACET_MAXLENGTH;
1444             fMaxLength = fBase.fMaxLength;
1445             maxLengthAnnotation = fBase.maxLengthAnnotation;
1446         }
1447         // inherit pattern
1448         if ( (fBase.fFacetsDefined & FACET_PATTERN) != 0 ) {
1449             if ((fFacetsDefined & FACET_PATTERN) == 0) {
1450                 fFacetsDefined |= FACET_PATTERN;
1451                 fPattern = fBase.fPattern;
1452                 fPatternStr = fBase.fPatternStr;
1453                 patternAnnotations = fBase.patternAnnotations;
1454             }
1455             else {
1456                 for (int i = fBase.fPattern.size()-1; i >= 0; --i) {
1457                     fPattern.addElement(fBase.fPattern.elementAt(i));
1458                     fPatternStr.addElement(fBase.fPatternStr.elementAt(i));
1459                 }
1460                 if (fBase.patternAnnotations != null) {
1461                     if (patternAnnotations != null) {
1462                         for (int i = fBase.patternAnnotations.getLength()-1; i >= 0; --i) {
1463                             patternAnnotations.addXSObject(fBase.patternAnnotations.item(i));
1464                         }
1465                     }
1466                     else {
1467                         patternAnnotations = fBase.patternAnnotations;
1468                     }
1469                 }
1470             }
1471         }
1472         // inherit whiteSpace
1473         if ( (fFacetsDefined & FACET_WHITESPACE) == 0 &&  (fBase.fFacetsDefined & FACET_WHITESPACE) != 0 ) {
1474             fFacetsDefined |= FACET_WHITESPACE;
1475             fWhiteSpace = fBase.fWhiteSpace;
1476             whiteSpaceAnnotation = fBase.whiteSpaceAnnotation;
1477         }
1478         // inherit enumeration
1479         if ((fFacetsDefined & FACET_ENUMERATION) == 0 && (fBase.fFacetsDefined & FACET_ENUMERATION) != 0) {
1480             fFacetsDefined |= FACET_ENUMERATION;
1481             fEnumeration = fBase.fEnumeration;
1482             enumerationAnnotations = fBase.enumerationAnnotations;
1483         }
1484         // inherit maxExclusive
1485         if ((( fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) &&
1486                 !((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && !((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1487             fFacetsDefined |= FACET_MAXEXCLUSIVE;
1488             fMaxExclusive = fBase.fMaxExclusive;
1489             maxExclusiveAnnotation = fBase.maxExclusiveAnnotation;
1490         }
1491         // inherit maxInclusive
1492         if ((( fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0) &&
1493                 !((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && !((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
1494             fFacetsDefined |= FACET_MAXINCLUSIVE;
1495             fMaxInclusive = fBase.fMaxInclusive;
1496             maxInclusiveAnnotation = fBase.maxInclusiveAnnotation;
1497         }
1498         // inherit minExclusive
1499         if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0) &&
1500                 !((fFacetsDefined & FACET_MINEXCLUSIVE) != 0) && !((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1501             fFacetsDefined |= FACET_MINEXCLUSIVE;
1502             fMinExclusive = fBase.fMinExclusive;
1503             minExclusiveAnnotation = fBase.minExclusiveAnnotation;
1504         }
1505         // inherit minExclusive
1506         if ((( fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0) &&
1507                 !((fFacetsDefined & FACET_MINEXCLUSIVE) != 0) && !((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
1508             fFacetsDefined |= FACET_MININCLUSIVE;
1509             fMinInclusive = fBase.fMinInclusive;
1510             minInclusiveAnnotation = fBase.minInclusiveAnnotation;
1511         }
1512         // inherit totalDigits
1513         if ((( fBase.fFacetsDefined & FACET_TOTALDIGITS) != 0) &&
1514                 !((fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
1515             fFacetsDefined |= FACET_TOTALDIGITS;
1516             fTotalDigits = fBase.fTotalDigits;
1517             totalDigitsAnnotation = fBase.totalDigitsAnnotation;
1518         }
1519         // inherit fractionDigits
1520         if ((( fBase.fFacetsDefined & FACET_FRACTIONDIGITS) != 0)
1521                 && !((fFacetsDefined & FACET_FRACTIONDIGITS) != 0)) {
1522             fFacetsDefined |= FACET_FRACTIONDIGITS;
1523             fFractionDigits = fBase.fFractionDigits;
1524             fractionDigitsAnnotation = fBase.fractionDigitsAnnotation;
1525         }
1526         //inherit tokeytype
1527         if ((fPatternType == SPECIAL_PATTERN_NONE ) && (fBase.fPatternType != SPECIAL_PATTERN_NONE)) {
1528             fPatternType = fBase.fPatternType ;
1529         }
1530 
1531         // step 5: mark fixed values
1532         fFixedFacet |= fBase.fFixedFacet;
1533 
1534         //step 6: setting fundamental facets
1535         calcFundamentalFacets();
1536 
1537     } //applyFacets()
1538 
1539     /**
1540      * validate a value, and return the compiled form
1541      */
1542     public Object validate(String content, ValidationContext context, ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {
1543 
1544         if (context == null)
1545             context = fEmptyContext;
1546 
1547         if (validatedInfo == null)
1548             validatedInfo = new ValidatedInfo();
1549         else
1550             validatedInfo.memberType = null;
1551 
1552         // first normalize string value, and convert it to actual value
1553         boolean needNormalize = context==null||context.needToNormalize();
1554         Object ob = getActualValue(content, context, validatedInfo, needNormalize);
1555 
1556         validate(context, validatedInfo);
1557 
1558         return ob;
1559 
1560     }
1561 
1562     protected ValidatedInfo getActualEnumValue(String lexical, ValidationContext ctx, ValidatedInfo info)
1563     throws InvalidDatatypeValueException {
1564         return fBase.validateWithInfo(lexical, ctx, info);
1565     }
1566 
1567     /**
1568      * validate a value, and return the compiled form
1569      */
1570     public ValidatedInfo validateWithInfo(String content, ValidationContext context, ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {
1571 
1572         if (context == null)
1573             context = fEmptyContext;
1574 
1575         if (validatedInfo == null)
1576             validatedInfo = new ValidatedInfo();
1577         else
1578             validatedInfo.memberType = null;
1579 
1580         // first normalize string value, and convert it to actual value
1581         boolean needNormalize = context==null||context.needToNormalize();
1582         getActualValue(content, context, validatedInfo, needNormalize);
1583 
1584         validate(context, validatedInfo);
1585 
1586         return validatedInfo;
1587 
1588     }
1589 
1590     /**
1591      * validate a value, and return the compiled form
1592      */
1593     public Object validate(Object content, ValidationContext context, ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {
1594 
1595         if (context == null)
1596             context = fEmptyContext;
1597 
1598         if (validatedInfo == null)
1599             validatedInfo = new ValidatedInfo();
1600         else
1601             validatedInfo.memberType = null;
1602 
1603         // first normalize string value, and convert it to actual value
1604         boolean needNormalize = context==null||context.needToNormalize();
1605         Object ob = getActualValue(content, context, validatedInfo, needNormalize);
1606 
1607         validate(context, validatedInfo);
1608 
1609         return ob;
1610 
1611     }
1612 
1613     /**
1614      * validate an actual value against this DV
1615      *
1616      * @param context       the validation context
1617      * @param validatedInfo used to provide the actual value and member types
1618      */
1619     public void validate(ValidationContext context, ValidatedInfo validatedInfo)
1620         throws InvalidDatatypeValueException {
1621 
1622         if (context == null)
1623             context = fEmptyContext;
1624 
1625         // then validate the actual value against the facets
1626         if (context.needFacetChecking() &&
1627                 (fFacetsDefined != 0 && fFacetsDefined != FACET_WHITESPACE)) {
1628             checkFacets(validatedInfo);
1629         }
1630 
1631         // now check extra rules: for ID/IDREF/ENTITY
1632         if (context.needExtraChecking()) {
1633             checkExtraRules(context, validatedInfo);
1634         }
1635 
1636     }
1637 
1638     private void checkFacets(ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {
1639 
1640         Object ob = validatedInfo.actualValue;
1641         String content = validatedInfo.normalizedValue;
1642         short type = validatedInfo.actualValueType;
1643         ShortList itemType = validatedInfo.itemValueTypes;
1644 
1645         // For QName and NOTATION types, we don't check length facets
1646         if (fValidationDV != DV_QNAME && fValidationDV != DV_NOTATION) {
1647             int length = fDVs[fValidationDV].getDataLength(ob);
1648 
1649             // maxLength
1650             if ( (fFacetsDefined & FACET_MAXLENGTH) != 0 ) {
1651                 if ( length > fMaxLength ) {
1652                     throw new InvalidDatatypeValueException("cvc-maxLength-valid",
1653                             new Object[]{content, Integer.toString(length), Integer.toString(fMaxLength), fTypeName});
1654                 }
1655             }
1656 
1657             //minLength
1658             if ( (fFacetsDefined & FACET_MINLENGTH) != 0 ) {
1659                 if ( length < fMinLength ) {
1660                     throw new InvalidDatatypeValueException("cvc-minLength-valid",
1661                             new Object[]{content, Integer.toString(length), Integer.toString(fMinLength), fTypeName});
1662                 }
1663             }
1664 
1665             //length
1666             if ( (fFacetsDefined & FACET_LENGTH) != 0 ) {
1667                 if ( length != fLength ) {
1668                     throw new InvalidDatatypeValueException("cvc-length-valid",
1669                             new Object[]{content, Integer.toString(length), Integer.toString(fLength), fTypeName});
1670                 }
1671             }
1672         }
1673 
1674         //enumeration
1675         if ( ((fFacetsDefined & FACET_ENUMERATION) != 0 ) ) {
1676             boolean present = false;
1677             final int enumSize = fEnumeration.size();
1678             final short primitiveType1 = convertToPrimitiveKind(type);
1679             for (int i = 0; i < enumSize; i++) {
1680                 final short primitiveType2 = convertToPrimitiveKind(fEnumerationType[i]);
1681                 if ((primitiveType1 == primitiveType2 ||
1682                         primitiveType1 == XSConstants.ANYSIMPLETYPE_DT && primitiveType2 == XSConstants.STRING_DT ||
1683                         primitiveType1 == XSConstants.STRING_DT && primitiveType2 == XSConstants.ANYSIMPLETYPE_DT)
1684                         && fEnumeration.elementAt(i).equals(ob)) {
1685                     if (primitiveType1 == XSConstants.LIST_DT || primitiveType1 == XSConstants.LISTOFUNION_DT) {
1686                         ShortList enumItemType = fEnumerationItemType[i];
1687                         final int typeList1Length = itemType != null ? itemType.getLength() : 0;
1688                         final int typeList2Length = enumItemType != null ? enumItemType.getLength() : 0;
1689                         if (typeList1Length == typeList2Length) {
1690                             int j;
1691                             for (j = 0; j < typeList1Length; ++j) {
1692                                 final short primitiveItem1 = convertToPrimitiveKind(itemType.item(j));
1693                                 final short primitiveItem2 = convertToPrimitiveKind(enumItemType.item(j));
1694                                 if (primitiveItem1 != primitiveItem2) {
1695                                     if (primitiveItem1 == XSConstants.ANYSIMPLETYPE_DT && primitiveItem2 == XSConstants.STRING_DT ||
1696                                             primitiveItem1 == XSConstants.STRING_DT && primitiveItem2 == XSConstants.ANYSIMPLETYPE_DT) {
1697                                         continue;
1698                                     }
1699                                     break;
1700                                 }
1701                             }
1702                             if (j == typeList1Length) {
1703                                 present = true;
1704                                 break;
1705                             }
1706                         }
1707                     }
1708                     else {
1709                         present = true;
1710                         break;
1711                     }
1712                 }
1713             }
1714             if(!present){
1715                 throw new InvalidDatatypeValueException("cvc-enumeration-valid",
1716                         new Object [] {content, fEnumeration.toString()});
1717             }
1718         }
1719 
1720         //fractionDigits
1721         if ((fFacetsDefined & FACET_FRACTIONDIGITS) != 0) {
1722             int scale = fDVs[fValidationDV].getFractionDigits(ob);
1723             if (scale > fFractionDigits) {
1724                 throw new InvalidDatatypeValueException("cvc-fractionDigits-valid",
1725                         new Object[] {content, Integer.toString(scale), Integer.toString(fFractionDigits)});
1726             }
1727         }
1728 
1729         //totalDigits
1730         if ((fFacetsDefined & FACET_TOTALDIGITS)!=0) {
1731             int totalDigits = fDVs[fValidationDV].getTotalDigits(ob);
1732             if (totalDigits > fTotalDigits) {
1733                 throw new InvalidDatatypeValueException("cvc-totalDigits-valid",
1734                         new Object[] {content, Integer.toString(totalDigits), Integer.toString(fTotalDigits)});
1735             }
1736         }
1737 
1738         int compare;
1739 
1740         //maxinclusive
1741         if ( (fFacetsDefined & FACET_MAXINCLUSIVE) != 0 ) {
1742             compare = fDVs[fValidationDV].compare(ob, fMaxInclusive);
1743             if (compare != -1 && compare != 0) {
1744                 throw new InvalidDatatypeValueException("cvc-maxInclusive-valid",
1745                         new Object[] {content, fMaxInclusive, fTypeName});
1746             }
1747         }
1748 
1749         //maxExclusive
1750         if ( (fFacetsDefined & FACET_MAXEXCLUSIVE) != 0 ) {
1751             compare = fDVs[fValidationDV].compare(ob, fMaxExclusive );
1752             if (compare != -1) {
1753                 throw new InvalidDatatypeValueException("cvc-maxExclusive-valid",
1754                         new Object[] {content, fMaxExclusive, fTypeName});
1755             }
1756         }
1757 
1758         //minInclusive
1759         if ( (fFacetsDefined & FACET_MININCLUSIVE) != 0 ) {
1760             compare = fDVs[fValidationDV].compare(ob, fMinInclusive);
1761             if (compare != 1 && compare != 0) {
1762                 throw new InvalidDatatypeValueException("cvc-minInclusive-valid",
1763                         new Object[] {content, fMinInclusive, fTypeName});
1764             }
1765         }
1766 
1767         //minExclusive
1768         if ( (fFacetsDefined & FACET_MINEXCLUSIVE) != 0 ) {
1769             compare = fDVs[fValidationDV].compare(ob, fMinExclusive);
1770             if (compare != 1) {
1771                 throw new InvalidDatatypeValueException("cvc-minExclusive-valid",
1772                         new Object[] {content, fMinExclusive, fTypeName});
1773             }
1774         }
1775 
1776     }
1777 
1778     private void checkExtraRules(ValidationContext context, ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {
1779 
1780         Object ob = validatedInfo.actualValue;
1781 
1782         if (fVariety == VARIETY_ATOMIC) {
1783 
1784             fDVs[fValidationDV].checkExtraRules(ob, context);
1785 
1786         } else if (fVariety == VARIETY_LIST) {
1787 
1788             ListDV.ListData values = (ListDV.ListData)ob;
1789             XSSimpleType memberType = validatedInfo.memberType;
1790             int len = values.getLength();
1791             try {
1792                 if (fItemType.fVariety == VARIETY_UNION) {
1793                     XSSimpleTypeDecl[] memberTypes = (XSSimpleTypeDecl[])validatedInfo.memberTypes;
1794                     for (int i = len-1; i >= 0; i--) {
1795                         validatedInfo.actualValue = values.item(i);
1796                         validatedInfo.memberType = memberTypes[i];
1797                         fItemType.checkExtraRules(context, validatedInfo);
1798                     }
1799                 } else { // (fVariety == VARIETY_ATOMIC)
1800                     for (int i = len-1; i >= 0; i--) {
1801                         validatedInfo.actualValue = values.item(i);
1802                         fItemType.checkExtraRules(context, validatedInfo);
1803                     }
1804                 }
1805             }
1806             finally {
1807                 validatedInfo.actualValue = values;
1808                 validatedInfo.memberType = memberType;
1809             }
1810 
1811         } else { // (fVariety == VARIETY_UNION)
1812 
1813             ((XSSimpleTypeDecl)validatedInfo.memberType).checkExtraRules(context, validatedInfo);
1814 
1815         }
1816 
1817     }// checkExtraRules()
1818 
1819     //we can still return object for internal use.
1820     private Object getActualValue(Object content, ValidationContext context,
1821             ValidatedInfo validatedInfo, boolean needNormalize)
1822     throws InvalidDatatypeValueException{
1823 
1824         String nvalue;
1825         if (needNormalize) {
1826             nvalue = normalize(content, fWhiteSpace);
1827         } else {
1828             nvalue = content.toString();
1829         }
1830         if ( (fFacetsDefined & FACET_PATTERN ) != 0 ) {
1831             if (fPattern.size()==0 && nvalue.length()>0) {
1832                         throw new InvalidDatatypeValueException("cvc-pattern-valid",
1833                                 new Object[]{content,
1834                                 "(empty string)",
1835                                 fTypeName});
1836             }
1837             RegularExpression regex;
1838             for (int idx = fPattern.size()-1; idx >= 0; idx--) {
1839                 regex = (RegularExpression)fPattern.elementAt(idx);
1840                 if (!regex.matches(nvalue)){
1841                     throw new InvalidDatatypeValueException("cvc-pattern-valid",
1842                             new Object[]{content,
1843                             fPatternStr.elementAt(idx),
1844                             fTypeName});
1845                 }
1846             }
1847         }
1848 
1849         if (fVariety == VARIETY_ATOMIC) {
1850 
1851             // validate special kinds of token, in place of old pattern matching
1852             if (fPatternType != SPECIAL_PATTERN_NONE) {
1853 
1854                 boolean seenErr = false;
1855                 if (fPatternType == SPECIAL_PATTERN_NMTOKEN) {
1856                     // PATTERN "\\c+"
1857                     seenErr = !XMLChar.isValidNmtoken(nvalue);
1858                 }
1859                 else if (fPatternType == SPECIAL_PATTERN_NAME) {
1860                     // PATTERN "\\i\\c*"
1861                     seenErr = !XMLChar.isValidName(nvalue);
1862                 }
1863                 else if (fPatternType == SPECIAL_PATTERN_NCNAME) {
1864                     // PATTERN "[\\i-[:]][\\c-[:]]*"
1865                     seenErr = !XMLChar.isValidNCName(nvalue);
1866                 }
1867                 if (seenErr) {
1868                     throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1",
1869                             new Object[]{nvalue, SPECIAL_PATTERN_STRING[fPatternType]});
1870                 }
1871             }
1872 
1873             validatedInfo.normalizedValue = nvalue;
1874             Object avalue = fDVs[fValidationDV].getActualValue(nvalue, context);
1875             validatedInfo.actualValue = avalue;
1876             validatedInfo.actualValueType = fBuiltInKind;
1877 
1878             return avalue;
1879 
1880         } else if (fVariety == VARIETY_LIST) {
1881 
1882             StringTokenizer parsedList = new StringTokenizer(nvalue, " ");
1883             int countOfTokens = parsedList.countTokens() ;
1884             Object[] avalue = new Object[countOfTokens];
1885             boolean isUnion = fItemType.getVariety() == VARIETY_UNION;
1886             short[] itemTypes = new short[isUnion ? countOfTokens : 1];
1887             if (!isUnion)
1888                 itemTypes[0] = fItemType.fBuiltInKind;
1889             XSSimpleTypeDecl[] memberTypes = new XSSimpleTypeDecl[countOfTokens];
1890             for(int i = 0 ; i < countOfTokens ; i ++){
1891                 // we can't call fItemType.validate(), otherwise checkExtraRules()
1892                 // will be called twice: once in fItemType.validate, once in
1893                 // validate method of this type.
1894                 // so we take two steps to get the actual value:
1895                 // 1. fItemType.getActualValue()
1896                 // 2. fItemType.chekcFacets()
1897                 avalue[i] = fItemType.getActualValue(parsedList.nextToken(), context, validatedInfo, false);
1898                 if (context.needFacetChecking() &&
1899                         (fItemType.fFacetsDefined != 0 && fItemType.fFacetsDefined != FACET_WHITESPACE)) {
1900                     fItemType.checkFacets(validatedInfo);
1901                 }
1902                 memberTypes[i] = (XSSimpleTypeDecl)validatedInfo.memberType;
1903                 if (isUnion)
1904                     itemTypes[i] = memberTypes[i].fBuiltInKind;
1905             }
1906 
1907             ListDV.ListData v = new ListDV.ListData(avalue);
1908             validatedInfo.actualValue = v;
1909             validatedInfo.actualValueType = isUnion ? XSConstants.LISTOFUNION_DT : XSConstants.LIST_DT;
1910             validatedInfo.memberType = null;
1911             validatedInfo.memberTypes = memberTypes;
1912             validatedInfo.itemValueTypes = new ShortListImpl(itemTypes, itemTypes.length);
1913             validatedInfo.normalizedValue = nvalue;
1914 
1915             return v;
1916 
1917         } else { // (fVariety == VARIETY_UNION)
1918             final Object _content = (fMemberTypes.length > 1 && content != null) ? content.toString() : content;
1919             for (int i = 0; i < fMemberTypes.length; i++) {
1920                 try {
1921                     // we can't call fMemberType[i].validate(), otherwise checkExtraRules()
1922                     // will be called twice: once in fMemberType[i].validate, once in
1923                     // validate method of this type.
1924                     // so we take two steps to get the actual value:
1925                     // 1. fMemberType[i].getActualValue()
1926                     // 2. fMemberType[i].chekcFacets()
1927                     Object aValue = fMemberTypes[i].getActualValue(_content, context, validatedInfo, true);
1928                     if (context.needFacetChecking() &&
1929                             (fMemberTypes[i].fFacetsDefined != 0 && fMemberTypes[i].fFacetsDefined != FACET_WHITESPACE)) {
1930                         fMemberTypes[i].checkFacets(validatedInfo);
1931                     }
1932                     validatedInfo.memberType = fMemberTypes[i];
1933                     return aValue;
1934                 } catch(InvalidDatatypeValueException invalidValue) {
1935                 }
1936             }
1937             StringBuffer typesBuffer = new StringBuffer();
1938             XSSimpleTypeDecl decl;
1939             for(int i = 0;i < fMemberTypes.length; i++) {
1940                 if(i != 0)
1941                     typesBuffer.append(" | ");
1942                 decl = fMemberTypes[i];
1943                 if(decl.fTargetNamespace != null) {
1944                     typesBuffer.append('{');
1945                     typesBuffer.append(decl.fTargetNamespace);
1946                     typesBuffer.append('}');
1947                 }
1948                 typesBuffer.append(decl.fTypeName);
1949                 if(decl.fEnumeration != null) {
1950                     Vector v = decl.fEnumeration;
1951                     typesBuffer.append(" : [");
1952                     for(int j = 0;j < v.size(); j++) {
1953                         if(j != 0)
1954                             typesBuffer.append(',');
1955                         typesBuffer.append(v.elementAt(j));
1956                     }
1957                     typesBuffer.append(']');
1958                 }
1959             }
1960             throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3",
1961                     new Object[]{content, fTypeName, typesBuffer.toString()});
1962         }
1963 
1964     }//getActualValue()
1965 
1966     public boolean isEqual(Object value1, Object value2) {
1967         if (value1 == null) {
1968             return false;
1969         }
1970         return value1.equals(value2);
1971     }//isEqual()
1972 
1973     // determine whether the two values are identical
1974     public boolean isIdentical (Object value1, Object value2) {
1975         if (value1 == null) {
1976             return false;
1977         }
1978         return fDVs[fValidationDV].isIdentical(value1, value2);
1979     }//isIdentical()
1980 
1981     // normalize the string according to the whiteSpace facet
1982     public static String normalize(String content, short ws) {
1983         int len = content == null ? 0 : content.length();
1984         if (len == 0 || ws == WS_PRESERVE)
1985             return content;
1986 
1987         StringBuffer sb = new StringBuffer();
1988         if (ws == WS_REPLACE) {
1989             char ch;
1990             // when it's replace, just replace #x9, #xa, #xd by #x20
1991             for (int i = 0; i < len; i++) {
1992                 ch = content.charAt(i);
1993                 if (ch != 0x9 && ch != 0xa && ch != 0xd)
1994                     sb.append(ch);
1995                 else
1996                     sb.append((char)0x20);
1997             }
1998         } else {
1999             char ch;
2000             int i;
2001             boolean isLeading = true;
2002             // when it's collapse
2003             for (i = 0; i < len; i++) {
2004                 ch = content.charAt(i);
2005                 // append real characters, so we passed leading ws
2006                 if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) {
2007                     sb.append(ch);
2008                     isLeading = false;
2009                 }
2010                 else {
2011                     // for whitespaces, we skip all following ws
2012                     for (; i < len-1; i++) {
2013                         ch = content.charAt(i+1);
2014                         if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20)
2015                             break;
2016                     }
2017                     // if it's not a leading or tailing ws, then append a space
2018                     if (i < len - 1 && !isLeading)
2019                         sb.append((char)0x20);
2020                 }
2021             }
2022         }
2023 
2024         return sb.toString();
2025     }
2026 
2027     // normalize the string according to the whiteSpace facet
2028     protected String normalize(Object content, short ws) {
2029         if (content == null)
2030             return null;
2031 
2032         // If pattern is not defined, we can skip some of the normalization.
2033         // Otherwise we have to normalize the data for correct result of
2034         // pattern validation.
2035         if ( (fFacetsDefined & FACET_PATTERN ) == 0 ) {
2036             short norm_type = fDVNormalizeType[fValidationDV];
2037             if (norm_type == NORMALIZE_NONE) {
2038                 return content.toString();
2039             }
2040             else if (norm_type == NORMALIZE_TRIM) {
2041                 return XMLChar.trim(content.toString());
2042             }
2043         }
2044 
2045         if (!(content instanceof StringBuffer)) {
2046             String strContent = content.toString();
2047             return normalize(strContent, ws);
2048         }
2049 
2050         StringBuffer sb = (StringBuffer)content;
2051         int len = sb.length();
2052         if (len == 0)
2053             return "";
2054         if (ws == WS_PRESERVE)
2055             return sb.toString();
2056 
2057         if (ws == WS_REPLACE) {
2058             char ch;
2059             // when it's replace, just replace #x9, #xa, #xd by #x20
2060             for (int i = 0; i < len; i++) {
2061                 ch = sb.charAt(i);
2062                 if (ch == 0x9 || ch == 0xa || ch == 0xd)
2063                     sb.setCharAt(i, (char)0x20);
2064             }
2065         } else {
2066             char ch;
2067             int i, j = 0;
2068             boolean isLeading = true;
2069             // when it's collapse
2070             for (i = 0; i < len; i++) {
2071                 ch = sb.charAt(i);
2072                 // append real characters, so we passed leading ws
2073                 if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) {
2074                     sb.setCharAt(j++, ch);
2075                     isLeading = false;
2076                 }
2077                 else {
2078                     // for whitespaces, we skip all following ws
2079                     for (; i < len-1; i++) {
2080                         ch = sb.charAt(i+1);
2081                         if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20)
2082                             break;
2083                     }
2084                     // if it's not a leading or tailing ws, then append a space
2085                     if (i < len - 1 && !isLeading)
2086                         sb.setCharAt(j++, (char)0x20);
2087                 }
2088             }
2089             sb.setLength(j);
2090         }
2091 
2092         return sb.toString();
2093     }
2094 
2095     void reportError(String key, Object[] args) throws InvalidDatatypeFacetException {
2096         throw new InvalidDatatypeFacetException(key, args);
2097     }
2098 
2099 
2100     private String whiteSpaceValue(short ws){
2101         return WS_FACET_STRING[ws];
2102     }
2103 
2104     /**
2105      *  Fundamental Facet: ordered.
2106      */
2107     public short getOrdered() {
2108         return fOrdered;
2109     }
2110 
2111     /**
2112      * Fundamental Facet: bounded.
2113      */
2114     public boolean getBounded(){
2115         return fBounded;
2116     }
2117 
2118     /**
2119      * Fundamental Facet: cardinality.
2120      */
2121     public boolean getFinite(){
2122         return fFinite;
2123     }
2124 
2125     /**
2126      * Fundamental Facet: numeric.
2127      */
2128     public boolean getNumeric(){
2129         return fNumeric;
2130     }
2131 
2132     /**
2133      * Convenience method. [Facets]: check whether a facet is defined on this
2134      * type.
2135      * @param facetName  The name of the facet.
2136      * @return  True if the facet is defined, false otherwise.
2137      */
2138     public boolean isDefinedFacet(short facetName) {
2139         if (fValidationDV == DV_ANYSIMPLETYPE ||
2140             fValidationDV == DV_ANYATOMICTYPE) {
2141             return false;
2142         }
2143         if ((fFacetsDefined & facetName) != 0) {
2144             return true;
2145         }
2146         if (fPatternType != SPECIAL_PATTERN_NONE) {
2147             return facetName == FACET_PATTERN;
2148         }
2149         if (fValidationDV == DV_INTEGER) {
2150             return facetName == FACET_PATTERN || facetName == FACET_FRACTIONDIGITS;
2151         }
2152         return false;
2153     }
2154 
2155     /**
2156      * [facets]: all facets defined on this type. The value is a bit
2157      * combination of FACET_XXX constants of all defined facets.
2158      */
2159     public short getDefinedFacets() {
2160         if (fValidationDV == DV_ANYSIMPLETYPE ||
2161             fValidationDV == DV_ANYATOMICTYPE) {
2162             return FACET_NONE;
2163         }
2164         if (fPatternType != SPECIAL_PATTERN_NONE) {
2165             return (short)(fFacetsDefined | FACET_PATTERN);
2166         }
2167         if (fValidationDV == DV_INTEGER) {
2168             return (short)(fFacetsDefined | FACET_PATTERN | FACET_FRACTIONDIGITS);
2169         }
2170         return fFacetsDefined;
2171     }
2172 
2173     /**
2174      * Convenience method. [Facets]: check whether a facet is defined and
2175      * fixed on this type.
2176      * @param facetName  The name of the facet.
2177      * @return  True if the facet is fixed, false otherwise.
2178      */
2179     public boolean isFixedFacet(short facetName) {
2180         if ((fFixedFacet & facetName) != 0)
2181             return true;
2182         if (fValidationDV == DV_INTEGER)
2183             return facetName == FACET_FRACTIONDIGITS;
2184         return false;
2185     }
2186 
2187     /**
2188      * [facets]: all defined facets for this type which are fixed.
2189      */
2190     public short getFixedFacets() {
2191         if (fValidationDV == DV_INTEGER)
2192             return (short)(fFixedFacet | FACET_FRACTIONDIGITS);
2193         return fFixedFacet;
2194     }
2195 
2196     /**
2197      * Convenience method. Returns a value of a single constraining facet for
2198      * this simple type definition. This method must not be used to retrieve
2199      * values for <code>enumeration</code> and <code>pattern</code> facets.
2200      * @param facetName The name of the facet, i.e.
2201      *   <code>FACET_LENGTH, FACET_TOTALDIGITS </code> (see
2202      *   <code>XSConstants</code>). To retrieve the value for a pattern or
2203      *   an enumeration, see <code>enumeration</code> and
2204      *   <code>pattern</code>.
2205      * @return A value of the facet specified in <code>facetName</code> for
2206      *   this simple type definition or <code>null</code>.
2207      */
2208     public String getLexicalFacetValue(short facetName) {
2209         switch (facetName) {
2210             case FACET_LENGTH:
2211                 return (fLength == -1)?null:Integer.toString(fLength);
2212             case FACET_MINLENGTH:
2213                 return (fMinLength == -1)?null:Integer.toString(fMinLength);
2214             case FACET_MAXLENGTH:
2215                 return (fMaxLength == -1)?null:Integer.toString(fMaxLength);
2216             case FACET_WHITESPACE:
2217                 if (fValidationDV == DV_ANYSIMPLETYPE ||
2218                     fValidationDV == DV_ANYATOMICTYPE) {
2219                     return null;
2220                 }
2221                 return WS_FACET_STRING[fWhiteSpace];
2222             case FACET_MAXINCLUSIVE:
2223                 return (fMaxInclusive == null)?null:fMaxInclusive.toString();
2224             case FACET_MAXEXCLUSIVE:
2225                 return (fMaxExclusive == null)?null:fMaxExclusive.toString();
2226             case FACET_MINEXCLUSIVE:
2227                 return (fMinExclusive == null)?null:fMinExclusive.toString();
2228             case FACET_MININCLUSIVE:
2229                 return (fMinInclusive == null)?null:fMinInclusive.toString();
2230             case FACET_TOTALDIGITS:
2231                 return (fTotalDigits == -1)?null:Integer.toString(fTotalDigits);
2232             case FACET_FRACTIONDIGITS:
2233                 if (fValidationDV == DV_INTEGER) {
2234                     return "0";
2235                 }
2236                 return (fFractionDigits == -1)?null:Integer.toString(fFractionDigits);
2237         }
2238         return null;
2239     }
2240 
2241     /**
2242      * A list of enumeration values if it exists, otherwise an empty
2243      * <code>StringList</code>.
2244      */
2245     public StringList getLexicalEnumeration() {
2246         if (fLexicalEnumeration == null){
2247             if (fEnumeration == null)
2248                 return StringListImpl.EMPTY_LIST;
2249             int size = fEnumeration.size();
2250             String[] strs = new String[size];
2251             for (int i = 0; i < size; i++)
2252                 strs[i] = fEnumeration.elementAt(i).toString();
2253             fLexicalEnumeration = new StringListImpl(strs, size);
2254         }
2255         return fLexicalEnumeration;
2256     }
2257 
2258     /**
2259      * A list of actual enumeration values if it exists, otherwise an empty
2260      * <code>ObjectList</code>.
2261      */
2262     public ObjectList getActualEnumeration() {
2263         if (fActualEnumeration == null) {
2264             fActualEnumeration = new AbstractObjectList() {
2265                 public int getLength() {
2266                     return (fEnumeration != null) ? fEnumeration.size() : 0;
2267                 }
2268                 public boolean contains(Object item) {
2269                     return (fEnumeration != null && fEnumeration.contains(item));
2270                 }
2271                 public Object item(int index) {
2272                     if (index < 0 || index >= getLength()) {
2273                         return null;
2274                     }
2275                     return fEnumeration.elementAt(index);
2276                 }
2277             };
2278         }
2279         return fActualEnumeration;
2280     }
2281 
2282     /**
2283      * A list of enumeration type values (as a list of ShortList objects) if it exists, otherwise returns
2284      * null
2285      */
2286     public ObjectList getEnumerationItemTypeList() {
2287         if (fEnumerationItemTypeList == null) {
2288             if(fEnumerationItemType == null)
2289                 return null;
2290             fEnumerationItemTypeList = new AbstractObjectList() {
2291                 public int getLength() {
2292                     return (fEnumerationItemType != null) ? fEnumerationItemType.length : 0;
2293                 }
2294                 public boolean contains(Object item) {
2295                     if(fEnumerationItemType == null || !(item instanceof ShortList))
2296                         return false;
2297                     for(int i = 0;i < fEnumerationItemType.length; i++)
2298                         if(fEnumerationItemType[i] == item)
2299                             return true;
2300                     return false;
2301                 }
2302                 public Object item(int index) {
2303                     if (index < 0 || index >= getLength()) {
2304                         return null;
2305                     }
2306                     return fEnumerationItemType[index];
2307                 }
2308             };
2309         }
2310         return fEnumerationItemTypeList;
2311     }
2312 
2313     public ShortList getEnumerationTypeList() {
2314         if (fEnumerationTypeList == null) {
2315             if (fEnumerationType == null) {
2316                 return ShortListImpl.EMPTY_LIST;
2317             }
2318             fEnumerationTypeList = new ShortListImpl (fEnumerationType, fEnumerationType.length);
2319         }
2320         return fEnumerationTypeList;
2321     }
2322 
2323     /**
2324      * A list of pattern values if it exists, otherwise an empty
2325      * <code>StringList</code>.
2326      */
2327     public StringList getLexicalPattern() {
2328         if (fPatternType == SPECIAL_PATTERN_NONE && fValidationDV != DV_INTEGER && fPatternStr == null)
2329             return StringListImpl.EMPTY_LIST;
2330         if (fLexicalPattern == null){
2331             int size = fPatternStr == null ? 0 : fPatternStr.size();
2332             String[] strs;
2333             if (fPatternType == SPECIAL_PATTERN_NMTOKEN) {
2334                 strs = new String[size+1];
2335                 strs[size] = "\\c+";
2336             }
2337             else if (fPatternType == SPECIAL_PATTERN_NAME) {
2338                 strs = new String[size+1];
2339                 strs[size] = "\\i\\c*";
2340             }
2341             else if (fPatternType == SPECIAL_PATTERN_NCNAME) {
2342                 strs = new String[size+2];
2343                 strs[size] = "\\i\\c*";
2344                 strs[size+1] = "[\\i-[:]][\\c-[:]]*";
2345             }
2346             else if (fValidationDV == DV_INTEGER) {
2347                 strs = new String[size+1];
2348                 strs[size] = "[\\-+]?[0-9]+";
2349             }
2350             else {
2351                 strs = new String[size];
2352             }
2353             for (int i = 0; i < size; i++)
2354                 strs[i] = (String)fPatternStr.elementAt(i);
2355             fLexicalPattern = new StringListImpl(strs, strs.length);
2356         }
2357         return fLexicalPattern;
2358     }
2359 
2360     /**
2361      * [annotations]: a set of annotations for this simple type component if
2362      * it exists, otherwise an empty <code>XSObjectList</code>.
2363      */
2364     public XSObjectList getAnnotations() {
2365         return (fAnnotations != null) ? fAnnotations : XSObjectListImpl.EMPTY_LIST;
2366     }
2367 
2368     private void calcFundamentalFacets() {
2369         setOrdered();
2370         setNumeric();
2371         setBounded();
2372         setCardinality();
2373     }
2374 
2375     private void setOrdered(){
2376 
2377         // 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).
2378         if(fVariety == VARIETY_ATOMIC){
2379             this.fOrdered = fBase.fOrdered;
2380         }
2381 
2382         // When {variety} is list, {value} is false.
2383         else if(fVariety == VARIETY_LIST){
2384             this.fOrdered = ORDERED_FALSE;
2385         }
2386 
2387         // When {variety} is union, the {value} is partial unless one of the following:
2388         // 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.
2389         // 2. If every member of {member type definitions} has a {value} of false for the ordered facet, then {value} is false.
2390         else if(fVariety == VARIETY_UNION){
2391             int length = fMemberTypes.length;
2392             // REVISIT: is the length possible to be 0?
2393             if (length == 0) {
2394                 this.fOrdered = ORDERED_PARTIAL;
2395                 return;
2396             }
2397             // we need to process the first member type before entering the loop
2398             short ancestorId = getPrimitiveDV(fMemberTypes[0].fValidationDV);
2399             boolean commonAnc = ancestorId != DV_ANYSIMPLETYPE;
2400             boolean allFalse = fMemberTypes[0].fOrdered == ORDERED_FALSE;
2401             // for the other member types, check whether the value is false
2402             // and whether they have the same ancestor as the first one
2403             for (int i = 1; i < fMemberTypes.length && (commonAnc || allFalse); i++) {
2404                 if (commonAnc)
2405                     commonAnc = ancestorId == getPrimitiveDV(fMemberTypes[i].fValidationDV);
2406                 if (allFalse)
2407                     allFalse = fMemberTypes[i].fOrdered == ORDERED_FALSE;
2408             }
2409             if (commonAnc) {
2410                 // REVISIT: all member types should have the same ordered value
2411                 //          just use the first one. Can we assume this?
2412                 this.fOrdered = fMemberTypes[0].fOrdered;
2413             } else if (allFalse) {
2414                 this.fOrdered = ORDERED_FALSE;
2415             } else {
2416                 this.fOrdered = ORDERED_PARTIAL;
2417             }
2418         }
2419 
2420     }//setOrdered
2421 
2422     private void setNumeric(){
2423         if(fVariety == VARIETY_ATOMIC){
2424             this.fNumeric = fBase.fNumeric;
2425         }
2426         else if(fVariety == VARIETY_LIST){
2427             this.fNumeric = false;
2428         }
2429         else if(fVariety == VARIETY_UNION){
2430             XSSimpleType[] memberTypes = fMemberTypes;
2431             for(int i = 0 ; i < memberTypes.length ; i++){
2432                 if(!memberTypes[i].getNumeric() ){
2433                     this.fNumeric = false;
2434                     return;
2435                 }
2436             }
2437             this.fNumeric = true;
2438         }
2439 
2440     }//setNumeric
2441 
2442     private void setBounded(){
2443         if(fVariety == VARIETY_ATOMIC){
2444             if( (((this.fFacetsDefined & FACET_MININCLUSIVE) != 0)  || ((this.fFacetsDefined & FACET_MINEXCLUSIVE) != 0))
2445                     &&  (((this.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)  || ((this.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) ){
2446                 this.fBounded = true;
2447             }
2448             else{
2449                 this.fBounded = false;
2450             }
2451         }
2452         else if(fVariety == VARIETY_LIST){
2453             if( ((this.fFacetsDefined & FACET_LENGTH) != 0 ) || ( ((this.fFacetsDefined & FACET_MINLENGTH) != 0 )
2454                     &&  ((this.fFacetsDefined & FACET_MAXLENGTH) != 0 )) ){
2455                 this.fBounded = true;
2456             }
2457             else{
2458                 this.fBounded = false;
2459             }
2460 
2461         }
2462         else if(fVariety == VARIETY_UNION){
2463 
2464             XSSimpleTypeDecl [] memberTypes = this.fMemberTypes;
2465             short ancestorId = 0 ;
2466 
2467             if(memberTypes.length > 0){
2468                 ancestorId = getPrimitiveDV(memberTypes[0].fValidationDV);
2469             }
2470 
2471             for(int i = 0 ; i < memberTypes.length ; i++){
2472                 if(!memberTypes[i].getBounded() || (ancestorId != getPrimitiveDV(memberTypes[i].fValidationDV)) ){
2473                     this.fBounded = false;
2474                     return;
2475                 }
2476             }
2477             this.fBounded = true;
2478         }
2479 
2480     }//setBounded
2481 
2482     private boolean specialCardinalityCheck(){
2483         if( (fBase.fValidationDV == XSSimpleTypeDecl.DV_DATE) || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GYEARMONTH)
2484                 || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GYEAR) || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GMONTHDAY)
2485                 || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GDAY) || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GMONTH) ){
2486             return true;
2487         }
2488         return false;
2489 
2490     } //specialCardinalityCheck()
2491 
2492     private void setCardinality(){
2493         if(fVariety == VARIETY_ATOMIC){
2494             if(fBase.fFinite){
2495                 this.fFinite = true;
2496             }
2497             else {// (!fBase.fFinite)
2498                 if ( ((this.fFacetsDefined & FACET_LENGTH) != 0 ) || ((this.fFacetsDefined & FACET_MAXLENGTH) != 0 )
2499                         || ((this.fFacetsDefined & FACET_TOTALDIGITS) != 0 ) ){
2500                     this.fFinite = true;
2501                 }
2502                 else if( (((this.fFacetsDefined & FACET_MININCLUSIVE) != 0 ) || ((this.fFacetsDefined & FACET_MINEXCLUSIVE) != 0 ))
2503                         && (((this.fFacetsDefined & FACET_MAXINCLUSIVE) != 0 ) || ((this.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0 )) ){
2504                     if( ((this.fFacetsDefined & FACET_FRACTIONDIGITS) != 0 ) || specialCardinalityCheck()){
2505                         this.fFinite = true;
2506                     }
2507                     else{
2508                         this.fFinite = false;
2509                     }
2510                 }
2511                 else{
2512                     this.fFinite = false;
2513                 }
2514             }
2515         }
2516         else if(fVariety == VARIETY_LIST){
2517             if( ((this.fFacetsDefined & FACET_LENGTH) != 0 ) || ( ((this.fFacetsDefined & FACET_MINLENGTH) != 0 )
2518                     && ((this.fFacetsDefined & FACET_MAXLENGTH) != 0 )) ){
2519                 this.fFinite = true;
2520             }
2521             else{
2522                 this.fFinite = false;
2523             }
2524 
2525         }
2526         else if(fVariety == VARIETY_UNION){
2527             XSSimpleType [] memberTypes = fMemberTypes;
2528             for(int i = 0 ; i < memberTypes.length ; i++){
2529                 if(!(memberTypes[i].getFinite()) ){
2530                     this.fFinite = false;
2531                     return;
2532                 }
2533             }
2534             this.fFinite = true;
2535         }
2536 
2537     }//setCardinality
2538 
2539     private short getPrimitiveDV(short validationDV){
2540 
2541         if (validationDV == DV_ID || validationDV == DV_IDREF || validationDV == DV_ENTITY){
2542             return DV_STRING;
2543         }
2544         else if (validationDV == DV_INTEGER) {
2545             return DV_DECIMAL;
2546         }
2547         else if (Constants.SCHEMA_1_1_SUPPORT && (validationDV == DV_YEARMONTHDURATION || validationDV == DV_DAYTIMEDURATION)) {
2548             return DV_DURATION;
2549         }
2550         else {
2551             return validationDV;
2552         }
2553 
2554     }//getPrimitiveDV()
2555 
2556     public boolean derivedFromType(XSTypeDefinition ancestor, short derivation) {
2557         // REVISIT: implement according to derivation
2558 
2559         // ancestor is null, return false
2560         if (ancestor == null) {
2561             return false;
2562         }
2563         // extract the actual XSTypeDefinition if the given ancestor is a delegate.
2564         while (ancestor instanceof XSSimpleTypeDelegate) {
2565             ancestor = ((XSSimpleTypeDelegate) ancestor).type;
2566         }
2567         // ancestor is anyType, return true
2568         // anyType is the only type whose base type is itself
2569         if (ancestor.getBaseType() == ancestor) {
2570             return true;
2571         }
2572         // recursively get base, and compare it with ancestor
2573         XSTypeDefinition type = this;
2574         while (type != ancestor &&                      // compare with ancestor
2575                 type != fAnySimpleType) {  // reached anySimpleType
2576             type = type.getBaseType();
2577         }
2578         return type == ancestor;
2579     }
2580 
2581     public boolean derivedFrom(String ancestorNS, String ancestorName, short derivation) {
2582         // REVISIT: implement according to derivation
2583 
2584         // ancestor is null, retur false
2585         if (ancestorName == null)
2586             return false;
2587         // ancestor is anyType, return true
2588         if (URI_SCHEMAFORSCHEMA.equals(ancestorNS) &&
2589                 ANY_TYPE.equals(ancestorName)) {
2590             return true;
2591         }
2592 
2593         // recursively get base, and compare it with ancestor
2594         XSTypeDefinition type = this;
2595         while (!(ancestorName.equals(type.getName()) &&
2596                 ((ancestorNS == null && type.getNamespace() == null) ||
2597                         (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) &&   // compare with ancestor
2598                         type != fAnySimpleType) {  // reached anySimpleType
2599             type = (XSTypeDefinition)type.getBaseType();
2600         }
2601 
2602         return type != fAnySimpleType;
2603     }
2604 
2605     /**
2606      * Checks if a type is derived from another by restriction, given the name
2607      * and namespace. See:
2608      * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
2609      *
2610      * @param ancestorNS
2611      *            The namspace of the ancestor type declaration
2612      * @param ancestorName
2613      *            The name of the ancestor type declaration
2614      * @param derivationMethod
2615      *            The derivation method
2616      *
2617      * @return boolean True if the ancestor type is derived from the reference type by the specifiied derivation method.
2618      */
2619     public boolean isDOMDerivedFrom(String ancestorNS, String ancestorName, int derivationMethod) {
2620 
2621         // ancestor is null, return false
2622         if (ancestorName == null)
2623             return false;
2624 
2625         // ancestor is anyType, return true
2626         if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(ancestorNS)
2627                 && SchemaSymbols.ATTVAL_ANYTYPE.equals(ancestorName)
2628                 && (((derivationMethod  & DERIVATION_RESTRICTION) != 0)
2629                         || (derivationMethod  == DERIVATION_ANY))) {
2630             return true;
2631         }
2632 
2633         // restriction
2634         if ((derivationMethod & DERIVATION_RESTRICTION) != 0) {
2635             if (isDerivedByRestriction(ancestorNS, ancestorName, this)) {
2636                 return true;
2637             }
2638         }
2639 
2640         // list
2641         if ((derivationMethod & DERIVATION_LIST) != 0) {
2642             if (isDerivedByList(ancestorNS, ancestorName, this)) {
2643                 return true;
2644             }
2645         }
2646 
2647         // union
2648         if ((derivationMethod & DERIVATION_UNION) != 0) {
2649             if (isDerivedByUnion(ancestorNS, ancestorName, this)) {
2650                 return true;
2651             }
2652         }
2653 
2654         // extension
2655         if (((derivationMethod & DERIVATION_EXTENSION) != 0)
2656                 && (((derivationMethod & DERIVATION_RESTRICTION) == 0)
2657                         && ((derivationMethod & DERIVATION_LIST) == 0)
2658                         && ((derivationMethod & DERIVATION_UNION) == 0))) {
2659             return false;
2660         }
2661 
2662         // If the value of the parameter is 0 i.e. no bit (corresponding to
2663         // restriction, list, extension or union) is set to 1 for the
2664         // derivationMethod parameter.
2665         if (((derivationMethod & DERIVATION_EXTENSION) == 0)
2666                 && (((derivationMethod & DERIVATION_RESTRICTION) == 0)
2667                         && ((derivationMethod & DERIVATION_LIST) == 0)
2668                         && ((derivationMethod & DERIVATION_UNION) == 0))) {
2669             return isDerivedByAny(ancestorNS, ancestorName, this);
2670         }
2671 
2672         return false;
2673     }
2674 
2675 
2676     /**
2677      * Checks if a type is derived from another by any combination of restriction, list ir union. See:
2678      * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
2679      *
2680      * @param ancestorNS
2681      *            The namspace of the ancestor type declaration
2682      * @param ancestorName
2683      *            The name of the ancestor type declaration
2684      * @param type
2685      *            The reference type definition
2686      *
2687      * @return boolean True if the type is derived by restriciton for the reference type
2688      */
2689     private boolean isDerivedByAny(String ancestorNS, String ancestorName,
2690             XSTypeDefinition type) {
2691 
2692         boolean derivedFrom = false;
2693         XSTypeDefinition oldType = null;
2694         // for each base, item or member type
2695         while (type != null && type != oldType)  {
2696 
2697             // If the ancestor type is reached or is the same as this type.
2698             if ((ancestorName.equals(type.getName()))
2699                     && ((ancestorNS == null && type.getNamespace() == null)
2700                             || (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) {
2701                 derivedFrom = true;
2702                 break;
2703             }
2704 
2705             // check if derived by restriction or list or union
2706             if (isDerivedByRestriction(ancestorNS, ancestorName, type)) {
2707                 return true;
2708             } else if (isDerivedByList(ancestorNS, ancestorName, type)) {
2709                 return true;
2710             } else  if (isDerivedByUnion(ancestorNS, ancestorName, type)) {
2711                 return true;
2712             }
2713             oldType = type;
2714             // get the base, item or member type depending on the variety
2715             if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_ABSENT
2716                     || ((XSSimpleTypeDecl) type).getVariety() == VARIETY_ATOMIC) {
2717                 type = type.getBaseType();
2718             } else if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_UNION) {
2719                 for (int i = 0; i < ((XSSimpleTypeDecl) type).getMemberTypes().getLength(); i++) {
2720                     return isDerivedByAny(ancestorNS, ancestorName,
2721                             (XSTypeDefinition) ((XSSimpleTypeDecl) type)
2722                             .getMemberTypes().item(i));
2723                 }
2724             } else if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_LIST) {
2725                 type = ((XSSimpleTypeDecl) type).getItemType();
2726             }
2727         }
2728 
2729         return derivedFrom;
2730     }
2731 
2732     /**
2733      * DOM Level 3
2734      * Checks if a type is derived from another by restriction. See:
2735      * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
2736      *
2737      * @param ancestorNS
2738      *            The namspace of the ancestor type declaration
2739      * @param ancestorName
2740      *            The name of the ancestor type declaration
2741      * @param type
2742      *            The reference type definition
2743      *
2744      * @return boolean True if the type is derived by restriciton for the
2745      *         reference type
2746      */
2747     private boolean isDerivedByRestriction (String ancestorNS, String ancestorName, XSTypeDefinition type) {
2748         XSTypeDefinition oldType = null;
2749         while (type != null && type != oldType) {
2750             if ((ancestorName.equals(type.getName()))
2751                     && ((ancestorNS != null && ancestorNS.equals(type.getNamespace()))
2752                             || (type.getNamespace() == null && ancestorNS == null))) {
2753 
2754                 return true;
2755             }
2756             oldType = type;
2757             type = type.getBaseType();
2758         }
2759 
2760         return false;
2761     }
2762 
2763     /**
2764      * Checks if a type is derived from another by list. See:
2765      * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
2766      *
2767      * @param ancestorNS
2768      *            The namspace of the ancestor type declaration
2769      * @param ancestorName
2770      *            The name of the ancestor type declaration
2771      * @param type
2772      *            The reference type definition
2773      *
2774      * @return boolean True if the type is derived by list for the reference type
2775      */
2776     private boolean isDerivedByList (String ancestorNS, String ancestorName, XSTypeDefinition type) {
2777         // If the variety is union
2778         if (type !=null && ((XSSimpleTypeDefinition)type).getVariety() == VARIETY_LIST) {
2779 
2780             // get the {item type}
2781             XSTypeDefinition itemType = ((XSSimpleTypeDefinition)type).getItemType();
2782 
2783             // T2 is the {item type definition}
2784             if (itemType != null) {
2785 
2786                 // T2 is derived from the other type definition by DERIVATION_RESTRICTION
2787                 if (isDerivedByRestriction(ancestorNS, ancestorName, itemType)) {
2788                     return true;
2789                 }
2790             }
2791         }
2792         return false;
2793     }
2794 
2795     /**
2796      * Checks if a type is derived from another by union.  See:
2797      * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
2798      *
2799      * @param ancestorNS
2800      *            The namspace of the ancestor type declaration
2801      * @param ancestorName
2802      *            The name of the ancestor type declaration
2803      * @param type
2804      *            The reference type definition
2805      *
2806      * @return boolean True if the type is derived by union for the reference type
2807      */
2808     private boolean isDerivedByUnion (String ancestorNS, String ancestorName, XSTypeDefinition type) {
2809 
2810         // If the variety is union
2811         if (type !=null && ((XSSimpleTypeDefinition)type).getVariety() == VARIETY_UNION) {
2812 
2813             // get member types
2814             XSObjectList memberTypes = ((XSSimpleTypeDefinition)type).getMemberTypes();
2815 
2816             for (int i = 0; i < memberTypes.getLength(); i++) {
2817                 // One of the {member type definitions} is T2.
2818                 if (memberTypes.item(i) != null) {
2819                     // T2 is derived from the other type definition by DERIVATION_RESTRICTION
2820                     if (isDerivedByRestriction(ancestorNS, ancestorName,(XSSimpleTypeDefinition)memberTypes.item(i))) {
2821                         return true;
2822                     }
2823                 }
2824             }
2825         }
2826         return false;
2827     }
2828 
2829 
2830     static final XSSimpleTypeDecl fAnySimpleType = new XSSimpleTypeDecl(null, "anySimpleType", DV_ANYSIMPLETYPE, ORDERED_FALSE, false, true, false, true, XSConstants.ANYSIMPLETYPE_DT);
2831 
2832     static final XSSimpleTypeDecl fAnyAtomicType = new XSSimpleTypeDecl(fAnySimpleType, "anyAtomicType", DV_ANYATOMICTYPE, ORDERED_FALSE, false, true, false, true, XSSimpleTypeDecl.ANYATOMICTYPE_DT);
2833 
2834     /**
2835      * Validation context used to validate facet values.
2836      */
2837     static final ValidationContext fDummyContext = new ValidationContext() {
2838         public boolean needFacetChecking() {
2839             return true;
2840         }
2841 
2842         public boolean needExtraChecking() {
2843             return false;
2844         }
2845         public boolean needToNormalize() {
2846             return false;
2847         }
2848         public boolean useNamespaces() {
2849             return true;
2850         }
2851 
2852         public boolean isEntityDeclared(String name) {
2853             return false;
2854         }
2855 
2856         public boolean isEntityUnparsed(String name) {
2857             return false;
2858         }
2859 
2860         public boolean isIdDeclared(String name) {
2861             return false;
2862         }
2863 
2864         public void addId(String name) {
2865         }
2866 
2867         public void addIdRef(String name) {
2868         }
2869 
2870         public String getSymbol (String symbol) {
2871             return symbol.intern();
2872         }
2873 
2874         public String getURI(String prefix) {
2875             return null;
2876         }
2877 
2878         public Locale getLocale() {
2879             return Locale.getDefault();
2880         }
2881     };
2882 
2883     private boolean fAnonymous = false;
2884 
2885     /**
2886      * A wrapper of ValidationContext, to provide a way of switching to a
2887      * different Namespace declaration context.
2888      */
2889     static final class ValidationContextImpl implements ValidationContext {
2890 
2891         final ValidationContext fExternal;
2892 
2893         ValidationContextImpl(ValidationContext external) {
2894             fExternal = external;
2895         }
2896 
2897         NamespaceContext fNSContext;
2898         void setNSContext(NamespaceContext nsContext) {
2899             fNSContext = nsContext;
2900         }
2901 
2902         public boolean needFacetChecking() {
2903             return fExternal.needFacetChecking();
2904         }
2905 
2906         public boolean needExtraChecking() {
2907             return fExternal.needExtraChecking();
2908         }
2909         public boolean needToNormalize() {
2910             return fExternal.needToNormalize();
2911         }
2912         // schema validation is predicated upon namespaces
2913         public boolean useNamespaces() {
2914             return true;
2915         }
2916 
2917         public boolean isEntityDeclared (String name) {
2918             return fExternal.isEntityDeclared(name);
2919         }
2920 
2921         public boolean isEntityUnparsed (String name) {
2922             return fExternal.isEntityUnparsed(name);
2923         }
2924 
2925         public boolean isIdDeclared (String name) {
2926             return fExternal.isIdDeclared(name);
2927         }
2928 
2929         public void addId(String name) {
2930             fExternal.addId(name);
2931         }
2932 
2933         public void addIdRef(String name) {
2934             fExternal.addIdRef(name);
2935         }
2936 
2937         public String getSymbol (String symbol) {
2938             return fExternal.getSymbol(symbol);
2939         }
2940 
2941         public String getURI(String prefix) {
2942             if (fNSContext == null) {
2943                 return fExternal.getURI(prefix);
2944             }
2945             else {
2946                 return fNSContext.getURI(prefix);
2947             }
2948         }
2949 
2950         public Locale getLocale() {
2951             return fExternal.getLocale();
2952         }
2953     }
2954 
2955     public void reset(){
2956 
2957         // if it's immutable, can't be reset:
2958         if (fIsImmutable) return;
2959         fItemType = null;
2960         fMemberTypes = null;
2961 
2962         fTypeName = null;
2963         fTargetNamespace = null;
2964         fFinalSet = 0;
2965         fBase = null;
2966         fVariety = -1;
2967         fValidationDV = -1;
2968 
2969         fFacetsDefined = 0;
2970         fFixedFacet = 0;
2971 
2972         //for constraining facets
2973         fWhiteSpace = 0;
2974         fLength = -1;
2975         fMinLength = -1;
2976         fMaxLength = -1;
2977         fTotalDigits = -1;
2978         fFractionDigits = -1;
2979         fPattern = null;
2980         fPatternStr = null;
2981         fEnumeration = null;
2982         fEnumerationType = null;
2983         fEnumerationItemType = null;
2984         fLexicalPattern = null;
2985         fLexicalEnumeration = null;
2986         fMaxInclusive = null;
2987         fMaxExclusive = null;
2988         fMinExclusive = null;
2989         fMinInclusive = null;
2990         lengthAnnotation = null;
2991         minLengthAnnotation = null;
2992         maxLengthAnnotation = null;
2993         whiteSpaceAnnotation = null;
2994         totalDigitsAnnotation = null;
2995         fractionDigitsAnnotation = null;
2996         patternAnnotations = null;
2997         enumerationAnnotations = null;
2998         maxInclusiveAnnotation = null;
2999         maxExclusiveAnnotation = null;
3000         minInclusiveAnnotation = null;
3001         minExclusiveAnnotation = null;
3002 
3003         fPatternType = SPECIAL_PATTERN_NONE;
3004         fAnnotations = null;
3005         fFacets = null;
3006 
3007         // REVISIT: reset for fundamental facets
3008     }
3009 
3010     /**
3011      * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespaceItem()
3012      */
3013     public XSNamespaceItem getNamespaceItem() {
3014         return fNamespaceItem;
3015     }
3016 
3017     public void setNamespaceItem(XSNamespaceItem namespaceItem) {
3018         fNamespaceItem = namespaceItem;
3019     }
3020 
3021     /**
3022      * @see java.lang.Object#toString()
3023      */
3024     public String toString() {
3025         return this.fTargetNamespace+"," +this.fTypeName;
3026     }
3027 
3028     /**
3029      *  A list of constraining facets if it exists, otherwise an empty
3030      * <code>XSObjectList</code>. Note: This method must not be used to
3031      * retrieve values for <code>enumeration</code> and <code>pattern</code>
3032      * facets.
3033      */
3034     public XSObjectList getFacets() {
3035         if (fFacets == null &&
3036                 (fFacetsDefined != 0 || fValidationDV == DV_INTEGER)) {
3037 
3038             XSFacetImpl[] facets = new XSFacetImpl[10];
3039             int count = 0;
3040             if ((fFacetsDefined & FACET_WHITESPACE) != 0 &&
3041                 fValidationDV != DV_ANYSIMPLETYPE &&
3042                 fValidationDV != DV_ANYATOMICTYPE) {
3043                 facets[count] =
3044                     new XSFacetImpl(
3045                             FACET_WHITESPACE,
3046                             WS_FACET_STRING[fWhiteSpace],
3047                             (fFixedFacet & FACET_WHITESPACE) != 0,
3048                             whiteSpaceAnnotation);
3049                 count++;
3050             }
3051             if (fLength != -1) {
3052                 facets[count] =
3053                     new XSFacetImpl(
3054                             FACET_LENGTH,
3055                             Integer.toString(fLength),
3056                             (fFixedFacet & FACET_LENGTH) != 0,
3057                             lengthAnnotation);
3058                 count++;
3059             }
3060             if (fMinLength != -1) {
3061                 facets[count] =
3062                     new XSFacetImpl(
3063                             FACET_MINLENGTH,
3064                             Integer.toString(fMinLength),
3065                             (fFixedFacet & FACET_MINLENGTH) != 0,
3066                             minLengthAnnotation);
3067                 count++;
3068             }
3069             if (fMaxLength != -1) {
3070                 facets[count] =
3071                     new XSFacetImpl(
3072                             FACET_MAXLENGTH,
3073                             Integer.toString(fMaxLength),
3074                             (fFixedFacet & FACET_MAXLENGTH) != 0,
3075                             maxLengthAnnotation);
3076                 count++;
3077             }
3078             if (fTotalDigits != -1) {
3079                 facets[count] =
3080                     new XSFacetImpl(
3081                             FACET_TOTALDIGITS,
3082                             Integer.toString(fTotalDigits),
3083                             (fFixedFacet & FACET_TOTALDIGITS) != 0,
3084                             totalDigitsAnnotation);
3085                 count++;
3086             }
3087             if (fValidationDV == DV_INTEGER) {
3088                 facets[count] =
3089                     new XSFacetImpl(
3090                             FACET_FRACTIONDIGITS,
3091                             "0",
3092                             true,
3093                             fractionDigitsAnnotation);
3094                 count++;
3095             }
3096             else if (fFractionDigits != -1) {
3097                 facets[count] =
3098                     new XSFacetImpl(
3099                             FACET_FRACTIONDIGITS,
3100                             Integer.toString(fFractionDigits),
3101                             (fFixedFacet & FACET_FRACTIONDIGITS) != 0,
3102                             fractionDigitsAnnotation);
3103                 count++;
3104             }
3105             if (fMaxInclusive != null) {
3106                 facets[count] =
3107                     new XSFacetImpl(
3108                             FACET_MAXINCLUSIVE,
3109                             fMaxInclusive.toString(),
3110                             (fFixedFacet & FACET_MAXINCLUSIVE) != 0,
3111                             maxInclusiveAnnotation);
3112                 count++;
3113             }
3114             if (fMaxExclusive != null) {
3115                 facets[count] =
3116                     new XSFacetImpl(
3117                             FACET_MAXEXCLUSIVE,
3118                             fMaxExclusive.toString(),
3119                             (fFixedFacet & FACET_MAXEXCLUSIVE) != 0,
3120                             maxExclusiveAnnotation);
3121                 count++;
3122             }
3123             if (fMinExclusive != null) {
3124                 facets[count] =
3125                     new XSFacetImpl(
3126                             FACET_MINEXCLUSIVE,
3127                             fMinExclusive.toString(),
3128                             (fFixedFacet & FACET_MINEXCLUSIVE) != 0,
3129                             minExclusiveAnnotation);
3130                 count++;
3131             }
3132             if (fMinInclusive != null) {
3133                 facets[count] =
3134                     new XSFacetImpl(
3135                             FACET_MININCLUSIVE,
3136                             fMinInclusive.toString(),
3137                             (fFixedFacet & FACET_MININCLUSIVE) != 0,
3138                             minInclusiveAnnotation);
3139                 count++;
3140             }
3141             fFacets = (count > 0) ? new XSObjectListImpl(facets, count) : XSObjectListImpl.EMPTY_LIST;
3142         }
3143         return (fFacets != null) ? fFacets : XSObjectListImpl.EMPTY_LIST;
3144     }
3145 
3146     /**
3147      *  A list of enumeration and pattern constraining facets if it exists,
3148      * otherwise an empty <code>XSObjectList</code>.
3149      */
3150     public XSObjectList getMultiValueFacets() {
3151         if (fMultiValueFacets == null &&
3152                 ((fFacetsDefined & FACET_ENUMERATION) != 0 ||
3153                         (fFacetsDefined & FACET_PATTERN) != 0 ||
3154                         fPatternType != SPECIAL_PATTERN_NONE ||
3155                         fValidationDV == DV_INTEGER)) {
3156 
3157             XSMVFacetImpl[] facets = new XSMVFacetImpl[2];
3158             int count = 0;
3159             if ((fFacetsDefined & FACET_PATTERN) != 0 ||
3160                     fPatternType != SPECIAL_PATTERN_NONE ||
3161                     fValidationDV == DV_INTEGER) {
3162                 facets[count] =
3163                     new XSMVFacetImpl(
3164                             FACET_PATTERN,
3165                             this.getLexicalPattern(),
3166                             patternAnnotations);
3167                 count++;
3168             }
3169             if (fEnumeration != null) {
3170                 facets[count] =
3171                     new XSMVFacetImpl(
3172                             FACET_ENUMERATION,
3173                             this.getLexicalEnumeration(),
3174                             enumerationAnnotations);
3175                 count++;
3176             }
3177             fMultiValueFacets = new XSObjectListImpl(facets, count);
3178         }
3179         return (fMultiValueFacets != null) ?
3180                 fMultiValueFacets : XSObjectListImpl.EMPTY_LIST;
3181     }
3182 
3183     public Object getMinInclusiveValue() {
3184         return fMinInclusive;
3185     }
3186 
3187     public Object getMinExclusiveValue() {
3188         return fMinExclusive;
3189     }
3190 
3191     public Object getMaxInclusiveValue() {
3192         return fMaxInclusive;
3193     }
3194 
3195     public Object getMaxExclusiveValue() {
3196         return fMaxExclusive;
3197     }
3198 
3199     public void setAnonymous(boolean anon) {
3200         fAnonymous = anon;
3201     }
3202 
3203     private static final class XSFacetImpl implements XSFacet {
3204         final short kind;
3205         final String value;
3206         final boolean fixed;
3207         final XSObjectList annotations;
3208 
3209         public XSFacetImpl(short kind, String value, boolean fixed, XSAnnotation annotation) {
3210             this.kind = kind;
3211             this.value = value;
3212             this.fixed = fixed;
3213 
3214             if (annotation != null) {
3215                 this.annotations = new XSObjectListImpl();
3216                 ((XSObjectListImpl)this.annotations).addXSObject(annotation);
3217             }
3218             else {
3219                 this.annotations =  XSObjectListImpl.EMPTY_LIST;
3220             }
3221         }
3222 
3223         /*
3224          * (non-Javadoc)
3225          *
3226          * @see com.sun.org.apache.xerces.internal.xs.XSFacet#getAnnotation()
3227          */
3228         /**
3229          * Optional. Annotation.
3230          */
3231         public XSAnnotation getAnnotation() {
3232             return (XSAnnotation) annotations.item(0);
3233         }
3234 
3235         /*
3236          * (non-Javadoc)
3237          *
3238          * @see com.sun.org.apache.xerces.internal.xs.XSFacet#getAnnotations()
3239          */
3240         /**
3241          * Optional. Annotations.
3242          */
3243         public XSObjectList getAnnotations() {
3244             return annotations;
3245         }
3246 
3247         /* (non-Javadoc)
3248          * @see com.sun.org.apache.xerces.internal.xs.XSFacet#getFacetKind()
3249          */
3250         public short getFacetKind() {
3251             return kind;
3252         }
3253 
3254         /* (non-Javadoc)
3255          * @see com.sun.org.apache.xerces.internal.xs.XSFacet#getLexicalFacetValue()
3256          */
3257         public String getLexicalFacetValue() {
3258             return value;
3259         }
3260 
3261         /* (non-Javadoc)
3262          * @see com.sun.org.apache.xerces.internal.xs.XSFacet#isFixed()
3263          */
3264         public boolean getFixed() {
3265             return fixed;
3266         }
3267 
3268         /* (non-Javadoc)
3269          * @see com.sun.org.apache.xerces.internal.xs.XSObject#getName()
3270          */
3271         public String getName() {
3272             return null;
3273         }
3274 
3275         /* (non-Javadoc)
3276          * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespace()
3277          */
3278         public String getNamespace() {
3279             return null;
3280         }
3281 
3282         /* (non-Javadoc)
3283          * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespaceItem()
3284          */
3285         public XSNamespaceItem getNamespaceItem() {
3286             // REVISIT: implement
3287             return null;
3288         }
3289 
3290         /* (non-Javadoc)
3291          * @see com.sun.org.apache.xerces.internal.xs.XSObject#getType()
3292          */
3293         public short getType() {
3294             return XSConstants.FACET;
3295         }
3296 
3297     }
3298 
3299     private static final class XSMVFacetImpl implements XSMultiValueFacet {
3300         final short kind;
3301         final XSObjectList annotations;
3302         final StringList values;
3303 
3304         public XSMVFacetImpl(short kind, StringList values, XSObjectList annotations) {
3305             this.kind = kind;
3306             this.values = values;
3307             this.annotations = (annotations != null) ? annotations : XSObjectListImpl.EMPTY_LIST;
3308         }
3309 
3310         /* (non-Javadoc)
3311          * @see com.sun.org.apache.xerces.internal.xs.XSFacet#getFacetKind()
3312          */
3313         public short getFacetKind() {
3314             return kind;
3315         }
3316 
3317         /* (non-Javadoc)
3318          * @see com.sun.org.apache.xerces.internal.xs.XSMultiValueFacet#getAnnotations()
3319          */
3320         public XSObjectList getAnnotations() {
3321             return annotations;
3322         }
3323 
3324         /* (non-Javadoc)
3325          * @see com.sun.org.apache.xerces.internal.xs.XSMultiValueFacet#getLexicalFacetValues()
3326          */
3327         public StringList getLexicalFacetValues() {
3328             return values;
3329         }
3330 
3331         /* (non-Javadoc)
3332          * @see com.sun.org.apache.xerces.internal.xs.XSObject#getName()
3333          */
3334         public String getName() {
3335             return null;
3336         }
3337 
3338         /* (non-Javadoc)
3339          * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespace()
3340          */
3341         public String getNamespace() {
3342             return null;
3343         }
3344 
3345         /* (non-Javadoc)
3346          * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespaceItem()
3347          */
3348         public XSNamespaceItem getNamespaceItem() {
3349             // REVISIT: implement
3350             return null;
3351         }
3352 
3353         /* (non-Javadoc)
3354          * @see com.sun.org.apache.xerces.internal.xs.XSObject#getType()
3355          */
3356         public short getType() {
3357             return XSConstants.MULTIVALUE_FACET;
3358         }
3359     }
3360 
3361     private static abstract class AbstractObjectList extends AbstractList implements ObjectList {
3362         public Object get(int index) {
3363             if (index >= 0 && index < getLength()) {
3364                 return item(index);
3365             }
3366             throw new IndexOutOfBoundsException("Index: " + index);
3367         }
3368         public int size() {
3369             return getLength();
3370         }
3371     }
3372 
3373     public String getTypeNamespace() {
3374         return getNamespace();
3375     }
3376 
3377     public boolean isDerivedFrom(String typeNamespaceArg, String typeNameArg, int derivationMethod) {
3378         return isDOMDerivedFrom(typeNamespaceArg, typeNameArg, derivationMethod);
3379     }
3380 
3381     private short convertToPrimitiveKind(short valueType) {
3382         /** Primitive datatypes. */
3383         if (valueType <= XSConstants.NOTATION_DT) {
3384             return valueType;
3385         }
3386         /** Types derived from string. */
3387         if (valueType <= XSConstants.ENTITY_DT) {
3388             return XSConstants.STRING_DT;
3389         }
3390         /** Types derived from decimal. */
3391         if (valueType <= XSConstants.POSITIVEINTEGER_DT) {
3392             return XSConstants.DECIMAL_DT;
3393         }
3394         /** Other types. */
3395         return valueType;
3396     }
3397 
3398 } // class XSSimpleTypeDecl