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