1/*
2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
3 */
4/*
5 * Licensed to the Apache Software Foundation (ASF) under one or more
6 * contributor license agreements.  See the NOTICE file distributed with
7 * this work for additional information regarding copyright ownership.
8 * The ASF licenses this file to You under the Apache License, Version 2.0
9 * (the "License"); you may not use this file except in compliance with
10 * the License.  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
21package com.sun.org.apache.xerces.internal.impl.xs.traversers;
22
23import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeFacetException;
24import com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory;
25import com.sun.org.apache.xerces.internal.impl.dv.XSFacets;
26import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
27import com.sun.org.apache.xerces.internal.impl.dv.xs.XSSimpleTypeDecl;
28import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar;
29import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
30import com.sun.org.apache.xerces.internal.impl.xs.XSAnnotationImpl;
31import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeGroupDecl;
32import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeUseImpl;
33import com.sun.org.apache.xerces.internal.impl.xs.XSComplexTypeDecl;
34import com.sun.org.apache.xerces.internal.impl.xs.XSConstraints;
35import com.sun.org.apache.xerces.internal.impl.xs.XSModelGroupImpl;
36import com.sun.org.apache.xerces.internal.impl.xs.XSParticleDecl;
37import com.sun.org.apache.xerces.internal.impl.xs.XSWildcardDecl;
38import com.sun.org.apache.xerces.internal.impl.xs.util.XInt;
39import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl;
40import com.sun.org.apache.xerces.internal.util.DOMUtil;
41import com.sun.org.apache.xerces.internal.xni.QName;
42import com.sun.org.apache.xerces.internal.xs.XSAttributeUse;
43import com.sun.org.apache.xerces.internal.xs.XSConstants;
44import com.sun.org.apache.xerces.internal.xs.XSObjectList;
45import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
46import org.w3c.dom.Element;
47
48/**
49 * A complex type definition schema component traverser.
50 *
51 * <complexType
52 *   abstract = boolean : false
53 *   block = (#all | List of (extension | restriction))
54 *   final = (#all | List of (extension | restriction))
55 *   id = ID
56 *   mixed = boolean : false
57 *   name = NCName
58 *   {any attributes with non-schema namespace . . .}>
59 *   Content: (annotation?, (simpleContent | complexContent |
60 *            ((group | all | choice | sequence)?,
61 *            ((attribute | attributeGroup)*, anyAttribute?))))
62 * </complexType>
63 *
64 * @xerces.internal
65 *
66 */
67
68class  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++] = (fDerivedBy << 16) + fFinal;
1217        fGlobalStore[fGlobalStorePos++] = (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]));
1232        fBlock = (short)(i >> 16);
1233        fContentType = (short)i;
1234        i = ((Integer)(fGlobalStore[--fGlobalStorePos]));
1235        fDerivedBy = (short)(i >> 16);
1236        fFinal = (short)i;
1237        fTargetNamespace = (String)fGlobalStore[--fGlobalStorePos];
1238        fName = (String)fGlobalStore[--fGlobalStorePos];
1239        fIsAbstract = ((Boolean)fGlobalStore[--fGlobalStorePos]);
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}
1260