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