View Javadoc
1   /*
2    * reserved comment block
3    * DO NOT REMOVE OR ALTER!
4    */
5   /*
6    * Copyright 2001-2005 The Apache Software Foundation.
7    *
8    * Licensed under the Apache License, Version 2.0 (the "License");
9    * you may not use this file except in compliance with the License.
10   * You may obtain a copy of the License at
11   *
12   *      http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package com.sun.org.apache.xerces.internal.impl.xs.traversers;
22  
23  import java.util.Locale;
24  
25  import com.sun.org.apache.xerces.internal.impl.dv.ValidatedInfo;
26  import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
27  import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar;
28  import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
29  import com.sun.org.apache.xerces.internal.impl.xs.XSAnnotationImpl;
30  import com.sun.org.apache.xerces.internal.impl.xs.XSComplexTypeDecl;
31  import com.sun.org.apache.xerces.internal.impl.xs.XSConstraints;
32  import com.sun.org.apache.xerces.internal.impl.xs.XSElementDecl;
33  import com.sun.org.apache.xerces.internal.impl.xs.XSParticleDecl;
34  import com.sun.org.apache.xerces.internal.impl.xs.util.XInt;
35  import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl;
36  import com.sun.org.apache.xerces.internal.util.DOMUtil;
37  import com.sun.org.apache.xerces.internal.util.SymbolTable;
38  import com.sun.org.apache.xerces.internal.util.XMLChar;
39  import com.sun.org.apache.xerces.internal.xni.QName;
40  import com.sun.org.apache.xerces.internal.xs.XSConstants;
41  import com.sun.org.apache.xerces.internal.xs.XSObject;
42  import com.sun.org.apache.xerces.internal.xs.XSObjectList;
43  import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
44  import org.w3c.dom.Attr;
45  import org.w3c.dom.Element;
46  
47  /**
48   * The element declaration schema component traverser.
49   * <element
50   *   abstract = boolean : false
51   *   block = (#all | List of (extension | restriction | substitution))
52   *   default = string
53   *   final = (#all | List of (extension | restriction))
54   *   fixed = string
55   *   form = (qualified | unqualified)
56   *   id = ID
57   *   maxOccurs = (nonNegativeInteger | unbounded)  : 1
58   *   minOccurs = nonNegativeInteger : 1
59   *   name = NCName
60   *   nillable = boolean : false
61   *   ref = QName
62   *   substitutionGroup = QName
63   *   type = QName
64   *   {any attributes with non-schema namespace . . .}>
65   *   Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
66   * </element>
67   *
68   * @xerces.internal
69   *
70   * @author Sandy Gao, IBM
71   *
72   * @version $Id: XSDElementTraverser.java,v 1.9 2010-11-01 04:40:02 joehw Exp $
73   */
74  class XSDElementTraverser extends XSDAbstractTraverser {
75  
76      protected final XSElementDecl  fTempElementDecl  = new XSElementDecl();
77  
78      // this controls what happens when a local element is encountered.
79      // We may not encounter all local elements when first parsing.
80      boolean fDeferTraversingLocalElements;
81  
82      XSDElementTraverser (XSDHandler handler,
83              XSAttributeChecker gAttrCheck) {
84          super(handler, gAttrCheck);
85      }
86  
87      /**
88       * Traverse a locally declared element (or an element reference).
89       *
90       * To handle the recursive cases efficiently, we delay the traversal
91       * and return an empty particle node. We'll fill in this particle node
92       * later after we've done with all the global declarations.
93       * This method causes a number of data structures in the schema handler to be filled in.
94       *
95       * @param  elmDecl
96       * @param  schemaDoc
97       * @param  grammar
98       * @return the particle
99       */
100     XSParticleDecl traverseLocal(Element elmDecl,
101             XSDocumentInfo schemaDoc,
102             SchemaGrammar grammar,
103             int allContextFlags,
104             XSObject parent) {
105 
106         XSParticleDecl particle = null;
107         if (fSchemaHandler.fDeclPool !=null) {
108             particle = fSchemaHandler.fDeclPool.getParticleDecl();
109         } else {
110             particle = new XSParticleDecl();
111         }
112         if (fDeferTraversingLocalElements) {
113             // The only thing we care about now is whether this element has
114             // minOccurs=0. This affects (if the element appears in a complex
115             // type) whether a type has emptiable content.
116             particle.fType = XSParticleDecl.PARTICLE_ELEMENT;
117             Attr attr = elmDecl.getAttributeNode(SchemaSymbols.ATT_MINOCCURS);
118             if (attr != null) {
119                 String min = attr.getValue();
120                 try {
121                     int m = Integer.parseInt(XMLChar.trim(min));
122                     if (m >= 0)
123                         particle.fMinOccurs = m;
124                 }
125                 catch (NumberFormatException ex) {
126                 }
127             }
128             fSchemaHandler.fillInLocalElemInfo(elmDecl, schemaDoc, allContextFlags, parent, particle);
129         } else {
130             traverseLocal(particle, elmDecl, schemaDoc, grammar, allContextFlags, parent, null);
131             // If it's an empty particle, return null.
132             if (particle.fType == XSParticleDecl.PARTICLE_EMPTY)
133                 particle = null;
134         }
135 
136         return particle;
137     }
138 
139     /**
140      * Traverse a locally declared element (or an element reference).
141      *
142      * This is the real traversal method. It's called after we've done with
143      * all the global declarations.
144      *
145      * @param  index
146      */
147     protected void traverseLocal(XSParticleDecl particle,
148             Element elmDecl,
149             XSDocumentInfo schemaDoc,
150             SchemaGrammar grammar,
151             int allContextFlags,
152             XSObject parent,
153             String[] localNSDecls) {
154 
155         if (localNSDecls != null) {
156             schemaDoc.fNamespaceSupport.setEffectiveContext(localNSDecls);
157         }
158 
159         // General Attribute Checking
160         Object[] attrValues = fAttrChecker.checkAttributes(elmDecl, false, schemaDoc);
161 
162         QName refAtt = (QName) attrValues[XSAttributeChecker.ATTIDX_REF];
163         XInt  minAtt = (XInt)  attrValues[XSAttributeChecker.ATTIDX_MINOCCURS];
164         XInt  maxAtt = (XInt)  attrValues[XSAttributeChecker.ATTIDX_MAXOCCURS];
165 
166         XSElementDecl element = null;
167         XSAnnotationImpl annotation = null;
168         if (elmDecl.getAttributeNode(SchemaSymbols.ATT_REF) != null) {
169             if (refAtt != null) {
170                 element = (XSElementDecl)fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.ELEMENT_TYPE, refAtt, elmDecl);
171 
172                 Element child = DOMUtil.getFirstChildElement(elmDecl);
173                 if (child != null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
174                     annotation = traverseAnnotationDecl(child, attrValues, false, schemaDoc);
175                     child = DOMUtil.getNextSiblingElement(child);
176                 }
177                 else {
178                     String text = DOMUtil.getSyntheticAnnotation(elmDecl);
179                     if (text != null) {
180                         annotation = traverseSyntheticAnnotation(elmDecl, text, attrValues, false, schemaDoc);
181                     }
182                 }
183                 // Element Declaration Representation OK
184                 // 2 If the item's parent is not <schema>, then all of the following must be true:
185                 // 2.1 One of ref or name must be present, but not both.
186                 // 2.2 If ref is present, then all of <complexType>, <simpleType>, <key>, <keyref>, <unique>, nillable, default, fixed, form, block and type must be absent, i.e. only minOccurs, maxOccurs, id are allowed in addition to ref, along with <annotation>.
187                 if (child != null) {
188                     reportSchemaError("src-element.2.2", new Object[]{refAtt.rawname, DOMUtil.getLocalName(child)}, child);
189                 }
190             } else {
191                 element = null;
192             }
193         } else {
194             element = traverseNamedElement(elmDecl, attrValues, schemaDoc, grammar, false, parent);
195         }
196 
197         particle.fMinOccurs = minAtt.intValue();
198         particle.fMaxOccurs = maxAtt.intValue();
199         if (element != null) {
200             particle.fType = XSParticleDecl.PARTICLE_ELEMENT;
201             particle.fValue = element;
202         }
203         else {
204             particle.fType = XSParticleDecl.PARTICLE_EMPTY;
205         }
206         if (refAtt != null) {
207             XSObjectList annotations;
208             if (annotation != null) {
209                 annotations = new XSObjectListImpl();
210                 ((XSObjectListImpl) annotations).addXSObject(annotation);
211             } else {
212                 annotations = XSObjectListImpl.EMPTY_LIST;
213             }
214             particle.fAnnotations = annotations;
215         } else {
216             particle.fAnnotations = ((element != null) ? element.fAnnotations
217                     : XSObjectListImpl.EMPTY_LIST);
218         }
219         Long defaultVals = (Long)attrValues[XSAttributeChecker.ATTIDX_FROMDEFAULT];
220         checkOccurrences(particle, SchemaSymbols.ELT_ELEMENT,
221                 (Element)elmDecl.getParentNode(), allContextFlags,
222                 defaultVals.longValue());
223 
224         fAttrChecker.returnAttrArray(attrValues, schemaDoc);
225     }
226 
227     /**
228      * Traverse a globally declared element.
229      *
230      * @param  elmDecl
231      * @param  schemaDoc
232      * @param  grammar
233      * @return the element declaration
234      */
235     XSElementDecl traverseGlobal(Element elmDecl,
236             XSDocumentInfo schemaDoc,
237             SchemaGrammar grammar) {
238 
239         // General Attribute Checking'
240 
241         Object[] attrValues = fAttrChecker.checkAttributes(elmDecl, true, schemaDoc);
242         XSElementDecl element = traverseNamedElement(elmDecl, attrValues, schemaDoc, grammar, true, null);
243         fAttrChecker.returnAttrArray(attrValues, schemaDoc);
244         return element;
245 
246     }
247 
248     /**
249      * Traverse a globally declared element.
250      *
251      * @param  elmDecl
252      * @param  attrValues
253      * @param  schemaDoc
254      * @param  grammar
255      * @param  isGlobal
256      * @return the element declaration
257      */
258     XSElementDecl traverseNamedElement(Element elmDecl,
259             Object[] attrValues,
260             XSDocumentInfo schemaDoc,
261             SchemaGrammar grammar,
262             boolean isGlobal,
263             XSObject parent) {
264 
265         Boolean abstractAtt  = (Boolean) attrValues[XSAttributeChecker.ATTIDX_ABSTRACT];
266         XInt    blockAtt     = (XInt)    attrValues[XSAttributeChecker.ATTIDX_BLOCK];
267         String  defaultAtt   = (String)  attrValues[XSAttributeChecker.ATTIDX_DEFAULT];
268         XInt    finalAtt     = (XInt)    attrValues[XSAttributeChecker.ATTIDX_FINAL];
269         String  fixedAtt     = (String)  attrValues[XSAttributeChecker.ATTIDX_FIXED];
270         XInt    formAtt      = (XInt)    attrValues[XSAttributeChecker.ATTIDX_FORM];
271         String  nameAtt      = (String)  attrValues[XSAttributeChecker.ATTIDX_NAME];
272         Boolean nillableAtt  = (Boolean) attrValues[XSAttributeChecker.ATTIDX_NILLABLE];
273         QName   subGroupAtt  = (QName)   attrValues[XSAttributeChecker.ATTIDX_SUBSGROUP];
274         QName   typeAtt      = (QName)   attrValues[XSAttributeChecker.ATTIDX_TYPE];
275 
276         // Step 1: get declaration information
277 
278         XSElementDecl element = null;
279         if (fSchemaHandler.fDeclPool !=null) {
280             element = fSchemaHandler.fDeclPool.getElementDecl();
281         } else {
282             element = new XSElementDecl();
283         }
284         // get 'name'
285         if (nameAtt != null)
286             element.fName = fSymbolTable.addSymbol(nameAtt);
287 
288         // get 'target namespace'
289         if (isGlobal) {
290             element.fTargetNamespace = schemaDoc.fTargetNamespace;
291             element.setIsGlobal();
292         }
293         else {
294             if (parent instanceof XSComplexTypeDecl)
295                 element.setIsLocal((XSComplexTypeDecl)parent);
296 
297             if (formAtt != null) {
298                 if (formAtt.intValue() == SchemaSymbols.FORM_QUALIFIED)
299                     element.fTargetNamespace = schemaDoc.fTargetNamespace;
300                 else
301                     element.fTargetNamespace = null;
302             } else if (schemaDoc.fAreLocalElementsQualified) {
303                 element.fTargetNamespace = schemaDoc.fTargetNamespace;
304             } else {
305                 element.fTargetNamespace = null;
306             }
307         }
308 
309         // get 'block', 'final', 'nillable', 'abstract'
310          if (blockAtt == null) {
311              // use defaults
312              element.fBlock = schemaDoc.fBlockDefault;
313              // discard valid Block 'Default' values that are invalid for Block
314              // respect #all
315              if (element.fBlock != XSConstants.DERIVATION_ALL) {
316                  element.fBlock &= (XSConstants.DERIVATION_EXTENSION | XSConstants.DERIVATION_RESTRICTION | XSConstants.DERIVATION_SUBSTITUTION);
317              }
318          } else {
319              // use specified values
320              element.fBlock = blockAtt.shortValue();
321              // check for valid values
322              if ((element.fBlock != XSConstants.DERIVATION_ALL)
323                  &&
324                  ((element.fBlock | XSConstants.DERIVATION_EXTENSION_RESTRICTION_SUBSTITION)
325                      != XSConstants.DERIVATION_EXTENSION_RESTRICTION_SUBSTITION)) {
326                  reportSchemaError(
327                          "s4s-att-invalid-value",
328                          new Object[]{element.fName, "block", "must be (#all | List of (extension | restriction | substitution))"},
329                          elmDecl);
330              }
331         }
332 
333         element.fFinal = finalAtt == null ? schemaDoc.fFinalDefault : finalAtt.shortValue();
334         // discard valid Final 'Default' values that are invalid for Final
335         element.fFinal &= (XSConstants.DERIVATION_EXTENSION | XSConstants.DERIVATION_RESTRICTION);
336 
337         if (nillableAtt.booleanValue())
338             element.setIsNillable();
339         if (abstractAtt != null && abstractAtt.booleanValue())
340             element.setIsAbstract();
341 
342         // get 'value constraint'
343         if (fixedAtt != null) {
344             element.fDefault = new ValidatedInfo();
345             element.fDefault.normalizedValue = fixedAtt;
346             element.setConstraintType(XSConstants.VC_FIXED);
347         } else if (defaultAtt != null) {
348             element.fDefault = new ValidatedInfo();
349             element.fDefault.normalizedValue = defaultAtt;
350             element.setConstraintType(XSConstants.VC_DEFAULT);
351         } else {
352             element.setConstraintType(XSConstants.VC_NONE);
353         }
354 
355         // get 'substitutionGroup affiliation'
356         if (subGroupAtt != null) {
357             element.fSubGroup = (XSElementDecl)fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.ELEMENT_TYPE, subGroupAtt, elmDecl);
358         }
359 
360         // get 'annotation'
361         Element child = DOMUtil.getFirstChildElement(elmDecl);
362         XSAnnotationImpl annotation = null;
363         if(child != null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
364             annotation = traverseAnnotationDecl(child, attrValues, false, schemaDoc);
365             child = DOMUtil.getNextSiblingElement(child);
366         }
367         else {
368             String text = DOMUtil.getSyntheticAnnotation(elmDecl);
369             if (text != null) {
370                 annotation = traverseSyntheticAnnotation(elmDecl, text, attrValues, false, schemaDoc);
371             }
372         }
373 
374         XSObjectList annotations;
375         if (annotation != null) {
376             annotations = new XSObjectListImpl();
377             ((XSObjectListImpl)annotations).addXSObject (annotation);
378         } else {
379             annotations = XSObjectListImpl.EMPTY_LIST;
380         }
381         element.fAnnotations = annotations;
382 
383         // get 'type definition'
384         XSTypeDefinition elementType = null;
385         boolean haveAnonType = false;
386 
387         // Handle Anonymous type if there is one
388         if (child != null) {
389             String childName = DOMUtil.getLocalName(child);
390 
391             if (childName.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
392                 elementType = fSchemaHandler.fComplexTypeTraverser.traverseLocal(child, schemaDoc, grammar);
393                 haveAnonType = true;
394                 child = DOMUtil.getNextSiblingElement(child);
395             }
396             else if (childName.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
397                 elementType = fSchemaHandler.fSimpleTypeTraverser.traverseLocal(child, schemaDoc, grammar);
398                 haveAnonType = true;
399                 child = DOMUtil.getNextSiblingElement(child);
400             }
401         }
402 
403         // Handler type attribute
404         if (elementType == null && typeAtt != null) {
405             elementType = (XSTypeDefinition)fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.TYPEDECL_TYPE, typeAtt, elmDecl);
406             if (elementType == null) {
407                 element.fUnresolvedTypeName = typeAtt;
408             }
409         }
410 
411         // Get it from the substitutionGroup declaration
412         if (elementType == null && element.fSubGroup != null) {
413             elementType = element.fSubGroup.fType;
414         }
415 
416         if (elementType == null) {
417             elementType = SchemaGrammar.fAnyType;
418         }
419 
420         element.fType = elementType;
421 
422         // get 'identity constraint'
423 
424         // see if there's something here; it had better be key, keyref or unique.
425         if (child != null) {
426             String childName = DOMUtil.getLocalName(child);
427             while (child != null &&
428                     (childName.equals(SchemaSymbols.ELT_KEY) ||
429                             childName.equals(SchemaSymbols.ELT_KEYREF) ||
430                             childName.equals(SchemaSymbols.ELT_UNIQUE))) {
431 
432                 if (childName.equals(SchemaSymbols.ELT_KEY) ||
433                         childName.equals(SchemaSymbols.ELT_UNIQUE)) {
434                     // need to set <key>/<unique> to hidden before traversing it,
435                     // because it has global scope
436                     DOMUtil.setHidden(child, fSchemaHandler.fHiddenNodes);
437                     fSchemaHandler.fUniqueOrKeyTraverser.traverse(child, element, schemaDoc, grammar);
438                     if(DOMUtil.getAttrValue(child, SchemaSymbols.ATT_NAME).length() != 0 ) {
439                         fSchemaHandler.checkForDuplicateNames(
440                                 (schemaDoc.fTargetNamespace == null) ? ","+DOMUtil.getAttrValue(child, SchemaSymbols.ATT_NAME)
441                                         : schemaDoc.fTargetNamespace+","+ DOMUtil.getAttrValue(child, SchemaSymbols.ATT_NAME),
442                                         fSchemaHandler.ATTRIBUTE_TYPE, fSchemaHandler.getIDRegistry(), fSchemaHandler.getIDRegistry_sub(),
443                                         child, schemaDoc);
444                     }
445                 } else if (childName.equals(SchemaSymbols.ELT_KEYREF)) {
446                     fSchemaHandler.storeKeyRef(child, schemaDoc, element);
447                 }
448                 child = DOMUtil.getNextSiblingElement(child);
449                 if (child != null) {
450                     childName = DOMUtil.getLocalName(child);
451                 }
452             }
453         }
454 
455         // Step 3: check against schema for schemas
456 
457         // required attributes
458         if (nameAtt == null) {
459             if (isGlobal)
460                 reportSchemaError("s4s-att-must-appear", new Object[]{SchemaSymbols.ELT_ELEMENT, SchemaSymbols.ATT_NAME}, elmDecl);
461             else
462                 reportSchemaError("src-element.2.1", null, elmDecl);
463             nameAtt = NO_NAME;
464         }
465 
466         // element
467         if (child != null) {
468             reportSchemaError("s4s-elt-must-match.1", new Object[]{nameAtt, "(annotation?, (simpleType | complexType)?, (unique | key | keyref)*))", DOMUtil.getLocalName(child)}, child);
469         }
470 
471         // Step 4: check 3.3.3 constraints
472 
473         // src-element
474 
475         // 1 default and fixed must not both be present.
476         if (defaultAtt != null && fixedAtt != null) {
477             reportSchemaError("src-element.1", new Object[]{nameAtt}, elmDecl);
478         }
479 
480         // 2 If the item's parent is not <schema>, then all of the following must be true:
481         // 2.1 One of ref or name must be present, but not both.
482         // This is checked in XSAttributeChecker
483 
484         // 2.2 If ref is present, then all of <complexType>, <simpleType>, <key>, <keyref>, <unique>, nillable, default, fixed, form, block and type must be absent, i.e. only minOccurs, maxOccurs, id are allowed in addition to ref, along with <annotation>.
485         // Attributes are checked in XSAttributeChecker, elements are checked in "traverse" method
486 
487         // 3 type and either <simpleType> or <complexType> are mutually exclusive.
488         if (haveAnonType && (typeAtt != null)) {
489             reportSchemaError("src-element.3", new Object[]{nameAtt}, elmDecl);
490         }
491 
492         // Step 5: check 3.3.6 constraints
493         // check for NOTATION type
494         checkNotationType(nameAtt, elementType, elmDecl);
495 
496         // e-props-correct
497 
498         // 2 If there is a {value constraint}, the canonical lexical representation of its value must be valid with respect to the {type definition} as defined in Element Default Valid (Immediate) (3.3.6).
499         if (element.fDefault != null) {
500             fValidationState.setNamespaceSupport(schemaDoc.fNamespaceSupport);
501             if (XSConstraints.ElementDefaultValidImmediate(element.fType, element.fDefault.normalizedValue, fValidationState, element.fDefault) == null) {
502                 reportSchemaError ("e-props-correct.2", new Object[]{nameAtt, element.fDefault.normalizedValue}, elmDecl);
503                 element.fDefault = null;
504                 element.setConstraintType(XSConstants.VC_NONE);
505             }
506         }
507 
508         // 4 If there is an {substitution group affiliation}, the {type definition} of the element declaration must be validly derived from the {type definition} of the {substitution group affiliation}, given the value of the {substitution group exclusions} of the {substitution group affiliation}, as defined in Type Derivation OK (Complex) (3.4.6) (if the {type definition} is complex) or as defined in Type Derivation OK (Simple) (3.14.6) (if the {type definition} is simple).
509         if (element.fSubGroup != null) {
510             if (!XSConstraints.checkTypeDerivationOk(element.fType, element.fSubGroup.fType, element.fSubGroup.fFinal)) {
511                 reportSchemaError ("e-props-correct.4", new Object[]{nameAtt, subGroupAtt.prefix+":"+subGroupAtt.localpart}, elmDecl);
512                 element.fSubGroup = null;
513             }
514         }
515 
516         // 5 If the {type definition} or {type definition}'s {content type} is or is derived from ID then there must not be a {value constraint}.
517         if (element.fDefault != null) {
518             if ((elementType.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE &&
519                     ((XSSimpleType)elementType).isIDType()) ||
520                     (elementType.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE &&
521                             ((XSComplexTypeDecl)elementType).containsTypeID())) {
522                 reportSchemaError ("e-props-correct.5", new Object[]{element.fName}, elmDecl);
523                 element.fDefault = null;
524                 element.setConstraintType(XSConstants.VC_NONE);
525             }
526         }
527 
528         // Element without a name. Return null.
529         if (element.fName == null)
530             return null;
531 
532         // Step 5: register the element decl to the grammar
533         if (isGlobal) {
534             grammar.addGlobalElementDeclAll(element);
535 
536             if (grammar.getGlobalElementDecl(element.fName) == null) {
537                 grammar.addGlobalElementDecl(element);
538             }
539 
540             // we also add the element to the tolerate duplicates list as well
541             final String loc = fSchemaHandler.schemaDocument2SystemId(schemaDoc);
542             final XSElementDecl element2 = grammar.getGlobalElementDecl(element.fName, loc);
543             if (element2 == null) {
544                 grammar.addGlobalElementDecl(element, loc);
545             }
546 
547             // if we are tolerating duplicates, and we found a duplicate declaration
548             // use the duplicate one instead
549             if (fSchemaHandler.fTolerateDuplicates) {
550                 if (element2 != null) {
551                     element = element2;
552                 }
553                 fSchemaHandler.addGlobalElementDecl(element);
554             }
555         }
556 
557         return element;
558     }
559 
560     void reset(SymbolTable symbolTable, boolean validateAnnotations, Locale locale) {
561         super.reset(symbolTable, validateAnnotations, locale);
562         fDeferTraversingLocalElements = true;
563     } // reset()
564 
565 }