View Javadoc
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 }