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