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 package com.sun.org.apache.xerces.internal.impl.xs.traversers; 21 22 import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeFacetException; 23 import com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory; 24 import com.sun.org.apache.xerces.internal.impl.dv.XSFacets; 25 import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType; 26 import com.sun.org.apache.xerces.internal.impl.dv.xs.XSSimpleTypeDecl; 27 import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar; 28 import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols; 29 import com.sun.org.apache.xerces.internal.impl.xs.XSAnnotationImpl; 30 import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeGroupDecl; 31 import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeUseImpl; 32 import com.sun.org.apache.xerces.internal.impl.xs.XSComplexTypeDecl; 33 import com.sun.org.apache.xerces.internal.impl.xs.XSConstraints; 34 import com.sun.org.apache.xerces.internal.impl.xs.XSModelGroupImpl; 35 import com.sun.org.apache.xerces.internal.impl.xs.XSParticleDecl; 36 import com.sun.org.apache.xerces.internal.impl.xs.XSWildcardDecl; 37 import com.sun.org.apache.xerces.internal.impl.xs.util.XInt; 38 import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl; 39 import com.sun.org.apache.xerces.internal.util.DOMUtil; 40 import com.sun.org.apache.xerces.internal.xni.QName; 41 import com.sun.org.apache.xerces.internal.xs.XSAttributeUse; 42 import com.sun.org.apache.xerces.internal.xs.XSConstants; 43 import com.sun.org.apache.xerces.internal.xs.XSObjectList; 44 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; 45 import org.w3c.dom.Element; 46 47 /** 48 * A complex type definition schema component traverser. 49 * 50 * <complexType 51 * abstract = boolean : false 52 * block = (#all | List of (extension | restriction)) 53 * final = (#all | List of (extension | restriction)) 54 * id = ID 55 * mixed = boolean : false 56 * name = NCName 57 * {any attributes with non-schema namespace . . .}> 58 * Content: (annotation?, (simpleContent | complexContent | 59 * ((group | all | choice | sequence)?, 60 * ((attribute | attributeGroup)*, anyAttribute?)))) 61 * </complexType> 62 * 63 * @xerces.internal 64 * 65 * @version $Id: XSDComplexTypeTraverser.java,v 1.8 2010-11-01 04:40:02 joehw Exp $ 66 */ 67 68 class XSDComplexTypeTraverser extends XSDAbstractParticleTraverser { 69 70 // size of stack to hold globals: 71 private final static int GLOBAL_NUM = 11; 72 73 private static XSParticleDecl fErrorContent = null; 74 private static XSWildcardDecl fErrorWildcard = null; 75 private static XSParticleDecl getErrorContent() { 76 if (fErrorContent == null) { 77 XSParticleDecl particle = new XSParticleDecl(); 78 particle.fType = XSParticleDecl.PARTICLE_WILDCARD; 79 particle.fValue = getErrorWildcard(); 80 particle.fMinOccurs = 0; 81 particle.fMaxOccurs = SchemaSymbols.OCCURRENCE_UNBOUNDED; 82 XSModelGroupImpl group = new XSModelGroupImpl(); 83 group.fCompositor = XSModelGroupImpl.MODELGROUP_SEQUENCE; 84 group.fParticleCount = 1; 85 group.fParticles = new XSParticleDecl[1]; 86 group.fParticles[0] = particle; 87 XSParticleDecl errorContent = new XSParticleDecl(); 88 errorContent.fType = XSParticleDecl.PARTICLE_MODELGROUP; 89 errorContent.fValue = group; 90 fErrorContent = errorContent; 91 } 92 return fErrorContent; 93 } 94 private static XSWildcardDecl getErrorWildcard() { 95 if (fErrorWildcard == null) { 96 XSWildcardDecl wildcard = new XSWildcardDecl(); 97 wildcard.fProcessContents = XSWildcardDecl.PC_SKIP; 98 fErrorWildcard = wildcard; 99 } 100 return fErrorWildcard; 101 } 102 103 // globals for building XSComplexTypeDecls 104 private String fName = null; 105 private String fTargetNamespace = null; 106 private short fDerivedBy = XSConstants.DERIVATION_RESTRICTION; 107 private short fFinal = XSConstants.DERIVATION_NONE; 108 private short fBlock = XSConstants.DERIVATION_NONE; 109 private short fContentType = XSComplexTypeDecl.CONTENTTYPE_EMPTY; 110 private XSTypeDefinition fBaseType = null; 111 private XSAttributeGroupDecl fAttrGrp = null; 112 private XSSimpleType fXSSimpleType = null; 113 private XSParticleDecl fParticle = null; 114 private boolean fIsAbstract = false; 115 private XSComplexTypeDecl fComplexTypeDecl = null; 116 private XSAnnotationImpl [] fAnnotations = null; 117 118 // our own little stack to retain state when getGlobalDecls is called: 119 private Object [] fGlobalStore = null; 120 private int fGlobalStorePos = 0; 121 122 XSDComplexTypeTraverser (XSDHandler handler, 123 XSAttributeChecker gAttrCheck) { 124 super(handler, gAttrCheck); 125 } 126 127 128 private static final boolean DEBUG=false; 129 130 private static final class ComplexTypeRecoverableError extends Exception { 131 132 private static final long serialVersionUID = 6802729912091130335L; 133 134 Object[] errorSubstText=null; 135 Element errorElem = null; 136 ComplexTypeRecoverableError() { 137 super(); 138 } 139 ComplexTypeRecoverableError(String msgKey, Object[] args, Element e) { 140 super(msgKey); 141 errorSubstText=args; 142 errorElem = e; 143 } 144 145 } 146 147 /** 148 * Traverse local complexType declarations 149 * 150 * @param Element 151 * @param XSDocumentInfo 152 * @param SchemaGrammar 153 * @return XSComplexTypeDecl 154 */ 155 XSComplexTypeDecl traverseLocal(Element complexTypeNode, 156 XSDocumentInfo schemaDoc, 157 SchemaGrammar grammar) { 158 159 160 Object[] attrValues = fAttrChecker.checkAttributes(complexTypeNode, false, 161 schemaDoc); 162 String complexTypeName = genAnonTypeName(complexTypeNode); 163 contentBackup(); 164 XSComplexTypeDecl type = traverseComplexTypeDecl (complexTypeNode, 165 complexTypeName, attrValues, schemaDoc, grammar); 166 contentRestore(); 167 // need to add the type to the grammar for later constraint checking 168 grammar.addComplexTypeDecl(type, fSchemaHandler.element2Locator(complexTypeNode)); 169 type.setIsAnonymous(); 170 fAttrChecker.returnAttrArray(attrValues, schemaDoc); 171 172 return type; 173 } 174 175 /** 176 * Traverse global complexType declarations 177 * 178 * @param Element 179 * @param XSDocumentInfo 180 * @param SchemaGrammar 181 * @return XSComplexTypeDecXSComplexTypeDecl 182 */ 183 XSComplexTypeDecl traverseGlobal (Element complexTypeNode, 184 XSDocumentInfo schemaDoc, 185 SchemaGrammar grammar) { 186 187 Object[] attrValues = fAttrChecker.checkAttributes(complexTypeNode, true, 188 schemaDoc); 189 String complexTypeName = (String) attrValues[XSAttributeChecker.ATTIDX_NAME]; 190 contentBackup(); 191 XSComplexTypeDecl type = traverseComplexTypeDecl (complexTypeNode, 192 complexTypeName, attrValues, schemaDoc, grammar); 193 contentRestore(); 194 // need to add the type to the grammar for later constraint checking 195 grammar.addComplexTypeDecl(type, fSchemaHandler.element2Locator(complexTypeNode)); 196 197 if (complexTypeName == null) { 198 reportSchemaError("s4s-att-must-appear", new Object[]{SchemaSymbols.ELT_COMPLEXTYPE, SchemaSymbols.ATT_NAME}, complexTypeNode); 199 type = null; 200 } else { 201 if (grammar.getGlobalTypeDecl(type.getName()) == null) { 202 grammar.addGlobalComplexTypeDecl(type); 203 } 204 205 // also add it to extended map 206 final String loc = fSchemaHandler.schemaDocument2SystemId(schemaDoc); 207 final XSTypeDefinition type2 = grammar.getGlobalTypeDecl(type.getName(), loc); 208 if (type2 == null) { 209 grammar.addGlobalComplexTypeDecl(type, loc); 210 } 211 212 // handle duplicates 213 if (fSchemaHandler.fTolerateDuplicates) { 214 if (type2 != null) { 215 if (type2 instanceof XSComplexTypeDecl) { 216 type = (XSComplexTypeDecl) type2; 217 } 218 } 219 fSchemaHandler.addGlobalTypeDecl(type); 220 } 221 } 222 223 fAttrChecker.returnAttrArray(attrValues, schemaDoc); 224 225 return type; 226 } 227 228 229 private XSComplexTypeDecl traverseComplexTypeDecl(Element complexTypeDecl, 230 String complexTypeName, 231 Object[] attrValues, 232 XSDocumentInfo schemaDoc, 233 SchemaGrammar grammar) { 234 235 fComplexTypeDecl = new XSComplexTypeDecl(); 236 fAttrGrp = new XSAttributeGroupDecl(); 237 Boolean abstractAtt = (Boolean) attrValues[XSAttributeChecker.ATTIDX_ABSTRACT]; 238 XInt blockAtt = (XInt) attrValues[XSAttributeChecker.ATTIDX_BLOCK]; 239 Boolean mixedAtt = (Boolean) attrValues[XSAttributeChecker.ATTIDX_MIXED]; 240 XInt finalAtt = (XInt) attrValues[XSAttributeChecker.ATTIDX_FINAL]; 241 242 fName = complexTypeName; 243 fComplexTypeDecl.setName(fName); 244 fTargetNamespace = schemaDoc.fTargetNamespace; 245 246 fBlock = blockAtt == null ? schemaDoc.fBlockDefault : blockAtt.shortValue(); 247 fFinal = finalAtt == null ? schemaDoc.fFinalDefault : finalAtt.shortValue(); 248 //discard valid Block/Final 'Default' values that are invalid for Block/Final 249 fBlock &= (XSConstants.DERIVATION_EXTENSION | XSConstants.DERIVATION_RESTRICTION); 250 fFinal &= (XSConstants.DERIVATION_EXTENSION | XSConstants.DERIVATION_RESTRICTION); 251 252 fIsAbstract = (abstractAtt != null && abstractAtt.booleanValue()); 253 fAnnotations = null; 254 255 Element child = null; 256 257 try { 258 // --------------------------------------------------------------- 259 // First, handle any ANNOTATION declaration and get next child 260 // --------------------------------------------------------------- 261 child = DOMUtil.getFirstChildElement(complexTypeDecl); 262 if(child != null) { 263 if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) { 264 addAnnotation(traverseAnnotationDecl(child, attrValues, false, schemaDoc)); 265 child = DOMUtil.getNextSiblingElement(child); 266 } 267 else { 268 String text = DOMUtil.getSyntheticAnnotation(complexTypeDecl); 269 if (text != null) { 270 addAnnotation(traverseSyntheticAnnotation(complexTypeDecl, text, attrValues, false, schemaDoc)); 271 } 272 } 273 if (child !=null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) { 274 throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1", 275 new Object[]{fName,SchemaSymbols.ELT_ANNOTATION}, 276 child); 277 } 278 } 279 else { 280 String text = DOMUtil.getSyntheticAnnotation(complexTypeDecl); 281 if (text != null) { 282 addAnnotation(traverseSyntheticAnnotation(complexTypeDecl, text, attrValues, false, schemaDoc)); 283 } 284 } 285 // --------------------------------------------------------------- 286 // Process the content of the complex type definition 287 // --------------------------------------------------------------- 288 if (child==null) { 289 // 290 // EMPTY complexType with complexContent 291 // 292 293 // set the base to the anyType 294 fBaseType = SchemaGrammar.fAnyType; 295 fDerivedBy = XSConstants.DERIVATION_RESTRICTION; 296 processComplexContent(child, mixedAtt.booleanValue(), false, 297 schemaDoc, grammar); 298 } 299 else if (DOMUtil.getLocalName(child).equals 300 (SchemaSymbols.ELT_SIMPLECONTENT)) { 301 // 302 // SIMPLE CONTENT 303 // 304 traverseSimpleContent(child, schemaDoc, grammar); 305 Element elemTmp = DOMUtil.getNextSiblingElement(child); 306 if (elemTmp != null) { 307 String siblingName = DOMUtil.getLocalName(elemTmp); 308 throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1", 309 new Object[]{fName,siblingName}, 310 elemTmp); 311 } 312 } 313 else if (DOMUtil.getLocalName(child).equals 314 (SchemaSymbols.ELT_COMPLEXCONTENT)) { 315 traverseComplexContent(child, mixedAtt.booleanValue(), 316 schemaDoc, grammar); 317 Element elemTmp = DOMUtil.getNextSiblingElement(child); 318 if (elemTmp != null) { 319 String siblingName = DOMUtil.getLocalName(elemTmp); 320 throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1", 321 new Object[]{fName,siblingName}, 322 elemTmp); 323 } 324 } 325 else { 326 // 327 // We must have .... 328 // GROUP, ALL, SEQUENCE or CHOICE, followed by optional attributes 329 // Note that it's possible that only attributes are specified. 330 // 331 332 // set the base to the anyType 333 fBaseType = SchemaGrammar.fAnyType; 334 fDerivedBy = XSConstants.DERIVATION_RESTRICTION; 335 processComplexContent(child, mixedAtt.booleanValue(), false, 336 schemaDoc, grammar); 337 } 338 339 } 340 catch (ComplexTypeRecoverableError e) { 341 handleComplexTypeError(e.getMessage(), e.errorSubstText, 342 e.errorElem); 343 } 344 345 if (DEBUG) { 346 System.out.println(fName); 347 } 348 fComplexTypeDecl.setValues(fName, fTargetNamespace, fBaseType, 349 fDerivedBy, fFinal, fBlock, fContentType, fIsAbstract, 350 fAttrGrp, fXSSimpleType, fParticle, new XSObjectListImpl(fAnnotations, 351 fAnnotations == null? 0 : fAnnotations.length)); 352 return fComplexTypeDecl; 353 } 354 355 356 private void traverseSimpleContent(Element simpleContentElement, 357 XSDocumentInfo schemaDoc, 358 SchemaGrammar grammar) 359 throws ComplexTypeRecoverableError { 360 361 362 Object[] simpleContentAttrValues = fAttrChecker.checkAttributes(simpleContentElement, false, 363 schemaDoc); 364 365 // ----------------------------------------------------------------------- 366 // Set content type 367 // ----------------------------------------------------------------------- 368 fContentType = XSComplexTypeDecl.CONTENTTYPE_SIMPLE; 369 fParticle = null; 370 371 Element simpleContent = DOMUtil.getFirstChildElement(simpleContentElement); 372 if (simpleContent != null && DOMUtil.getLocalName(simpleContent).equals(SchemaSymbols.ELT_ANNOTATION)) { 373 addAnnotation(traverseAnnotationDecl(simpleContent, simpleContentAttrValues, false, schemaDoc)); 374 simpleContent = DOMUtil.getNextSiblingElement(simpleContent); 375 } 376 else { 377 String text = DOMUtil.getSyntheticAnnotation(simpleContentElement); 378 if (text != null) { 379 addAnnotation(traverseSyntheticAnnotation(simpleContentElement, text, simpleContentAttrValues, false, schemaDoc)); 380 } 381 } 382 383 // If there are no children, return 384 if (simpleContent==null) { 385 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 386 throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.2", 387 new Object[]{fName,SchemaSymbols.ELT_SIMPLECONTENT}, 388 simpleContentElement); 389 } 390 391 // ----------------------------------------------------------------------- 392 // The content should be either "restriction" or "extension" 393 // ----------------------------------------------------------------------- 394 String simpleContentName = DOMUtil.getLocalName(simpleContent); 395 if (simpleContentName.equals(SchemaSymbols.ELT_RESTRICTION)) 396 fDerivedBy = XSConstants.DERIVATION_RESTRICTION; 397 else if (simpleContentName.equals(SchemaSymbols.ELT_EXTENSION)) 398 fDerivedBy = XSConstants.DERIVATION_EXTENSION; 399 else { 400 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 401 throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1", 402 new Object[]{fName,simpleContentName}, 403 simpleContent); 404 } 405 Element elemTmp = DOMUtil.getNextSiblingElement(simpleContent); 406 if (elemTmp != null) { 407 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 408 String siblingName = DOMUtil.getLocalName(elemTmp); 409 throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1", 410 new Object[]{fName,siblingName}, 411 elemTmp); 412 } 413 414 Object [] derivationTypeAttrValues = fAttrChecker.checkAttributes(simpleContent, false, 415 schemaDoc); 416 QName baseTypeName = (QName) derivationTypeAttrValues[XSAttributeChecker.ATTIDX_BASE]; 417 418 419 // ----------------------------------------------------------------------- 420 // Need a base type. 421 // ----------------------------------------------------------------------- 422 if (baseTypeName==null) { 423 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 424 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 425 throw new ComplexTypeRecoverableError("s4s-att-must-appear", 426 new Object[]{simpleContentName, "base"}, simpleContent); 427 } 428 429 XSTypeDefinition type = (XSTypeDefinition)fSchemaHandler.getGlobalDecl(schemaDoc, 430 XSDHandler.TYPEDECL_TYPE, baseTypeName, 431 simpleContent); 432 if (type==null) { 433 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 434 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 435 throw new ComplexTypeRecoverableError(); 436 } 437 438 fBaseType = type; 439 440 XSSimpleType baseValidator = null; 441 XSComplexTypeDecl baseComplexType = null; 442 int baseFinalSet = 0; 443 444 // If the base type is complex, it must have simpleContent 445 if ((type.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE)) { 446 447 baseComplexType = (XSComplexTypeDecl)type; 448 baseFinalSet = baseComplexType.getFinal(); 449 // base is a CT with simple content (both restriction and extension are OK) 450 if (baseComplexType.getContentType() == XSComplexTypeDecl.CONTENTTYPE_SIMPLE) { 451 baseValidator = (XSSimpleType)baseComplexType.getSimpleType(); 452 } 453 // base is a CT with mixed/emptiable content (only restriction is OK) 454 else if (fDerivedBy == XSConstants.DERIVATION_RESTRICTION && 455 baseComplexType.getContentType() == XSComplexTypeDecl.CONTENTTYPE_MIXED && 456 ((XSParticleDecl)baseComplexType.getParticle()).emptiable()) { 457 } 458 else { 459 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 460 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 461 throw new ComplexTypeRecoverableError("src-ct.2.1", 462 new Object[]{fName, baseComplexType.getName()}, simpleContent); 463 } 464 } 465 else { 466 baseValidator = (XSSimpleType)type; 467 // base is a ST (only extension is OK) 468 if (fDerivedBy == XSConstants.DERIVATION_RESTRICTION) { 469 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 470 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 471 throw new ComplexTypeRecoverableError("src-ct.2.1", 472 new Object[]{fName, baseValidator.getName()}, simpleContent); 473 } 474 baseFinalSet=baseValidator.getFinal(); 475 } 476 477 // ----------------------------------------------------------------------- 478 // Check that the base permits the derivation 479 // ----------------------------------------------------------------------- 480 if ((baseFinalSet & fDerivedBy)!=0) { 481 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 482 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 483 String errorKey = (fDerivedBy==XSConstants.DERIVATION_EXTENSION) ? 484 "cos-ct-extends.1.1" : "derivation-ok-restriction.1"; 485 throw new ComplexTypeRecoverableError(errorKey, 486 new Object[]{fName, fBaseType.getName()}, simpleContent); 487 } 488 489 // ----------------------------------------------------------------------- 490 // Skip over any potential annotations 491 // ----------------------------------------------------------------------- 492 Element scElement = simpleContent; 493 simpleContent = DOMUtil.getFirstChildElement(simpleContent); 494 if (simpleContent != null) { 495 // traverse annotation if any 496 497 if (DOMUtil.getLocalName(simpleContent).equals(SchemaSymbols.ELT_ANNOTATION)) { 498 addAnnotation(traverseAnnotationDecl(simpleContent, derivationTypeAttrValues, false, schemaDoc)); 499 simpleContent = DOMUtil.getNextSiblingElement(simpleContent); 500 } 501 else { 502 String text = DOMUtil.getSyntheticAnnotation(scElement); 503 if (text != null) { 504 addAnnotation(traverseSyntheticAnnotation(scElement, text, derivationTypeAttrValues, false, schemaDoc)); 505 } 506 } 507 508 if (simpleContent !=null && 509 DOMUtil.getLocalName(simpleContent).equals(SchemaSymbols.ELT_ANNOTATION)){ 510 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 511 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 512 throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1", 513 new Object[]{fName,SchemaSymbols.ELT_ANNOTATION}, 514 simpleContent); 515 } 516 } 517 else { 518 String text = DOMUtil.getSyntheticAnnotation(scElement); 519 if (text != null) { 520 addAnnotation(traverseSyntheticAnnotation(scElement, text, derivationTypeAttrValues, false, schemaDoc)); 521 } 522 } 523 524 // ----------------------------------------------------------------------- 525 // Process a RESTRICTION 526 // ----------------------------------------------------------------------- 527 if (fDerivedBy == XSConstants.DERIVATION_RESTRICTION) { 528 529 // ----------------------------------------------------------------------- 530 // There may be a simple type definition in the restriction element 531 // The data type validator will be based on it, if specified 532 // ----------------------------------------------------------------------- 533 if (simpleContent !=null && 534 DOMUtil.getLocalName(simpleContent).equals(SchemaSymbols.ELT_SIMPLETYPE )) { 535 536 XSSimpleType dv = fSchemaHandler.fSimpleTypeTraverser.traverseLocal( 537 simpleContent, schemaDoc, grammar); 538 if (dv == null) { 539 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 540 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 541 throw new ComplexTypeRecoverableError(); 542 } 543 //check that this datatype validator is validly derived from the base 544 //according to derivation-ok-restriction 5.1.2.1 545 546 if (baseValidator != null && 547 !XSConstraints.checkSimpleDerivationOk(dv, baseValidator, 548 baseValidator.getFinal())) { 549 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 550 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 551 throw new ComplexTypeRecoverableError("derivation-ok-restriction.5.2.2.1", 552 new Object[]{fName, dv.getName(), baseValidator.getName()}, 553 simpleContent); 554 } 555 baseValidator = dv; 556 simpleContent = DOMUtil.getNextSiblingElement(simpleContent); 557 } 558 559 // this only happens when restricting a mixed/emptiable CT 560 // but there is no <simpleType>, which is required 561 if (baseValidator == null) { 562 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 563 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 564 throw new ComplexTypeRecoverableError("src-ct.2.2", 565 new Object[]{fName}, simpleContent); 566 } 567 568 // ----------------------------------------------------------------------- 569 // Traverse any facets 570 // ----------------------------------------------------------------------- 571 Element attrNode = null; 572 XSFacets facetData = null; 573 short presentFacets = 0 ; 574 short fixedFacets = 0 ; 575 576 if (simpleContent!=null) { 577 FacetInfo fi = traverseFacets(simpleContent, baseValidator, schemaDoc); 578 attrNode = fi.nodeAfterFacets; 579 facetData = fi.facetdata; 580 presentFacets = fi.fPresentFacets; 581 fixedFacets = fi.fFixedFacets; 582 } 583 584 String name = genAnonTypeName(simpleContentElement); 585 fXSSimpleType = fSchemaHandler.fDVFactory.createTypeRestriction(name,schemaDoc.fTargetNamespace,(short)0,baseValidator,null); 586 try{ 587 fValidationState.setNamespaceSupport(schemaDoc.fNamespaceSupport); 588 fXSSimpleType.applyFacets(facetData, presentFacets, fixedFacets, fValidationState); 589 }catch(InvalidDatatypeFacetException ex){ 590 reportSchemaError(ex.getKey(), ex.getArgs(), simpleContent); 591 // Recreate the type, ignoring the facets 592 fXSSimpleType = fSchemaHandler.fDVFactory.createTypeRestriction(name,schemaDoc.fTargetNamespace,(short)0,baseValidator,null); 593 } 594 if (fXSSimpleType instanceof XSSimpleTypeDecl) { 595 ((XSSimpleTypeDecl)fXSSimpleType).setAnonymous(true); 596 } 597 598 // ----------------------------------------------------------------------- 599 // Traverse any attributes 600 // ----------------------------------------------------------------------- 601 if (attrNode != null) { 602 if (!isAttrOrAttrGroup(attrNode)) { 603 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 604 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 605 throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1", 606 new Object[]{fName,DOMUtil.getLocalName(attrNode)}, 607 attrNode); 608 } 609 Element node=traverseAttrsAndAttrGrps(attrNode,fAttrGrp, 610 schemaDoc,grammar,fComplexTypeDecl); 611 if (node!=null) { 612 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 613 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 614 throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1", 615 new Object[]{fName,DOMUtil.getLocalName(node)}, 616 node); 617 } 618 } 619 620 try { 621 mergeAttributes(baseComplexType.getAttrGrp(), fAttrGrp, fName, false, simpleContentElement); 622 } catch (ComplexTypeRecoverableError e) { 623 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 624 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 625 throw e; 626 } 627 // Prohibited uses must be removed after merge for RESTRICTION 628 fAttrGrp.removeProhibitedAttrs(); 629 630 Object[] errArgs=fAttrGrp.validRestrictionOf(fName, baseComplexType.getAttrGrp()); 631 if (errArgs != null) { 632 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 633 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 634 throw new ComplexTypeRecoverableError((String)errArgs[errArgs.length-1], 635 errArgs, attrNode); 636 } 637 638 } 639 // ----------------------------------------------------------------------- 640 // Process a EXTENSION 641 // ----------------------------------------------------------------------- 642 else { 643 fXSSimpleType = baseValidator; 644 if (simpleContent != null) { 645 // ----------------------------------------------------------------------- 646 // Traverse any attributes 647 // ----------------------------------------------------------------------- 648 Element attrNode = simpleContent; 649 if (!isAttrOrAttrGroup(attrNode)) { 650 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 651 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 652 throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1", 653 new Object[]{fName,DOMUtil.getLocalName(attrNode)}, 654 attrNode); 655 } 656 Element node=traverseAttrsAndAttrGrps(attrNode,fAttrGrp, 657 schemaDoc,grammar,fComplexTypeDecl); 658 659 if (node!=null) { 660 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 661 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 662 throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1", 663 new Object[]{fName,DOMUtil.getLocalName(node)}, 664 node); 665 } 666 // Remove prohibited uses. Should be done prior to any merge. 667 fAttrGrp.removeProhibitedAttrs(); 668 } 669 670 if (baseComplexType != null) { 671 try { 672 mergeAttributes(baseComplexType.getAttrGrp(), fAttrGrp, fName, true, simpleContentElement); 673 } catch (ComplexTypeRecoverableError e) { 674 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 675 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 676 throw e; 677 } 678 } 679 } 680 // and finally, since we've nothing more to traverse, we can 681 // return the attributes (and thereby reset the namespace support) 682 fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); 683 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 684 } 685 686 private void traverseComplexContent(Element complexContentElement, 687 boolean mixedOnType, XSDocumentInfo schemaDoc, 688 SchemaGrammar grammar) 689 throws ComplexTypeRecoverableError { 690 691 692 Object[] complexContentAttrValues = fAttrChecker.checkAttributes(complexContentElement, false, 693 schemaDoc); 694 695 696 // ----------------------------------------------------------------------- 697 // Determine if this is mixed content 698 // ----------------------------------------------------------------------- 699 boolean mixedContent = mixedOnType; 700 Boolean mixedAtt = (Boolean) complexContentAttrValues[XSAttributeChecker.ATTIDX_MIXED]; 701 if (mixedAtt != null) { 702 mixedContent = mixedAtt.booleanValue(); 703 } 704 705 706 // ----------------------------------------------------------------------- 707 // Since the type must have complex content, set the simple type validators 708 // to null 709 // ----------------------------------------------------------------------- 710 fXSSimpleType = null; 711 712 Element complexContent = DOMUtil.getFirstChildElement(complexContentElement); 713 if (complexContent != null && DOMUtil.getLocalName(complexContent).equals(SchemaSymbols.ELT_ANNOTATION)) { 714 addAnnotation(traverseAnnotationDecl(complexContent, complexContentAttrValues, false, schemaDoc)); 715 complexContent = DOMUtil.getNextSiblingElement(complexContent); 716 } 717 else { 718 String text = DOMUtil.getSyntheticAnnotation(complexContentElement); 719 if (text != null) { 720 addAnnotation(traverseSyntheticAnnotation(complexContentElement, text, complexContentAttrValues, false, schemaDoc)); 721 } 722 } 723 724 // If there are no children, return 725 if (complexContent==null) { 726 fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); 727 throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.2", 728 new Object[]{fName,SchemaSymbols.ELT_COMPLEXCONTENT}, 729 complexContentElement); 730 } 731 732 // ----------------------------------------------------------------------- 733 // The content should be either "restriction" or "extension" 734 // ----------------------------------------------------------------------- 735 String complexContentName = DOMUtil.getLocalName(complexContent); 736 if (complexContentName.equals(SchemaSymbols.ELT_RESTRICTION)) 737 fDerivedBy = XSConstants.DERIVATION_RESTRICTION; 738 else if (complexContentName.equals(SchemaSymbols.ELT_EXTENSION)) 739 fDerivedBy = XSConstants.DERIVATION_EXTENSION; 740 else { 741 fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); 742 throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1", 743 new Object[]{fName, complexContentName}, complexContent); 744 } 745 Element elemTmp = DOMUtil.getNextSiblingElement(complexContent); 746 if (elemTmp != null) { 747 fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); 748 String siblingName = DOMUtil.getLocalName(elemTmp); 749 throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1", 750 new Object[]{fName, siblingName}, elemTmp); 751 } 752 753 Object[] derivationTypeAttrValues = fAttrChecker.checkAttributes(complexContent, false, 754 schemaDoc); 755 QName baseTypeName = (QName) derivationTypeAttrValues[XSAttributeChecker.ATTIDX_BASE]; 756 757 758 // ----------------------------------------------------------------------- 759 // Need a base type. Check that it's a complex type 760 // ----------------------------------------------------------------------- 761 if (baseTypeName==null) { 762 fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); 763 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 764 throw new ComplexTypeRecoverableError("s4s-att-must-appear", 765 new Object[]{complexContentName, "base"}, complexContent); 766 } 767 768 XSTypeDefinition type = (XSTypeDefinition)fSchemaHandler.getGlobalDecl(schemaDoc, 769 XSDHandler.TYPEDECL_TYPE, 770 baseTypeName, 771 complexContent); 772 773 if (type==null) { 774 fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); 775 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 776 throw new ComplexTypeRecoverableError(); 777 } 778 779 if (! (type instanceof XSComplexTypeDecl)) { 780 fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); 781 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 782 throw new ComplexTypeRecoverableError("src-ct.1", 783 new Object[]{fName, type.getName()}, complexContent); 784 } 785 XSComplexTypeDecl baseType = (XSComplexTypeDecl)type; 786 fBaseType = baseType; 787 788 // ----------------------------------------------------------------------- 789 // Check that the base permits the derivation 790 // ----------------------------------------------------------------------- 791 if ((baseType.getFinal() & fDerivedBy)!=0) { 792 fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); 793 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 794 String errorKey = (fDerivedBy==XSConstants.DERIVATION_EXTENSION) ? 795 "cos-ct-extends.1.1" : "derivation-ok-restriction.1"; 796 throw new ComplexTypeRecoverableError(errorKey, 797 new Object[]{fName, fBaseType.getName()}, complexContent); 798 } 799 800 // ----------------------------------------------------------------------- 801 // Skip over any potential annotations 802 // ----------------------------------------------------------------------- 803 complexContent = DOMUtil.getFirstChildElement(complexContent); 804 805 if (complexContent != null) { 806 // traverse annotation if any 807 if (DOMUtil.getLocalName(complexContent).equals(SchemaSymbols.ELT_ANNOTATION)) { 808 addAnnotation(traverseAnnotationDecl(complexContent, derivationTypeAttrValues, false, schemaDoc)); 809 complexContent = DOMUtil.getNextSiblingElement(complexContent); 810 } 811 else { 812 String text = DOMUtil.getSyntheticAnnotation(complexContent); 813 if (text != null) { 814 addAnnotation(traverseSyntheticAnnotation(complexContent, text, derivationTypeAttrValues, false, schemaDoc)); 815 } 816 } 817 if (complexContent !=null && 818 DOMUtil.getLocalName(complexContent).equals(SchemaSymbols.ELT_ANNOTATION)){ 819 fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); 820 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 821 throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1", 822 new Object[]{fName,SchemaSymbols.ELT_ANNOTATION}, complexContent); 823 } 824 } 825 else { 826 String text = DOMUtil.getSyntheticAnnotation(complexContent); 827 if (text != null) { 828 addAnnotation(traverseSyntheticAnnotation(complexContent, text, derivationTypeAttrValues, false, schemaDoc)); 829 } 830 } 831 // ----------------------------------------------------------------------- 832 // Process the content. Note: should I try to catch any complexType errors 833 // here in order to return the attr array? 834 // ----------------------------------------------------------------------- 835 try { 836 processComplexContent(complexContent, mixedContent, true, schemaDoc, 837 grammar); 838 } catch (ComplexTypeRecoverableError e) { 839 fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); 840 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 841 throw e; 842 } 843 844 // ----------------------------------------------------------------------- 845 // Compose the final content and attribute uses 846 // ----------------------------------------------------------------------- 847 XSParticleDecl baseContent = (XSParticleDecl)baseType.getParticle(); 848 if (fDerivedBy==XSConstants.DERIVATION_RESTRICTION) { 849 850 // This is an RESTRICTION 851 852 // N.B. derivation-ok-restriction.5.3 is checked under schema 853 // full checking. That's because we need to wait until locals are 854 // traversed so that occurrence information is correct. 855 856 857 if (fContentType == XSComplexTypeDecl.CONTENTTYPE_MIXED && 858 baseType.getContentType() != XSComplexTypeDecl.CONTENTTYPE_MIXED) { 859 fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); 860 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 861 throw new ComplexTypeRecoverableError("derivation-ok-restriction.5.4.1.2", 862 new Object[]{fName, baseType.getName()}, 863 complexContent); 864 } 865 866 try { 867 mergeAttributes(baseType.getAttrGrp(), fAttrGrp, fName, false, complexContent); 868 } catch (ComplexTypeRecoverableError e) { 869 fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); 870 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 871 throw e; 872 } 873 // Remove prohibited uses. Must be done after merge for RESTRICTION. 874 fAttrGrp.removeProhibitedAttrs(); 875 876 if (baseType != SchemaGrammar.fAnyType) { 877 Object[] errArgs = fAttrGrp.validRestrictionOf(fName, baseType.getAttrGrp()); 878 if (errArgs != null) { 879 fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); 880 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 881 throw new ComplexTypeRecoverableError((String)errArgs[errArgs.length-1], 882 errArgs, complexContent); 883 } 884 } 885 } 886 else { 887 888 // This is an EXTENSION 889 890 // Create the particle 891 if (fParticle == null) { 892 fContentType = baseType.getContentType(); 893 fXSSimpleType = (XSSimpleType)baseType.getSimpleType(); 894 fParticle = baseContent; 895 } 896 else if (baseType.getContentType() == XSComplexTypeDecl.CONTENTTYPE_EMPTY) { 897 } 898 else { 899 // 900 // Check if the contentType of the base is consistent with the new type 901 // cos-ct-extends.1.4.3.2 902 if (fContentType == XSComplexTypeDecl.CONTENTTYPE_ELEMENT && 903 baseType.getContentType() != XSComplexTypeDecl.CONTENTTYPE_ELEMENT) { 904 fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); 905 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 906 throw new ComplexTypeRecoverableError("cos-ct-extends.1.4.3.2.2.1.a", 907 new Object[]{fName}, complexContent); 908 } 909 else if (fContentType == XSComplexTypeDecl.CONTENTTYPE_MIXED && 910 baseType.getContentType() != XSComplexTypeDecl.CONTENTTYPE_MIXED) { 911 fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); 912 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 913 throw new ComplexTypeRecoverableError("cos-ct-extends.1.4.3.2.2.1.b", 914 new Object[]{fName}, complexContent); 915 } 916 917 // if the content of either type is an "all" model group, error. 918 if (fParticle.fType == XSParticleDecl.PARTICLE_MODELGROUP && 919 ((XSModelGroupImpl)fParticle.fValue).fCompositor == XSModelGroupImpl.MODELGROUP_ALL || 920 ((XSParticleDecl)baseType.getParticle()).fType == XSParticleDecl.PARTICLE_MODELGROUP && 921 ((XSModelGroupImpl)(((XSParticleDecl)baseType.getParticle())).fValue).fCompositor == XSModelGroupImpl.MODELGROUP_ALL) { 922 fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); 923 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 924 throw new ComplexTypeRecoverableError("cos-all-limited.1.2", 925 new Object[]{}, complexContent); 926 } 927 // the "sequence" model group to contain both particles 928 XSModelGroupImpl group = new XSModelGroupImpl(); 929 group.fCompositor = XSModelGroupImpl.MODELGROUP_SEQUENCE; 930 group.fParticleCount = 2; 931 group.fParticles = new XSParticleDecl[2]; 932 group.fParticles[0] = (XSParticleDecl)baseType.getParticle(); 933 group.fParticles[1] = fParticle; 934 group.fAnnotations = XSObjectListImpl.EMPTY_LIST; 935 // the particle to contain the above sequence 936 XSParticleDecl particle = new XSParticleDecl(); 937 particle.fType = XSParticleDecl.PARTICLE_MODELGROUP; 938 particle.fValue = group; 939 particle.fAnnotations = XSObjectListImpl.EMPTY_LIST; 940 941 fParticle = particle; 942 } 943 944 // Remove prohibited uses. Must be done before merge for EXTENSION. 945 fAttrGrp.removeProhibitedAttrs(); 946 try { 947 mergeAttributes(baseType.getAttrGrp(), fAttrGrp, fName, true, complexContent); 948 } catch (ComplexTypeRecoverableError e) { 949 fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); 950 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 951 throw e; 952 } 953 954 } 955 956 // and *finally* we can legitimately return the attributes! 957 fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); 958 fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); 959 960 } // end of traverseComplexContent 961 962 963 // This method merges attribute uses from the base, into the derived set. 964 // LM: may want to merge with attributeGroup processing. 965 private void mergeAttributes(XSAttributeGroupDecl fromAttrGrp, 966 XSAttributeGroupDecl toAttrGrp, 967 String typeName, 968 boolean extension, 969 Element elem) 970 throws ComplexTypeRecoverableError { 971 972 XSObjectList attrUseS = fromAttrGrp.getAttributeUses(); 973 XSAttributeUseImpl oneAttrUse = null; 974 int attrCount = attrUseS.getLength(); 975 for (int i=0; i<attrCount; i++) { 976 oneAttrUse = (XSAttributeUseImpl)attrUseS.item(i); 977 XSAttributeUse existingAttrUse = toAttrGrp.getAttributeUse(oneAttrUse.fAttrDecl.getNamespace(), 978 oneAttrUse.fAttrDecl.getName()); 979 if (existingAttrUse == null) { 980 981 String idName = toAttrGrp.addAttributeUse(oneAttrUse); 982 if (idName != null) { 983 throw new ComplexTypeRecoverableError("ct-props-correct.5", 984 new Object[]{typeName, idName, oneAttrUse.fAttrDecl.getName()}, 985 elem); 986 } 987 } 988 else if (existingAttrUse != oneAttrUse) { 989 if (extension) { 990 reportSchemaError("ct-props-correct.4", 991 new Object[]{typeName, oneAttrUse.fAttrDecl.getName()}, 992 elem); 993 // Recover by using the attribute use from the base type, 994 // to make the resulting schema "more valid". 995 toAttrGrp.replaceAttributeUse(existingAttrUse, oneAttrUse); 996 } 997 } 998 } 999 // For extension, the wildcard must be formed by doing a union of the wildcards 1000 if (extension) { 1001 if (toAttrGrp.fAttributeWC==null) { 1002 toAttrGrp.fAttributeWC = fromAttrGrp.fAttributeWC; 1003 } 1004 else if (fromAttrGrp.fAttributeWC != null) { 1005 toAttrGrp.fAttributeWC = toAttrGrp.fAttributeWC.performUnionWith(fromAttrGrp.fAttributeWC, toAttrGrp.fAttributeWC.fProcessContents); 1006 if (toAttrGrp.fAttributeWC == null) { 1007 // REVISIT: XML Schema 1.0 2nd edition doesn't actually specify this constraint. It's a bug in the spec 1008 // which will eventually be fixed. We're just guessing what the error code will be. If it turns out to be 1009 // something else we'll need to change it. -- mrglavas 1010 throw new ComplexTypeRecoverableError("src-ct.5", new Object[]{typeName}, elem); 1011 } 1012 } 1013 1014 } 1015 } 1016 1017 private void processComplexContent(Element complexContentChild, 1018 boolean isMixed, boolean isDerivation, 1019 XSDocumentInfo schemaDoc, SchemaGrammar grammar) 1020 throws ComplexTypeRecoverableError { 1021 1022 Element attrNode = null; 1023 XSParticleDecl particle = null; 1024 1025 // whether there is a particle with empty model group 1026 boolean emptyParticle = false; 1027 if (complexContentChild != null) { 1028 // ------------------------------------------------------------- 1029 // GROUP, ALL, SEQUENCE or CHOICE, followed by attributes, if specified. 1030 // Note that it's possible that only attributes are specified. 1031 // ------------------------------------------------------------- 1032 1033 1034 String childName = DOMUtil.getLocalName(complexContentChild); 1035 1036 if (childName.equals(SchemaSymbols.ELT_GROUP)) { 1037 1038 particle = fSchemaHandler.fGroupTraverser.traverseLocal(complexContentChild, 1039 schemaDoc, grammar); 1040 attrNode = DOMUtil.getNextSiblingElement(complexContentChild); 1041 } 1042 else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) { 1043 particle = traverseSequence(complexContentChild,schemaDoc,grammar, 1044 NOT_ALL_CONTEXT,fComplexTypeDecl); 1045 if (particle != null) { 1046 XSModelGroupImpl group = (XSModelGroupImpl)particle.fValue; 1047 if (group.fParticleCount == 0) 1048 emptyParticle = true; 1049 } 1050 attrNode = DOMUtil.getNextSiblingElement(complexContentChild); 1051 } 1052 else if (childName.equals(SchemaSymbols.ELT_CHOICE)) { 1053 particle = traverseChoice(complexContentChild,schemaDoc,grammar, 1054 NOT_ALL_CONTEXT,fComplexTypeDecl); 1055 if (particle != null && particle.fMinOccurs == 0) { 1056 XSModelGroupImpl group = (XSModelGroupImpl)particle.fValue; 1057 if (group.fParticleCount == 0) 1058 emptyParticle = true; 1059 } 1060 attrNode = DOMUtil.getNextSiblingElement(complexContentChild); 1061 } 1062 else if (childName.equals(SchemaSymbols.ELT_ALL)) { 1063 particle = traverseAll(complexContentChild,schemaDoc,grammar, 1064 PROCESSING_ALL_GP,fComplexTypeDecl); 1065 if (particle != null) { 1066 XSModelGroupImpl group = (XSModelGroupImpl)particle.fValue; 1067 if (group.fParticleCount == 0) 1068 emptyParticle = true; 1069 } 1070 attrNode = DOMUtil.getNextSiblingElement(complexContentChild); 1071 } 1072 else { 1073 // Should be attributes here - will check below... 1074 attrNode = complexContentChild; 1075 } 1076 } 1077 1078 // if the particle is empty because there is no non-annotation chidren, 1079 // we need to make the particle itself null (so that the effective 1080 // content is empty). 1081 if (emptyParticle) { 1082 // get the first child 1083 Element child = DOMUtil.getFirstChildElement(complexContentChild); 1084 // if it's annotation, get the next one 1085 if (child != null) { 1086 if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) { 1087 child = DOMUtil.getNextSiblingElement(child); 1088 } 1089 } 1090 // if there is no (non-annotation) children, mark particle empty 1091 if (child == null) 1092 particle = null; 1093 // child != null means we might have seen an element with 1094 // minOccurs == maxOccurs == 0 1095 } 1096 1097 if (particle == null && isMixed) { 1098 particle = XSConstraints.getEmptySequence(); 1099 } 1100 fParticle = particle; 1101 1102 // ----------------------------------------------------------------------- 1103 // Set the content type 1104 // ----------------------------------------------------------------------- 1105 if (fParticle == null) 1106 fContentType = XSComplexTypeDecl.CONTENTTYPE_EMPTY; 1107 else if (isMixed) 1108 fContentType = XSComplexTypeDecl.CONTENTTYPE_MIXED; 1109 else 1110 fContentType = XSComplexTypeDecl.CONTENTTYPE_ELEMENT; 1111 1112 1113 // ------------------------------------------------------------- 1114 // Now, process attributes 1115 // ------------------------------------------------------------- 1116 if (attrNode != null) { 1117 if (!isAttrOrAttrGroup(attrNode)) { 1118 throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1", 1119 new Object[]{fName,DOMUtil.getLocalName(attrNode)}, 1120 attrNode); 1121 } 1122 Element node = 1123 traverseAttrsAndAttrGrps(attrNode,fAttrGrp,schemaDoc,grammar,fComplexTypeDecl); 1124 if (node!=null) { 1125 throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1", 1126 new Object[]{fName,DOMUtil.getLocalName(node)}, 1127 node); 1128 } 1129 // Only remove prohibited attribute uses if this isn't a derived type 1130 // Derivation-specific code worries about this elsewhere 1131 if (!isDerivation) { 1132 fAttrGrp.removeProhibitedAttrs(); 1133 } 1134 } 1135 1136 1137 1138 } // end processComplexContent 1139 1140 1141 private boolean isAttrOrAttrGroup(Element e) { 1142 String elementName = DOMUtil.getLocalName(e); 1143 1144 if (elementName.equals(SchemaSymbols.ELT_ATTRIBUTE) || 1145 elementName.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP) || 1146 elementName.equals(SchemaSymbols.ELT_ANYATTRIBUTE)) 1147 return true; 1148 else 1149 return false; 1150 } 1151 1152 private void traverseSimpleContentDecl(Element simpleContentDecl) { 1153 } 1154 1155 private void traverseComplexContentDecl(Element complexContentDecl, 1156 boolean mixedOnComplexTypeDecl) { 1157 } 1158 1159 /* 1160 * Generate a name for an anonymous type 1161 */ 1162 private String genAnonTypeName(Element complexTypeDecl) { 1163 1164 // Generate a unique name for the anonymous type by concatenating together the 1165 // names of parent nodes 1166 // The name is quite good for debugging/error purposes, but we may want to 1167 // revisit how this is done for performance reasons (LM). 1168 StringBuffer typeName = new StringBuffer("#AnonType_"); 1169 Element node = DOMUtil.getParent(complexTypeDecl); 1170 while (node != null && (node != DOMUtil.getRoot(DOMUtil.getDocument(node)))) { 1171 typeName.append(node.getAttribute(SchemaSymbols.ATT_NAME)); 1172 node = DOMUtil.getParent(node); 1173 } 1174 return typeName.toString(); 1175 } 1176 1177 1178 private void handleComplexTypeError(String messageId,Object[] args, 1179 Element e) { 1180 1181 if (messageId!=null) { 1182 reportSchemaError(messageId, args, e); 1183 } 1184 1185 // 1186 // Mock up the typeInfo structure so that there won't be problems during 1187 // validation 1188 // 1189 fBaseType = SchemaGrammar.fAnyType; 1190 fContentType = XSComplexTypeDecl.CONTENTTYPE_MIXED; 1191 fXSSimpleType = null; 1192 fParticle = getErrorContent(); 1193 // REVISIT: do we need to remove all attribute uses already added into 1194 // the attribute group? maybe it's ok to leave them there. -SG 1195 fAttrGrp.fAttributeWC = getErrorWildcard(); 1196 1197 return; 1198 1199 } 1200 1201 private void contentBackup() { 1202 if(fGlobalStore == null) { 1203 fGlobalStore = new Object [GLOBAL_NUM]; 1204 fGlobalStorePos = 0; 1205 } 1206 if(fGlobalStorePos == fGlobalStore.length) { 1207 Object [] newArray = new Object[fGlobalStorePos+GLOBAL_NUM]; 1208 System.arraycopy(fGlobalStore, 0, newArray, 0, fGlobalStorePos); 1209 fGlobalStore = newArray; 1210 } 1211 fGlobalStore[fGlobalStorePos++] = fComplexTypeDecl; 1212 fGlobalStore[fGlobalStorePos++] = fIsAbstract?Boolean.TRUE:Boolean.FALSE; 1213 fGlobalStore[fGlobalStorePos++] = fName ; 1214 fGlobalStore[fGlobalStorePos++] = fTargetNamespace; 1215 // let's save ourselves a couple of objects... 1216 fGlobalStore[fGlobalStorePos++] = new Integer((fDerivedBy << 16) + fFinal); 1217 fGlobalStore[fGlobalStorePos++] = new Integer((fBlock << 16) + fContentType); 1218 fGlobalStore[fGlobalStorePos++] = fBaseType; 1219 fGlobalStore[fGlobalStorePos++] = fAttrGrp; 1220 fGlobalStore[fGlobalStorePos++] = fParticle; 1221 fGlobalStore[fGlobalStorePos++] = fXSSimpleType; 1222 fGlobalStore[fGlobalStorePos++] = fAnnotations; 1223 } 1224 1225 private void contentRestore() { 1226 fAnnotations = (XSAnnotationImpl [])fGlobalStore[--fGlobalStorePos]; 1227 fXSSimpleType = (XSSimpleType)fGlobalStore[--fGlobalStorePos]; 1228 fParticle = (XSParticleDecl)fGlobalStore[--fGlobalStorePos]; 1229 fAttrGrp = (XSAttributeGroupDecl)fGlobalStore[--fGlobalStorePos]; 1230 fBaseType = (XSTypeDefinition)fGlobalStore[--fGlobalStorePos]; 1231 int i = ((Integer)(fGlobalStore[--fGlobalStorePos])).intValue(); 1232 fBlock = (short)(i >> 16); 1233 fContentType = (short)i; 1234 i = ((Integer)(fGlobalStore[--fGlobalStorePos])).intValue(); 1235 fDerivedBy = (short)(i >> 16); 1236 fFinal = (short)i; 1237 fTargetNamespace = (String)fGlobalStore[--fGlobalStorePos]; 1238 fName = (String)fGlobalStore[--fGlobalStorePos]; 1239 fIsAbstract = ((Boolean)fGlobalStore[--fGlobalStorePos]).booleanValue(); 1240 fComplexTypeDecl = (XSComplexTypeDecl)fGlobalStore[--fGlobalStorePos]; 1241 } 1242 1243 private void addAnnotation(XSAnnotationImpl annotation) { 1244 if(annotation == null) 1245 return; 1246 // it isn't very likely that there will be more than one annotation 1247 // in a complexType decl. This saves us fromhaving to push/pop 1248 // one more object from the fGlobalStore, and that's bound 1249 // to be a savings for most applications 1250 if(fAnnotations == null) { 1251 fAnnotations = new XSAnnotationImpl[1]; 1252 } else { 1253 XSAnnotationImpl [] tempArray = new XSAnnotationImpl[fAnnotations.length + 1]; 1254 System.arraycopy(fAnnotations, 0, tempArray, 0, fAnnotations.length); 1255 fAnnotations = tempArray; 1256 } 1257 fAnnotations[fAnnotations.length-1] = annotation; 1258 } 1259 }