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