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 
  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  * @LastModified: Oct 2017
  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                                         XSDHandler.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 }