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 }