1 22 23 package org.xquark.schema; 24 25 import java.util.*; 26 27 import org.xquark.schema.datatypes.PrimitiveType; 28 import org.xquark.schema.loader.*; 29 import org.xquark.schema.validation.ValidationContextProvider; 30 31 public class InitializationVisitor extends DefaultSchemaVisitor implements SchemaConstants { 32 private static final String RCSRevision = "$Revision: 1.5 $"; 33 private static final String RCSName = "$Name: $"; 34 private ReferenceResolver refResolver = new ReferenceResolver(); 35 private HashSet initialized = new HashSet(); 36 private Schema schema; 37 private ArrayList pendingTypes = null; 38 private Map contextProviders = null; 39 private Loader loader = null; 40 41 public InitializationVisitor(Schema schema) { 42 this.schema = schema; 43 } 44 45 public InitializationVisitor(Schema schema, Map contextProviders, Loader loader) { 46 this.schema = schema; 47 this.contextProviders = contextProviders; 48 this.loader = loader; 49 } 50 51 public void visit(AttributeGroupDefinition attG) throws SchemaException { 52 if (attG.getSchema() != schema || initialized.contains(attG)) 53 return; 54 initialized.add(attG); 55 56 Iterator it = attG.getAttributeDeclarations().iterator(); 57 while (it.hasNext()) { 58 SchemaComponent comp = (SchemaComponent) it.next(); 59 refResolver.resolve(comp); 60 comp.accept(this); 61 } 62 } 63 64 public void visit(ElementDeclaration decl) throws SchemaException { 65 if (initialized.contains(decl)) 66 return; 67 initialized.add(decl); 69 70 72 if (decl.getType() != null) { 74 initType(decl); 75 if (decl.getType().isSimpleType() 77 && decl.getType().isDerivedFrom(decl.getManager().getType(XMLSCHEMA_URI, "NOTATION"))) { 78 throw new SchemaException("enumeration-required-notation", decl); 79 } 80 } 81 82 ElementDeclaration substitutionElement = null; 84 if (decl.getSubstitutionGroup() != null) { 85 substitutionElement = (ElementDeclaration) refResolver.resolve(decl.getSubstitutionGroup()); 86 substitutionElement.accept(this); 87 if ((substitutionElement.getBlock() & SUBSTITUTION) != 0) { 88 throw new SchemaException("cos-equiv-derived-ok-rec.1", decl); 89 } 90 if (decl.getType() == null) { 91 decl.setType(substitutionElement.getType()); 92 } else { 93 String errCode = 94 decl.getType().checkTypeDerivationOK( 95 substitutionElement.getType(), 96 substitutionElement.getFinal(), 97 false); 98 if (errCode != null) { 99 throw new SchemaException("e-props-correct.3", decl); 101 } 102 } 103 String errCode = 104 decl.getType().checkTypeDerivationOK( 105 substitutionElement.getType(), 106 substitutionElement.getBlock(), 107 true); 108 if (errCode != null) { 109 throw new SchemaException("cos-equiv-derived-ok-rec.3", decl); 111 } 112 decl.setSubstitutionGroup(substitutionElement); 113 substitutionElement.addSubstitutionMember(decl); 114 propagateSubstitution(substitutionElement, decl); 115 } 116 if (decl.getType() == null) { 118 Schema w3cSchema = schema.getManager().getSchema(XMLSCHEMA_URI); 119 if (w3cSchema == null) 120 w3cSchema = schema; 121 Type type = new TypeRef(w3cSchema, ANY_TYPE); 122 decl.setType(type); 123 initType(decl); 124 } 125 126 if (decl.getValueConstraint() != null) { 128 ValidationContextProvider vcp = null; 129 if (contextProviders != null) { 130 vcp = (ValidationContextProvider) contextProviders.get(decl); 131 } 132 decl.setValueConstraint(decl.getType().validateDefault(decl.getValueConstraint(), vcp)); 133 } 134 135 Collection identityConstraints = decl.getIdentityConstraints(); 137 if (identityConstraints != null) { 138 Iterator it = identityConstraints.iterator(); 139 while (it.hasNext()) { 140 IdentityConstraint idConstraint = (IdentityConstraint) it.next(); 141 if (idConstraint.getCategory() == IdentityConstraint.CATEGORY_KEYREF) { 143 IdentityConstraint idRefer = idConstraint.getReferencedKey(); 144 idRefer = (IdentityConstraint) refResolver.resolve(idRefer); 146 idConstraint.setReferencedKey(idRefer); 147 if (!idConstraint.isEqualToKeyRefFields()) { 151 throw new SchemaException("c-props-correct.2", idConstraint); 152 } 153 } 154 } 155 } 156 } 157 158 public void visit(AttributeDeclaration decl) throws SchemaException { 159 if (initialized.contains(decl)) 161 return; 162 initialized.add(decl); 163 164 166 if (decl.getType() != null) { 168 initType(decl); 169 if (!decl.getType().isSimpleType()) throw new SchemaException("src-attribute.3.2", decl); 171 172 if (decl.getType() == decl.getManager().getType(XMLSCHEMA_URI, "NOTATION")) { 174 throw new SchemaException("enumeration-required-notation", decl); 175 } 176 } else { 177 SimpleType type = new SimpleType(decl.getSchema(), SIMPLE_UR_TYPE, null); 178 type.setPrimitive(PrimitiveType.createType(SIMPLE_UR_TYPE)); 179 decl.setType(type); 180 } 181 182 try { 183 if (decl.getValueConstraint() != null) { 185 ValidationContextProvider vcp = null; 186 if (contextProviders != null) { 187 vcp = (ValidationContextProvider) contextProviders.get(decl); 188 } 189 decl.setValueConstraint(decl.getType().validateDefault(decl.getValueConstraint(), vcp)); 190 } 191 } catch (SchemaException e) { 192 throw new SchemaException("a-props-correct.2", decl, e); 193 } 194 } 195 196 public void visit(SimpleType type) throws SchemaException { 197 if (type.getSchema() != schema || initialized.contains(type)) 198 return; 199 initialized.add(type); 200 201 PrimitiveType primitive = null; 203 switch (type.getVariety()) { 204 case SimpleType.VARIETY_ATOMIC : 206 SimpleType base = (SimpleType) initBaseType(type); 207 if (base != null) { 208 type.setVariety(base.getVariety()); 209 type.setItemType(base.getItemType()); 210 List memberTypes = base.getMemberTypes(); 211 if (memberTypes != null) 212 type.addMemberTypes(memberTypes); 213 try { 214 primitive = (PrimitiveType) base.getPrimitive().clone(); 215 } catch (CloneNotSupportedException e) { 216 } 218 } else if (!XMLSCHEMA_URI.equals(type.getNamespace())) { 219 throw new SchemaException("src-simple-type.2", type); 221 } 222 break; 223 case SimpleType.VARIETY_LIST : 224 SimpleType item = initItemType(type); 225 if (item != null) { 226 if (item.getVariety() == SimpleType.VARIETY_LIST) { 227 throw new SchemaException("cos-st-restricts.2.1", type); 229 } 230 primitive = PrimitiveType.createListType(item.getPrimitive()); 231 } else { 232 throw new SchemaException("src-simple-type.3", type); 234 } 235 break; 236 237 case SimpleType.VARIETY_UNION : 238 primitive = initMemberTypes(type); 239 break; 240 } 241 242 if (primitive != null) { 243 type.setPrimitive(primitive); 244 Iterator it = type.getAllFacets().iterator(); 246 while (it.hasNext()) { 247 Facet facet = (Facet) it.next(); 248 ContextLocatorImpl vcp = null; 249 if (contextProviders != null) { 250 vcp = (ContextLocatorImpl) contextProviders.get(facet); 251 vcp.setNotationDeclarations(schema.getNotationDeclarationMap()); 252 } 253 primitive.setFacet(facet, vcp); 254 } 255 } 256 257 checkNotationType(type); 258 } 259 260 public void visit(ComplexType type) throws SchemaException { 261 if (type.getSchema() != schema || initialized.contains(type)) { 262 return; 263 } 264 initialized.add(type); 265 266 ArrayList localPendingTypes = null; 269 if (pendingTypes == null) { 270 localPendingTypes = new ArrayList(); 271 pendingTypes = localPendingTypes; 272 } 273 274 276 if (type.getContentModel() == null) { 278 type.setContentModel(new ContentModel()); 279 } 280 281 Type base = initBaseType(type); 282 283 if (type.isExtension()) { 284 if (base == null) { 285 } else if (base.isSimpleType()) { 287 if (type.getContentModel().getContentType() == TEXT_ONLY) { 288 type.getContentModel().setModel((SimpleType) base); 289 } else { 290 throw new SchemaException("src-ct.1", type); 292 } 293 initAttributes(type, null); 294 } else { 295 initAttributes(type, (ComplexType) base); 296 if (type.getContentModel().getContentType() == TEXT_ONLY) { 297 if (((ComplexType) base).getContentModel().getContentType() != TEXT_ONLY) { 298 throw new SchemaException("src-ct.2", type); 300 } 301 type.getContentModel().setModel(((ComplexType) base).getContentModel().getModel()); 302 } else if (((ComplexType) base).getContentModel().getContentType() == EMPTY) { 303 initContent(type, null); 304 } else if (type.getContentModel().getContentType() == EMPTY) { 305 type.getContentModel().setContentType(((ComplexType) base).getContentModel().getContentType()); 306 initContent(type, (ComplexType) base); 307 } else { 308 if (type.getContentModel().getContentType() 309 != ((ComplexType) base).getContentModel().getContentType()) { 310 throw new SchemaException("cos-ct-extends.1.4.2.2.2.1", type); 312 } 313 initContent(type, (ComplexType) base); 314 } 315 } 316 } else { 317 if (base == null) { 319 initAttributes(type, null); 321 initContent(type, null); 322 } else if (base.isSimpleType()) { 323 if (type.getContentModel().getContentType() == TEXT_ONLY) { 324 throw new SchemaException("src-ct.2", type); 326 } else { 327 throw new SchemaException("src-ct.1", type); 329 } 330 } else { 331 initAttributes(type, (ComplexType) base); 332 if (type.getContentModel().getContentType() == TEXT_ONLY) { 333 if (type.getContentModel().getModel() == null) 334 type.getContentModel().setModel(((ComplexType) base).getContentModel().getModel()); 335 else 336 ((SimpleType) type.getContentModel().getModel()).accept(this); 337 } else { 338 initContent(type, null); 339 } 340 type.checkDerivationValidRestriction(loader); 341 } 342 } 343 344 type.checkUniqueParticleAttribution(); 345 346 if (localPendingTypes != null) { 347 pendingTypes = null; 350 Iterator it = localPendingTypes.iterator(); 351 while (it.hasNext()) { 352 ((SchemaVisitable) it.next()).accept(this); 353 } 354 } 355 } 356 357 private Type initType(Declaration decl) throws SchemaException { 358 Type type = decl.getType(); 359 if (type != null) { 360 type = (Type) refResolver.resolve(type); 361 if (type.isSimpleType() || pendingTypes == null) { 362 type.accept(this); 363 } else { 364 resolveDerivationHierarchy(type); 365 pendingTypes.add(type); 366 } 367 decl.setType(type); 368 } 369 if (!type.isSimpleType() && type.getName() == null) { 370 type.accept(this); 371 } 372 return type; 373 } 374 375 private void resolveDerivationHierarchy(Type type) throws SchemaException { 376 Type previous = type; 377 Type base = type.getBaseType(); 378 while (base != null) { 379 base = (Type) refResolver.resolve(base); 380 previous.setBaseType(base); 381 if (base == type) { 382 String errCode = null; 383 if (type.isSimpleType()) 384 errCode = "st-props-correct.2"; 385 else 386 errCode = "ct-props-correct.3"; 387 throw new SchemaException(errCode, type); 389 } 390 previous = base; 391 base = base.getBaseType(); 392 } 393 } 394 395 private void propagateSubstitution(ElementDeclaration subst, ElementDeclaration decl) { 396 for (subst = (ElementDeclaration) subst.getSubstitutionGroup(); 397 subst != null; 398 subst = (ElementDeclaration) subst.getSubstitutionGroup()) { 399 String errCode = decl.getType().checkTypeDerivationOK(subst.getType(), subst.getBlock(), true); 400 if (errCode != null) 401 return; 402 List list = subst.getSubstitutionElementList(); 403 if (list.indexOf(decl) != -1) 404 return; 405 subst.addSubstitutionMember(decl); 406 } 407 } 408 409 private Type initBaseType(Type type) throws SchemaException { 410 Type base = type.getBaseType(); 411 if (base != null) { 413 if (SIMPLE_UR_TYPE.equals(base.getName())) { 414 if (XMLSCHEMA_URI.equals(schema.getNamespace())) { 415 base = null; 416 ((SimpleType) type).setPrimitive(PrimitiveType.createType(type.getName())); 417 type.setBaseType(base); 418 } else { 419 throw new SchemaException("cos-st-restricts.1.1", type); 421 } 422 } else { 423 base = (Type) refResolver.resolve(base); 425 base.accept(this); 426 type.setBaseType(base); 427 } 428 } 429 430 return base; 431 } 432 433 private Type initBaseType(SimpleType type) throws SchemaException { 434 Type base = initBaseType((Type) type); 435 if (base != null) { 436 if (!base.isSimpleType()) { 437 throw new SchemaException("derivation-ok-restriction.5.1.1", base); 438 } 439 SimpleType simpleBase = (SimpleType) base; 440 SimpleType current = simpleBase; 441 while (current != null) { 442 if (current == type) { 443 throw new SchemaException("st-props-correct.2", type); 445 } 446 current = (SimpleType) current.getBaseType(); 447 } 448 int exclusions = base.getFinal(); 449 if ((exclusions & RESTRICTION) != 0) { 450 throw new SchemaException("st-props-correct.3", type); 452 } else if (simpleBase.getVariety() == SimpleType.VARIETY_LIST && (exclusions & LIST) != 0) { 453 throw new SchemaException("st-props-correct.4.2.1", type); 455 } else if (simpleBase.getVariety() == SimpleType.VARIETY_LIST && (exclusions & LIST) != 0) { 456 throw new SchemaException("st-props-correct.4.2.2", type); 458 } 459 } 460 return base; 461 } 462 463 private Type initBaseType(ComplexType type) throws SchemaException { 464 Type base = initBaseType((Type) type); 465 if (base != null) { 466 Type current = base; 467 while (current != null) { 468 if (current == type) { 469 throw new SchemaException("ct-props-correct.3", type); 471 } 472 current = current.getBaseType(); 473 } 474 int exclusions = base.getFinal(); 475 if (type.isRestriction() && (exclusions & RESTRICTION) != 0) { 476 throw new SchemaException("derivation-ok-restriction.1", type); 478 } else if (type.isExtension() && (exclusions & EXTENSION) != 0) { 479 String errCode = null; 480 if (base.isSimpleType()) 481 errCode = "cos-ct-extends.2.2"; 482 else 483 errCode = "cos-ct-extends.1.1"; 484 throw new SchemaException(errCode, type); 486 } 487 } 488 return base; 489 } 490 491 private SimpleType initItemType(SimpleType type) throws SchemaException { 492 Type itemType = type.getItemType(); 493 if (itemType != null) { 494 itemType = (Type) refResolver.resolve(itemType); 495 itemType.accept(this); 496 type.setItemType(itemType); 497 } 498 return (SimpleType) itemType; 499 } 500 501 private PrimitiveType initMemberTypes(Type type) throws SchemaException { 502 ArrayList primitiveTypes = new ArrayList(); 503 String primitiveName = "union of "; 504 ListIterator it = ((SimpleType) type).getMemberTypes().listIterator(); 505 while (it.hasNext()) { 506 Type memberType = (Type) it.next(); 509 memberType = (Type) refResolver.resolve(memberType); 510 memberType.accept(this); 511 if (!memberType.isSimpleType()) { 512 throw new SchemaException("cos-st-restricts.3.1", memberType); 514 } else if (memberType == type) { 515 throw new SchemaException("src-simple-type.4", type); 517 } else if (((SimpleType) memberType).getVariety() == SimpleType.VARIETY_UNION) { 518 it.remove(); 519 Iterator it2 = ((SimpleType) memberType).getMemberTypes().iterator(); 520 while (it2.hasNext()) { 521 SimpleType m = (SimpleType) it2.next(); 522 if (m == type) { 523 throw new SchemaException("src-simple-type.4", type); 525 } 526 it.add(m); 527 primitiveTypes.add(m.getPrimitive()); 528 if (m.getName() != null) 529 primitiveName += memberType.getName() + " "; 530 else 531 primitiveName += m.getPrimitive().getName() + " "; 532 } 533 } else { 534 it.set(memberType); 535 PrimitiveType primitive = ((SimpleType) memberType).getPrimitive(); 536 primitiveTypes.add(primitive); 537 if (memberType.getName() != null) 538 primitiveName += memberType.getName() + " "; 539 else 540 primitiveName += primitive.getName() + " "; 541 } 542 } 543 return PrimitiveType.createUnionType(primitiveTypes, primitiveName); 544 } 545 546 private void initAttributes(ComplexType type, ComplexType base) throws SchemaException { 547 ArrayList requiredAndDefaultAttributes = new ArrayList(); 548 ArrayList groupContent = new ArrayList(); 550 ArrayList prohibited = new ArrayList(); 551 552 Iterator it = type.getAttributeEntries().iterator(); 553 while (it.hasNext()) { 554 Map.Entry entry = (Map.Entry) it.next(); 555 SchemaComponent comp = refResolver.resolve((SchemaComponent) entry.getValue()); 556 if (comp instanceof AttributeDeclaration) { 558 AttributeDeclaration decl = (AttributeDeclaration) comp; 559 entry.setValue(decl); 560 decl.accept(this); 561 if (decl.getUse() == PROHIBITED) { 562 it.remove(); 563 prohibited.add(decl); 564 } else { 565 checkIDAttribute(type, decl); 566 checkNotationAttribute(type, decl); 567 if (decl.getUse() == REQUIRED || decl.getValueConstraint() != null) 568 requiredAndDefaultAttributes.add(decl); 569 } 570 } 571 else { 573 appendContent(type, (AttributeGroupDefinition) comp, groupContent, null); 575 it.remove(); 576 } 577 } 578 579 it = groupContent.iterator(); 581 while (it.hasNext()) { 582 AttributeDeclaration decl = (AttributeDeclaration) it.next(); 583 decl = (AttributeDeclaration) importInScope(decl, type); 584 decl.accept(this); 585 if (decl.getUse() == PROHIBITED) 586 prohibited.add(decl); 587 else { 588 type.register(decl); 589 checkIDAttribute(type, decl); 590 checkNotationAttribute(type, decl); 591 if (decl.getUse() == REQUIRED || decl.getValueConstraint() != null) 592 requiredAndDefaultAttributes.add(decl); 593 } 594 } 595 596 if (base != null) { 598 it = base.getAttributeDeclarations().iterator(); 599 while (it.hasNext()) { 600 AttributeDeclaration decl = (AttributeDeclaration) it.next(); 601 AttributeDeclaration tDecl = type.getAttributeDeclaration(decl.getNamespace(), decl.getName()); 602 if (tDecl == null) { 603 boolean authorized = true; 604 Iterator it2 = prohibited.iterator(); 605 while (authorized && it2.hasNext()) { 606 AttributeDeclaration p = (AttributeDeclaration) it2.next(); 607 if (p.hasName(decl.getNamespace(), decl.getName())) 608 authorized = false; 609 } 610 if (authorized) { 611 type.register((AttributeDeclaration) decl); 614 checkIDAttribute(type, decl); 615 checkNotationAttribute(type, decl); 616 if (decl.getUse() == REQUIRED || decl.getValueConstraint() != null) 617 requiredAndDefaultAttributes.add(decl); 618 } 619 } else if (type.isExtension()) { 620 throw new SchemaException("ct-props-correct.4", tDecl); 622 } 623 } 624 if (type.isExtension()) 625 type.setAttributeWildcard(wildcardUnion(type.getAttributeWildcard(), base.getAttributeWildcard())); 626 else 627 type.setAttributeWildcard( 628 wildcardIntersection(type.getAttributeWildcard(), base.getAttributeWildcard())); 629 630 } 631 type.setRequiredAndDefaultAttributes(requiredAndDefaultAttributes); 632 } 633 634 void checkIDAttribute(ComplexType type, AttributeDeclaration decl) throws SchemaException { 635 Type attrType = decl.getType(); 636 if (attrType.isDerivedFrom(type.getManager().getType(XMLSCHEMA_URI, "ID"))) { 637 if (type.getIDAttribute() != null) { 638 throw new SchemaException("ct-props-correct.5", type); 640 } 641 type.setIDAttribute(decl); 642 } 643 } 644 645 void checkNotationAttribute(ComplexType type, AttributeDeclaration decl) { 646 Type attrType = decl.getType(); 647 if (attrType.isDerivedFrom(type.getManager().getType(XMLSCHEMA_URI, "NOTATION"))) { 648 type.setNotationAttribute(decl); 649 } 650 } 651 652 void checkNotationType(SimpleType type) throws SchemaException { 653 if (type.isDerivedFrom(type.getManager().getType(XMLSCHEMA_URI, "NOTATION"))) { 654 Facet enumFacet = (Facet) type.getFacets().get(ENUMERATION_TAG); 655 if (enumFacet == null) { 656 throw new SchemaException("enumeration-required-notation", type); 658 } 659 } 660 } 661 662 private void appendContent(ComplexType type, AttributeGroupDefinition def, ArrayList content, ArrayList expanded) 663 throws SchemaException { 664 if (expanded == null) 665 expanded = new ArrayList(); 666 if (expanded.indexOf(def) != -1) { 667 throw new SchemaException("src-attribute_group.3", def); 669 } else { 670 expanded.add(def); 671 type.setAttributeWildcard(wildcardIntersection(type.getAttributeWildcard(), def.getAttributeWildcard())); 672 Iterator it = def.getContents().iterator(); 673 while (it.hasNext()) { 674 SchemaComponent comp = refResolver.resolve((SchemaComponent) it.next()); 675 if (comp instanceof AttributeDeclaration) { 676 content.add(comp); 677 } else { 678 appendContent(type, (AttributeGroupDefinition) comp, content, expanded); 679 } 680 } 681 } 682 } 683 684 private Wildcard wildcardIntersection(Wildcard wc1, Wildcard wc2) throws SchemaException { 685 if (wc1 == null || wc1.isAny()) 686 return wc2; 687 return wc1.wildcardIntersection(wc2); 688 } 689 690 private Wildcard wildcardUnion(Wildcard wc1, Wildcard wc2) throws SchemaException { 691 if (wc1 == null) 692 return wc2; 693 return wc1.wildcardUnion(wc2); 694 } 695 696 private void initContent(ComplexType type, ComplexType base) throws SchemaException { 697 Particle particle = (Particle) type.getContentModel().getModel(); 699 if (particle != null) { 700 particle = initParticle(particle, type, false, null); 701 type.getContentModel().setModel(particle); 702 } 703 704 if (base != null) { 706 Iterator decls = base.getElementDeclarations().iterator(); 707 while (decls.hasNext()) { 708 ElementDeclaration decl = (ElementDeclaration) decls.next(); 709 type.register(decl); 710 } 711 ModelGroup group = null; 712 713 if (particle == null) { 715 group = new SequenceModelGroup(); 716 particle = new Particle(group); 717 type.getContentModel().setModel(particle); 718 } 719 else if ( 721 particle.getMinOccurs() == 1 722 && particle.getMaxOccurs() == 1 723 && particle.getTerm() instanceof SequenceModelGroup) { 724 group = (ModelGroup) particle.getTerm(); 725 } 726 else { 728 group = new SequenceModelGroup(); 729 group.add(particle); 730 particle = new Particle(group); 731 type.getContentModel().setModel(particle); 732 } 733 734 Particle basePart = (Particle) base.getContentModel().getModel(); 738 if (basePart != null) { 739 if (basePart.getTerm() instanceof ModelGroup) { 740 ModelGroup baseGroup = (ModelGroup) basePart.getTerm(); 741 if (baseGroup.size() != 0) { 742 if (basePart.getMinOccurs() == 1 743 && basePart.getMaxOccurs() == 1 744 && baseGroup.getCompositor() == ModelGroup.SEQUENCE) { 745 Iterator it = baseGroup.iterator(); 746 int i = 0; 747 while (it.hasNext()) 748 group.add(i++, it.next()); 749 } else { 750 group.add(0, basePart); 751 } 752 } 753 } else { 754 group.add(0, basePart); 755 } 756 } 757 758 if (particle == null) { 759 type.getContentModel().setContentType(EMPTY); 760 } else { 761 particle.setTerm(group); 762 new ValidationInfoInitializer(particle).initialize(); 763 } 764 } 765 } 766 767 private Particle initParticle(Particle p, SchemaScope scope, boolean duplicate, ArrayList expanded) 768 throws SchemaException { 769 ModelGroup group = null; 770 if (p.getMaxOccurs() == 0) 771 return null; 772 773 try { 774 if (duplicate) { 775 Particle newP = (Particle) p.clone(); 776 if (loader != null) 777 loader.addComp2ComponentContextLocators(newP, p); 778 p = newP; 779 } 780 } catch (CloneNotSupportedException ex) { 781 throw new SchemaException(null, p); 783 } 784 785 if (p.getTerm() instanceof SchemaComponent) { 786 SchemaComponent comp = refResolver.resolve((SchemaComponent) p.getTerm()); 787 if (comp instanceof ElementDeclaration) { 788 comp = importInScope((ElementDeclaration) comp, scope); 789 comp.accept(this); 790 scope.register((ElementDeclaration) comp); 791 p.setTerm(comp); 792 } else if (comp instanceof ModelGroupDefinition) { 793 group = (ModelGroup) ((ModelGroupDefinition) comp).getModelGroup(); 794 if (group.getCompositor() == ModelGroup.ALL && expanded != null) { 797 } 800 if (expanded == null) 801 expanded = new ArrayList(); 802 else if (expanded.indexOf(comp) != -1) { 803 throw new SchemaException("mg-props-correct.2", p); 805 } 806 expanded.add(comp); 807 duplicate = true; 808 } 809 } else if (p.getTerm() instanceof ModelGroup) { 810 group = (ModelGroup) p.getTerm(); 811 } 812 813 if (group != null) { 814 if (expanded == null) 815 expanded = new ArrayList(); 816 group = initGroup(group, scope, duplicate, expanded); 817 if (group.size() == 0 && (group.getCompositor() != ModelGroup.CHOICE || p.getMinOccurs() == 0)) 818 return null; 819 p.setTerm(group); 820 if (group.size() == 1 && p.getMinOccurs() == 1 && p.getMaxOccurs() == 1) { 821 p = (Particle) group.get(0); 822 } 823 } 824 825 new ValidationInfoInitializer(p).initialize(); 826 return p; 827 } 828 829 private ModelGroup initGroup(ModelGroup group, SchemaScope scope, boolean duplicate, ArrayList expanded) 830 throws SchemaException { 831 if (duplicate) 832 group = (ModelGroup) group.clone(); 833 ListIterator it = group.listIterator(); 835 while (it.hasNext()) { 836 Particle p = initParticle((Particle) it.next(), scope, duplicate, expanded); 837 it.set(p); 838 if (p == null) 839 it.remove(); 840 else if (p.getTerm() instanceof ModelGroup) { 841 ModelGroup subgroup = (ModelGroup) p.getTerm(); 842 if (p.getMinOccurs() == 1 843 && p.getMaxOccurs() == 1 844 && subgroup.getCompositor() == group.getCompositor()) { 845 it.remove(); 846 Iterator it2 = subgroup.iterator(); 847 while (it2.hasNext()) 848 it.add(it2.next()); 849 } 850 } 851 } 852 853 return group; 854 } 855 856 private Declaration importInScope(Declaration decl, SchemaScope scope) throws SchemaException { 857 if (decl.getScope() != null) 858 return decl; 859 Declaration result = null; 862 try { 863 result = (Declaration) decl.clone(); 864 if (loader != null) 865 loader.addComp2ComponentContextLocators(result, decl); 866 } catch (CloneNotSupportedException ex) { 867 throw new SchemaException(null, decl); 869 } 870 result.setScope(scope); 871 return result; 872 } 873 874 class ReferenceResolver extends DefaultSchemaVisitor { 875 private static final String RCSRevision = "$Revision: 1.5 $"; 876 private static final String RCSName = "$Name: $"; 877 878 SchemaComponent result = null; 879 880 SchemaComponent resolve(SchemaComponent ref) throws SchemaException { 881 result = ref; 882 ref.accept(this); 883 if (result == null) { 884 throw new SchemaException("src-resolve.3", ref); 886 } 887 return result; 888 } 889 890 public void visit(SchemaComponentRef ref) { 891 result = ref.getSchema().getSchemaComponent(ref.getName(), ref.getType()); 892 } 893 894 public void visit(TypeRef ref) { 895 result = ref.getSchema().getType(ref.getName()); 896 } 897 898 public void visit(ElementDeclarationRef ref) throws SchemaException { 899 result = ref.getSchema().getElementDeclaration(ref.getName()); 900 } 901 902 public void visit(AttributeDeclarationRef ref) throws SchemaException { 903 AttributeDeclaration decl = ref.getSchema().getAttributeDeclaration(ref.getName()); 904 if (decl != null) { 905 try { 906 AttributeDeclaration newDecl = (AttributeDeclaration) decl.clone(); 907 if (loader != null) 908 loader.addComp2ComponentContextLocators(newDecl, decl); 909 decl = newDecl; 910 } catch (CloneNotSupportedException e) { 911 throw new SchemaException(null, decl); 913 } 914 decl.setUse(ref.getUse()); 915 String def = ref.getDefaultValue(); 916 String fix = ref.getFixedValue(); 917 String fixDecl = decl.getFixedValue(); 918 if (fixDecl != null) { 919 if (def != null || (fix != null && !fix.equals(fixDecl))) { 920 throw new SchemaException("au-props-correct.2", decl); 922 } 923 } else if (fix != null) { 924 decl.setFixedValue(fix); 925 decl.setDefaultValue(null); 926 } else if (def != null) { 927 decl.setDefaultValue(def); 928 } 929 } 930 result = decl; 931 } 932 933 public void visit(SimpleBaseTypeRef ref) throws SchemaException { 934 Type base = ref.getType().getBaseType(); 935 if (base.isSimpleType() == false) { 936 ContentModel model = ((ComplexType) base).getContentModel(); 937 if (model.getContentType() == TEXT_ONLY) { 938 result = (SchemaComponent) model.getModel(); 939 return; 940 } 941 } 942 throw new SchemaException("derivation-ok-restriction.5.1.1", base); 944 } 945 946 public void visit(IdentityConstraintRef ref) throws SchemaException { 947 result = ref.getSchema().getIdentityConstraint(ref.getName()); 948 if (result != null && ((IdentityConstraint) result).getCategory() == IdentityConstraint.CATEGORY_KEYREF) 949 result = null; 950 } 951 } 952 953 class ValidationInfoInitializer extends DefaultSchemaVisitor { 954 private static final String RCSRevision = "$Revision: 1.5 $"; 955 private static final String RCSName = "$Name: $"; 956 957 private Particle particle; 958 959 ValidationInfoInitializer(Particle p) { 960 particle = p; 961 } 962 963 void initialize() throws SchemaException { 964 if (particle.getFirstElements().isEmpty() && particle.getFirstWildcards() == null) { 965 ((SchemaVisitable) particle.getTerm()).accept(this); 966 } 967 } 968 969 public void visit(ElementDeclaration decl) { 970 particle.addFirstElement(decl); 971 particle.setMinExtent(particle.getMinOccurs()); 972 particle.setMaxExtent(particle.getMaxOccurs()); 973 } 974 975 public void visit(AllModelGroup group) { 976 Iterator it = group.iterator(); 977 long minExtent = 0; 978 long maxExtent = 0; 979 while (it.hasNext()) { 980 Particle p = (Particle) it.next(); 981 minExtent += p.getMinExtent(); 982 maxExtent += p.getMaxExtent(); 983 particle.addFirstElements(p.getFirstElements()); 984 particle.addFirstWildcards(p.getFirstWildcards()); 985 } 986 if (maxExtent > Integer.MAX_VALUE) 987 maxExtent = Integer.MAX_VALUE; 988 minExtent *= particle.getMinOccurs(); 989 maxExtent *= particle.getMaxOccurs(); 990 if (maxExtent > Integer.MAX_VALUE) 991 maxExtent = Integer.MAX_VALUE; 992 particle.setMinExtent((int) minExtent); 993 particle.setMaxExtent((int) maxExtent); 994 } 995 996 public void visit(ChoiceModelGroup group) { 997 Iterator it = group.iterator(); 998 long minExtent = Integer.MAX_VALUE; 999 long maxExtent = 0; 1000 while (it.hasNext()) { 1001 Particle p = (Particle) it.next(); 1002 if (p.getMinExtent() < minExtent) 1003 minExtent = p.getMinExtent(); 1004 if (p.getMaxExtent() > maxExtent) 1005 maxExtent = p.getMaxExtent(); 1006 particle.addFirstElements(p.getFirstElements()); 1007 particle.addFirstWildcards(p.getFirstWildcards()); 1008 } 1009 minExtent *= particle.getMinOccurs(); 1010 maxExtent *= particle.getMaxOccurs(); 1011 if (maxExtent > Integer.MAX_VALUE) 1012 maxExtent = Integer.MAX_VALUE; 1013 particle.setMinExtent((int) minExtent); 1014 particle.setMaxExtent((int) maxExtent); 1015 } 1016 1017 public void visit(SequenceModelGroup group) { 1018 Iterator it = group.iterator(); 1019 long minExtent = 0; 1020 long maxExtent = 0; 1021 boolean optional = true; 1022 while (it.hasNext()) { 1023 Particle p = (Particle) it.next(); 1024 minExtent += p.getMinExtent(); 1025 maxExtent += p.getMaxExtent(); 1026 if (optional) { 1027 particle.addFirstElements(p.getFirstElements()); 1028 particle.addFirstWildcards(p.getFirstWildcards()); 1029 } 1030 if (p.getMinExtent() > 0) 1031 optional = false; 1032 } 1033 if (maxExtent > Integer.MAX_VALUE) 1034 maxExtent = Integer.MAX_VALUE; 1035 minExtent *= particle.getMinOccurs(); 1036 maxExtent *= particle.getMaxOccurs(); 1037 if (maxExtent > Integer.MAX_VALUE) 1038 maxExtent = Integer.MAX_VALUE; 1039 particle.setMinExtent((int) minExtent); 1040 particle.setMaxExtent((int) maxExtent); 1041 } 1042 1043 public void visit(Wildcard wildcard) { 1044 particle.addFirstWildcard(wildcard); 1045 particle.setMinExtent(particle.getMinOccurs()); 1046 particle.setMaxExtent(particle.getMaxOccurs()); 1047 } 1048 } 1049 1050} 1051 | Popular Tags |