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