1 /*
   2  * Copyright (c) 2007, 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 com.sun.org.apache.xerces.internal.impl.Constants;
  24 import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
  25 import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
  26 import com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory;
  27 import com.sun.org.apache.xerces.internal.impl.dv.xs.XSSimpleTypeDecl;
  28 import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar;
  29 import com.sun.org.apache.xerces.internal.impl.xs.SchemaNamespaceSupport;
  30 import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
  31 import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaException;
  32 import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader;
  33 import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeDecl;
  34 import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeGroupDecl;
  35 import com.sun.org.apache.xerces.internal.impl.xs.XSComplexTypeDecl;
  36 import com.sun.org.apache.xerces.internal.impl.xs.XSDDescription;
  37 import com.sun.org.apache.xerces.internal.impl.xs.XSDeclarationPool;
  38 import com.sun.org.apache.xerces.internal.impl.xs.XSElementDecl;
  39 import com.sun.org.apache.xerces.internal.impl.xs.XSGrammarBucket;
  40 import com.sun.org.apache.xerces.internal.impl.xs.XSGroupDecl;
  41 import com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter;
  42 import com.sun.org.apache.xerces.internal.impl.xs.XSModelGroupImpl;
  43 import com.sun.org.apache.xerces.internal.impl.xs.XSNotationDecl;
  44 import com.sun.org.apache.xerces.internal.impl.xs.XSParticleDecl;
  45 import com.sun.org.apache.xerces.internal.impl.xs.identity.IdentityConstraint;
  46 import com.sun.org.apache.xerces.internal.impl.xs.opti.ElementImpl;
  47 import com.sun.org.apache.xerces.internal.impl.xs.opti.SchemaDOMParser;
  48 import com.sun.org.apache.xerces.internal.impl.xs.opti.SchemaParsingConfig;
  49 import com.sun.org.apache.xerces.internal.impl.xs.util.SimpleLocator;
  50 import com.sun.org.apache.xerces.internal.impl.xs.util.XSInputSource;
  51 import com.sun.org.apache.xerces.internal.parsers.SAXParser;
  52 import com.sun.org.apache.xerces.internal.parsers.XML11Configuration;
  53 import com.sun.org.apache.xerces.internal.util.DOMInputSource;
  54 import com.sun.org.apache.xerces.internal.util.DOMUtil;
  55 import com.sun.org.apache.xerces.internal.util.DefaultErrorHandler;
  56 import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper;
  57 import com.sun.org.apache.xerces.internal.util.SAXInputSource;
  58 import com.sun.org.apache.xerces.internal.util.StAXInputSource;
  59 import com.sun.org.apache.xerces.internal.util.StAXLocationWrapper;
  60 import com.sun.org.apache.xerces.internal.util.SymbolHash;
  61 import com.sun.org.apache.xerces.internal.util.SymbolTable;
  62 import com.sun.org.apache.xerces.internal.util.URI.MalformedURIException;
  63 import com.sun.org.apache.xerces.internal.util.XMLSymbols;
  64 import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
  65 import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
  66 import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
  67 import com.sun.org.apache.xerces.internal.xni.QName;
  68 import com.sun.org.apache.xerces.internal.xni.XNIException;
  69 import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
  70 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
  71 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
  72 import com.sun.org.apache.xerces.internal.xni.grammars.XMLSchemaDescription;
  73 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
  74 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  75 import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
  76 import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
  77 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
  78 import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
  79 import com.sun.org.apache.xerces.internal.xs.StringList;
  80 import com.sun.org.apache.xerces.internal.xs.XSAttributeDeclaration;
  81 import com.sun.org.apache.xerces.internal.xs.XSAttributeGroupDefinition;
  82 import com.sun.org.apache.xerces.internal.xs.XSAttributeUse;
  83 import com.sun.org.apache.xerces.internal.xs.XSConstants;
  84 import com.sun.org.apache.xerces.internal.xs.XSElementDeclaration;
  85 import com.sun.org.apache.xerces.internal.xs.XSModelGroup;
  86 import com.sun.org.apache.xerces.internal.xs.XSModelGroupDefinition;
  87 import com.sun.org.apache.xerces.internal.xs.XSNamedMap;
  88 import com.sun.org.apache.xerces.internal.xs.XSObject;
  89 import com.sun.org.apache.xerces.internal.xs.XSObjectList;
  90 import com.sun.org.apache.xerces.internal.xs.XSParticle;
  91 import com.sun.org.apache.xerces.internal.xs.XSSimpleTypeDefinition;
  92 import com.sun.org.apache.xerces.internal.xs.XSTerm;
  93 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
  94 import com.sun.org.apache.xerces.internal.xs.datatypes.ObjectList;
  95 import java.io.IOException;
  96 import java.io.StringReader;
  97 import java.util.ArrayList;
  98 import java.util.Collections;
  99 import java.util.HashMap;
 100 import java.util.Locale;
 101 import java.util.Map;
 102 import java.util.Stack;
 103 import java.util.Vector;
 104 import javax.xml.XMLConstants;
 105 import javax.xml.stream.XMLEventReader;
 106 import javax.xml.stream.XMLStreamException;
 107 import javax.xml.stream.XMLStreamReader;
 108 import jdk.xml.internal.JdkXmlUtils;
 109 import org.w3c.dom.Document;
 110 import org.w3c.dom.Element;
 111 import org.w3c.dom.Node;
 112 import org.xml.sax.InputSource;
 113 import org.xml.sax.SAXException;
 114 import org.xml.sax.SAXNotRecognizedException;
 115 import org.xml.sax.SAXParseException;
 116 import org.xml.sax.XMLReader;
 117 
 118 /**
 119  * The purpose of this class is to co-ordinate the construction of a
 120  * grammar object corresponding to a schema.  To do this, it must be
 121  * prepared to parse several schema documents (for instance if the
 122  * schema document originally referred to contains <include> or
 123  * <redefined> information items).  If any of the schemas imports a
 124  * schema, other grammars may be constructed as a side-effect.
 125  *
 126  * @xerces.internal
 127  *
 128  * @author Neil Graham, IBM
 129  * @author Pavani Mukthipudi, Sun Microsystems
 130  *
 131  */
 132 public class XSDHandler {
 133 
 134     /** Feature identifier: validation. */
 135     protected static final String VALIDATION =
 136         Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE;
 137 
 138     /** feature identifier: XML Schema validation */
 139     protected static final String XMLSCHEMA_VALIDATION =
 140         Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE;
 141 
 142     /** Feature identifier:  allow java encodings */
 143     protected static final String ALLOW_JAVA_ENCODINGS =
 144         Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE;
 145 
 146     /** Feature identifier:  continue after fatal error */
 147     protected static final String CONTINUE_AFTER_FATAL_ERROR =
 148         Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE;
 149 
 150     /** Feature identifier:  allow java encodings */
 151     protected static final String STANDARD_URI_CONFORMANT_FEATURE =
 152         Constants.XERCES_FEATURE_PREFIX + Constants.STANDARD_URI_CONFORMANT_FEATURE;
 153 
 154     /** Feature: disallow doctype*/
 155     protected static final String DISALLOW_DOCTYPE =
 156         Constants.XERCES_FEATURE_PREFIX + Constants.DISALLOW_DOCTYPE_DECL_FEATURE;
 157 
 158     /** Feature: generate synthetic annotations */
 159     protected static final String GENERATE_SYNTHETIC_ANNOTATIONS =
 160         Constants.XERCES_FEATURE_PREFIX + Constants.GENERATE_SYNTHETIC_ANNOTATIONS_FEATURE;
 161 
 162     /** Feature identifier: validate annotations. */
 163     protected static final String VALIDATE_ANNOTATIONS =
 164         Constants.XERCES_FEATURE_PREFIX + Constants.VALIDATE_ANNOTATIONS_FEATURE;
 165 
 166     /** Feature identifier: honour all schemaLocations */
 167     protected static final String HONOUR_ALL_SCHEMALOCATIONS =
 168       Constants.XERCES_FEATURE_PREFIX + Constants.HONOUR_ALL_SCHEMALOCATIONS_FEATURE;
 169 
 170     /** Feature identifier: namespace growth */
 171     protected static final String NAMESPACE_GROWTH =
 172       Constants.XERCES_FEATURE_PREFIX + Constants.NAMESPACE_GROWTH_FEATURE;
 173 
 174     /** Feature identifier: tolerate duplicates */
 175     protected static final String TOLERATE_DUPLICATES =
 176       Constants.XERCES_FEATURE_PREFIX + Constants.TOLERATE_DUPLICATES_FEATURE;
 177 
 178     /** Feature identifier: namespace prefixes. */
 179     private static final String NAMESPACE_PREFIXES =
 180         Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACE_PREFIXES_FEATURE;
 181 
 182     /** Feature identifier: string interning. */
 183     protected static final String STRING_INTERNING =
 184         Constants.SAX_FEATURE_PREFIX + Constants.STRING_INTERNING_FEATURE;
 185 
 186     /** Property identifier: error handler. */
 187     protected static final String ERROR_HANDLER =
 188         Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY;
 189 
 190     /** Property identifier: JAXP schema source. */
 191     protected static final String JAXP_SCHEMA_SOURCE =
 192         Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE;
 193 
 194     /** Property identifier: entity resolver. */
 195     public static final String ENTITY_RESOLVER =
 196         Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY;
 197 
 198     /** Property identifier: entity manager. */
 199     protected static final String ENTITY_MANAGER =
 200         Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
 201 
 202     /** Property identifier: error reporter. */
 203     public static final String ERROR_REPORTER =
 204         Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
 205 
 206     /** Property identifier: grammar pool. */
 207     public static final String XMLGRAMMAR_POOL =
 208         Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
 209 
 210     /** Property identifier: symbol table. */
 211     public static final String SYMBOL_TABLE =
 212         Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
 213 
 214     /** Property identifier: security manager. */
 215     protected static final String SECURITY_MANAGER =
 216         Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
 217 
 218     /** Property identifier: locale. */
 219     protected static final String LOCALE =
 220         Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY;
 221 
 222     /** Property identifier: Security property manager. */
 223     private static final String XML_SECURITY_PROPERTY_MANAGER =
 224         Constants.XML_SECURITY_PROPERTY_MANAGER;
 225 
 226     protected static final boolean DEBUG_NODE_POOL = false;
 227 
 228     // Data
 229 
 230     // different sorts of declarations; should make lookup and
 231     // traverser calling more efficient/less bulky.
 232     final static int ATTRIBUTE_TYPE          = 1;
 233     final static int ATTRIBUTEGROUP_TYPE     = 2;
 234     final static int ELEMENT_TYPE            = 3;
 235     final static int GROUP_TYPE              = 4;
 236     final static int IDENTITYCONSTRAINT_TYPE = 5;
 237     final static int NOTATION_TYPE           = 6;
 238     final static int TYPEDECL_TYPE           = 7;
 239 
 240     // this string gets appended to redefined names; it's purpose is to be
 241     // as unlikely as possible to cause collisions.
 242     public final static String REDEF_IDENTIFIER = "_fn3dktizrknc9pi";
 243 
 244     //protected data that can be accessible by any traverser
 245 
 246     protected XSDeclarationPool fDeclPool = null;
 247 
 248     // the Security manager in effect.
 249     protected XMLSecurityManager fSecurityManager = null;
 250 
 251     private String fAccessExternalSchema;
 252     private String fAccessExternalDTD;
 253 
 254     // These tables correspond to the symbol spaces defined in the
 255     // spec.
 256     // They are keyed with a QName (that is, String("URI,localpart) and
 257     // their values are nodes corresponding to the given name's decl.
 258     // By asking the node for its ownerDocument and looking in
 259     // XSDocumentInfoRegistry we can easily get the corresponding
 260     // XSDocumentInfo object.
 261     private boolean registryEmpty = true;
 262     private Map<String, Element> fUnparsedAttributeRegistry = new HashMap<>();
 263     private Map<String, Element> fUnparsedAttributeGroupRegistry =  new HashMap<>();
 264     private Map<String, Element> fUnparsedElementRegistry =  new HashMap<>();
 265     private Map<String, Element> fUnparsedGroupRegistry =  new HashMap<>();
 266     private Map<String, Element> fUnparsedIdentityConstraintRegistry =  new HashMap<>();
 267     private Map<String, Element> fUnparsedNotationRegistry =  new HashMap<>();
 268     private Map<String, Element> fUnparsedTypeRegistry =  new HashMap<>();
 269     // Compensation for the above maps to locate XSDocumentInfo,
 270     // Since we may take Schema Element directly, so can not get the
 271     // corresponding XSDocumentInfo object just using above maps.
 272     private Map<String, XSDocumentInfo> fUnparsedAttributeRegistrySub =  new HashMap<>();
 273     private Map<String, XSDocumentInfo> fUnparsedAttributeGroupRegistrySub =  new HashMap<>();
 274     private Map<String, XSDocumentInfo> fUnparsedElementRegistrySub =  new HashMap<>();
 275     private Map<String, XSDocumentInfo> fUnparsedGroupRegistrySub =  new HashMap<>();
 276     private Map<String, XSDocumentInfo> fUnparsedIdentityConstraintRegistrySub =  new HashMap<>();
 277     private Map<String, XSDocumentInfo> fUnparsedNotationRegistrySub =  new HashMap<>();
 278     private Map<String, XSDocumentInfo> fUnparsedTypeRegistrySub =  new HashMap<>();
 279 
 280     // Stores XSDocumentInfo (keyed by component name), to check for duplicate
 281     // components declared within the same xsd document
 282     @SuppressWarnings("unchecked")
 283     private Map<String, XSDocumentInfo> fUnparsedRegistriesExt[] = new HashMap[] {
 284         null,
 285         null, // ATTRIBUTE_TYPE
 286         null, // ATTRIBUTEGROUP_TYPE
 287         null, // ELEMENT_TYPE
 288         null, // GROUP_TYPE
 289         null, // IDENTITYCONSTRAINT_TYPE
 290         null, // NOTATION_TYPE
 291         null, // TYPEDECL_TYPE
 292     };
 293 
 294     // this map is keyed on by XSDocumentInfo objects.  Its values
 295     // are Vectors containing the XSDocumentInfo objects <include>d,
 296     // <import>ed or <redefine>d by the key XSDocumentInfo.
 297     private Map<XSDocumentInfo, Vector<XSDocumentInfo>> fDependencyMap = new HashMap<>();
 298 
 299     // this map is keyed on by a target namespace.  Its values
 300     // are Vectors containing namespaces imported by schema documents
 301     // with the key target namespace.
 302     // if an imported schema has absent namespace, the value "null" is stored.
 303     private Map<String, Vector> fImportMap = new HashMap<> ();
 304 
 305     // all namespaces that imports other namespaces
 306     // if the importing schema has absent namespace, empty string is stored.
 307     // (because the key of a map can't be null.)
 308     private Vector<String> fAllTNSs = new Vector<>();
 309 
 310     // stores instance document mappings between namespaces and schema hints
 311     private Map<String, XMLSchemaLoader.LocationArray> fLocationPairs = null;
 312 
 313     // Records which nodes are hidden when the input is a DOMInputSource.
 314     Map<Node, String> fHiddenNodes = null;
 315 
 316     // convenience methods
 317     private String null2EmptyString(String ns) {
 318         return ns == null ? XMLSymbols.EMPTY_STRING : ns;
 319     }
 320     private String emptyString2Null(String ns) {
 321         return ns == XMLSymbols.EMPTY_STRING ? null : ns;
 322     }
 323     // use Schema Element to lookup the SystemId.
 324     private String doc2SystemId(Element ele) {
 325         String documentURI = null;
 326         /**
 327          * REVISIT: Casting until DOM Level 3 interfaces are available. -- mrglavas
 328          */
 329         if(ele.getOwnerDocument() instanceof com.sun.org.apache.xerces.internal.impl.xs.opti.SchemaDOM){
 330             documentURI = ((com.sun.org.apache.xerces.internal.impl.xs.opti.SchemaDOM) ele.getOwnerDocument()).getDocumentURI();
 331         }
 332         return documentURI != null ? documentURI : fDoc2SystemId.get(ele);
 333     }
 334 
 335     // This vector stores strings which are combinations of the
 336     // publicId and systemId of the inputSource corresponding to a
 337     // schema document.  This combination is used so that the user's
 338     // EntityResolver can provide a consistent way of identifying a
 339     // schema document that is included in multiple other schemas.
 340     private Map<XSDKey, Element> fTraversed = new HashMap<>();
 341 
 342     // this map contains a mapping from Schema Element to its systemId
 343     // this is useful to resolve a uri relative to the referring document
 344     private Map<Element, String> fDoc2SystemId = new HashMap<>();
 345 
 346     // the primary XSDocumentInfo we were called to parse
 347     private XSDocumentInfo fRoot = null;
 348 
 349     // This map's job is to act as a link between the Schema Element and its
 350     // XSDocumentInfo object.
 351     private Map fDoc2XSDocumentMap = new HashMap();
 352 
 353     // map between <redefine> elements and the XSDocumentInfo
 354     // objects that correspond to the documents being redefined.
 355     private Map fRedefine2XSDMap = null;
 356 
 357     // map between <redefine> elements and the namespace support
 358     private Map fRedefine2NSSupport = null;
 359 
 360     // these objects store a mapping between the names of redefining
 361     // groups/attributeGroups and the groups/AttributeGroups which
 362     // they redefine by restriction (implicitly).  It is up to the
 363     // Group and AttributeGroup traversers to check these restrictions for
 364     // validity.
 365     private Map fRedefinedRestrictedAttributeGroupRegistry = new HashMap();
 366     private Map fRedefinedRestrictedGroupRegistry = new HashMap();
 367 
 368     // a variable storing whether the last schema document
 369     // processed (by getSchema) was a duplicate.
 370     private boolean fLastSchemaWasDuplicate;
 371 
 372     // validate annotations feature
 373     private boolean fValidateAnnotations = false;
 374 
 375     //handle multiple import feature
 376     private boolean fHonourAllSchemaLocations = false;
 377 
 378     //handle namespace growth feature
 379     boolean fNamespaceGrowth = false;
 380 
 381     // handle tolerate duplicates feature
 382     boolean fTolerateDuplicates = false;
 383 
 384     // the XMLErrorReporter
 385     private XMLErrorReporter fErrorReporter;
 386 
 387     // the XMLErrorHandler
 388     private XMLErrorHandler fErrorHandler;
 389 
 390     // the Locale
 391     private Locale fLocale;
 392 
 393     // the XMLEntityManager
 394     private XMLEntityResolver fEntityManager;
 395 
 396     // the XSAttributeChecker
 397     private XSAttributeChecker fAttributeChecker;
 398 
 399     // the symbol table
 400     private SymbolTable fSymbolTable;
 401 
 402     // the GrammarResolver
 403     private XSGrammarBucket fGrammarBucket;
 404 
 405     // the Grammar description
 406     private XSDDescription fSchemaGrammarDescription;
 407 
 408     // the Grammar Pool
 409     private XMLGrammarPool fGrammarPool;
 410 
 411     // the security property manager
 412     private XMLSecurityPropertyManager fSecurityPropertyMgr = null;
 413 
 414     private boolean fOverrideDefaultParser;
 415 
 416     //************ Traversers **********
 417     XSDAttributeGroupTraverser fAttributeGroupTraverser;
 418     XSDAttributeTraverser fAttributeTraverser;
 419     XSDComplexTypeTraverser fComplexTypeTraverser;
 420     XSDElementTraverser fElementTraverser;
 421     XSDGroupTraverser fGroupTraverser;
 422     XSDKeyrefTraverser fKeyrefTraverser;
 423     XSDNotationTraverser fNotationTraverser;
 424     XSDSimpleTypeTraverser fSimpleTypeTraverser;
 425     XSDUniqueOrKeyTraverser fUniqueOrKeyTraverser;
 426     XSDWildcardTraverser fWildCardTraverser;
 427 
 428     SchemaDVFactory fDVFactory;
 429     SchemaDOMParser fSchemaParser;
 430     SchemaContentHandler fXSContentHandler;
 431     StAXSchemaParser fStAXSchemaParser;
 432     XML11Configuration fAnnotationValidator;
 433     XSAnnotationGrammarPool fGrammarBucketAdapter;
 434 
 435     // these data members are needed for the deferred traversal
 436     // of local elements.
 437 
 438     // the initial size of the array to store deferred local elements
 439     private static final int INIT_STACK_SIZE = 30;
 440     // the incremental size of the array to store deferred local elements
 441     private static final int INC_STACK_SIZE  = 10;
 442     // current position of the array (# of deferred local elements)
 443     private int fLocalElemStackPos = 0;
 444 
 445     private XSParticleDecl[] fParticle = new XSParticleDecl[INIT_STACK_SIZE];
 446     private Element[] fLocalElementDecl = new Element[INIT_STACK_SIZE];
 447     private XSDocumentInfo[] fLocalElementDecl_schema = new XSDocumentInfo[INIT_STACK_SIZE]; //JACK
 448     private int[] fAllContext = new int[INIT_STACK_SIZE];
 449     private XSObject[] fParent = new XSObject[INIT_STACK_SIZE];
 450     private String [][] fLocalElemNamespaceContext = new String [INIT_STACK_SIZE][1];
 451 
 452     // these data members are needed for the deferred traversal
 453     // of keyrefs.
 454 
 455     // the initial size of the array to store deferred keyrefs
 456     private static final int INIT_KEYREF_STACK = 2;
 457     // the incremental size of the array to store deferred keyrefs
 458     private static final int INC_KEYREF_STACK_AMOUNT = 2;
 459     // current position of the array (# of deferred keyrefs)
 460     private int fKeyrefStackPos = 0;
 461 
 462     private Element [] fKeyrefs = new Element[INIT_KEYREF_STACK];
 463     private XSDocumentInfo [] fKeyrefsMapXSDocumentInfo = new XSDocumentInfo[INIT_KEYREF_STACK];
 464     private XSElementDecl [] fKeyrefElems = new XSElementDecl [INIT_KEYREF_STACK];
 465     private String [][] fKeyrefNamespaceContext = new String[INIT_KEYREF_STACK][1];
 466 
 467     // global decls: map from decl name to decl object
 468     SymbolHash fGlobalAttrDecls = new SymbolHash(12);
 469     SymbolHash fGlobalAttrGrpDecls = new SymbolHash(5);
 470     SymbolHash fGlobalElemDecls = new SymbolHash(25);
 471     SymbolHash fGlobalGroupDecls = new SymbolHash(5);
 472     SymbolHash fGlobalNotationDecls = new SymbolHash(1);
 473     SymbolHash fGlobalIDConstraintDecls = new SymbolHash(3);
 474     SymbolHash fGlobalTypeDecls = new SymbolHash(25);
 475 
 476     // Constructors
 477     public XSDHandler(){
 478         fHiddenNodes = new HashMap<>();
 479         fSchemaParser = new SchemaDOMParser(new SchemaParsingConfig());
 480     }
 481 
 482     // it should be possible to use the same XSDHandler to parse
 483     // multiple schema documents; this will allow one to be
 484     // constructed.
 485     public XSDHandler (XSGrammarBucket gBucket) {
 486         this();
 487         fGrammarBucket = gBucket;
 488 
 489         // Note: don't use SchemaConfiguration internally
 490         //       we will get stack overflaw because
 491         //       XMLSchemaValidator will be instantiating XSDHandler...
 492         fSchemaGrammarDescription = new XSDDescription();
 493     } // end constructor
 494 
 495     /**
 496      * This method initiates the parse of a schema.  It will likely be
 497      * called from the Validator and it will make the
 498      * resulting grammar available; it returns a reference to this object just
 499      * in case.  A reset(XMLComponentManager) must be called before this methods is called.
 500      * @param is
 501      * @param desc
 502      * @param locationPairs
 503      * @return the SchemaGrammar
 504      * @throws IOException
 505      */
 506     public SchemaGrammar parseSchema(XMLInputSource is, XSDDescription desc,
 507             Map<String, XMLSchemaLoader.LocationArray> locationPairs)
 508     throws IOException {
 509         fLocationPairs = locationPairs;
 510         fSchemaParser.resetNodePool();
 511         SchemaGrammar grammar = null;
 512         String schemaNamespace  = null;
 513         short referType = desc.getContextType();
 514 
 515         // if loading using JAXP schemaSource property, or using grammar caching loadGrammar
 516         // the desc.targetNamespace is always null.
 517         // Therefore we should not attempt to find out if
 518         // the schema is already in the bucket, since in the case we have
 519         // no namespace schema in the bucket, findGrammar will always return the
 520         // no namespace schema.
 521         if (referType != XSDDescription.CONTEXT_PREPARSE){
 522             // first try to find it in the bucket/pool, return if one is found
 523             if (fHonourAllSchemaLocations && referType == XSDDescription.CONTEXT_IMPORT && isExistingGrammar(desc, fNamespaceGrowth)) {
 524                 grammar = fGrammarBucket.getGrammar(desc.getTargetNamespace());
 525             }
 526             else {
 527                 grammar = findGrammar(desc, fNamespaceGrowth);
 528             }
 529             if (grammar != null) {
 530                 if (!fNamespaceGrowth) {
 531                     return grammar;
 532                 }
 533                 else {
 534                     try {
 535                         if (grammar.getDocumentLocations().contains(XMLEntityManager.expandSystemId(is.getSystemId(), is.getBaseSystemId(), false))) {
 536                             return grammar;
 537                         }
 538                     }
 539                     catch (MalformedURIException e) {
 540                         //REVISIT: return the grammar?
 541                     }
 542                 }
 543             }
 544 
 545             schemaNamespace = desc.getTargetNamespace();
 546             // handle empty string URI as null
 547             if (schemaNamespace != null) {
 548                 schemaNamespace = fSymbolTable.addSymbol(schemaNamespace);
 549             }
 550         }
 551 
 552         // before parsing a schema, need to clear registries associated with
 553         // parsing schemas
 554         prepareForParse();
 555 
 556         Element schemaRoot = null;
 557         // first phase:  construct trees.
 558         if (is instanceof DOMInputSource) {
 559             schemaRoot = getSchemaDocument(schemaNamespace, (DOMInputSource) is,
 560                     referType == XSDDescription.CONTEXT_PREPARSE,
 561                     referType, null);
 562         } // DOMInputSource
 563         else if (is instanceof SAXInputSource) {
 564                 schemaRoot = getSchemaDocument(schemaNamespace, (SAXInputSource) is,
 565                     referType == XSDDescription.CONTEXT_PREPARSE,
 566                     referType, null);
 567         } // SAXInputSource
 568         else if (is instanceof StAXInputSource) {
 569             schemaRoot = getSchemaDocument(schemaNamespace, (StAXInputSource) is,
 570                     referType == XSDDescription.CONTEXT_PREPARSE,
 571                     referType, null);
 572         } // StAXInputSource
 573         else if (is instanceof XSInputSource) {
 574             schemaRoot = getSchemaDocument((XSInputSource) is, desc);
 575         } // XSInputSource
 576         else {
 577                 schemaRoot = getSchemaDocument(schemaNamespace, is,
 578                   referType == XSDDescription.CONTEXT_PREPARSE,
 579                   referType, null);
 580 
 581         } //is instanceof XMLInputSource
 582 
 583         if (schemaRoot == null) {
 584             // something went wrong right off the hop
 585             if (is instanceof XSInputSource) {
 586                 return fGrammarBucket.getGrammar(desc.getTargetNamespace());
 587             }
 588             return grammar;
 589         }
 590 
 591         if (referType == XSDDescription.CONTEXT_PREPARSE) {
 592                 Element schemaElem = schemaRoot;
 593             schemaNamespace = DOMUtil.getAttrValue(schemaElem, SchemaSymbols.ATT_TARGETNAMESPACE);
 594             if(schemaNamespace != null && schemaNamespace.length() > 0) {
 595                 // Since now we've discovered a namespace, we need to update xsd key
 596                 // and store this schema in traversed schemas bucket
 597                 schemaNamespace = fSymbolTable.addSymbol(schemaNamespace);
 598                 desc.setTargetNamespace(schemaNamespace);
 599             }
 600             else {
 601                 schemaNamespace = null;
 602             }
 603             grammar = findGrammar(desc, fNamespaceGrowth);
 604             String schemaId = XMLEntityManager.expandSystemId(is.getSystemId(), is.getBaseSystemId(), false);
 605             if (grammar != null) {
 606                 // When namespace growth is enabled and a null location is provided we cannot tell
 607                 // whether we've loaded this schema document before so we must assume that we haven't.
 608                 if (!fNamespaceGrowth || (schemaId != null && grammar.getDocumentLocations().contains(schemaId))) {
 609                     return grammar;
 610                 }
 611             }
 612 
 613             XSDKey key = new XSDKey(schemaId, referType, schemaNamespace);
 614             fTraversed.put(key, schemaRoot);
 615             if (schemaId != null) {
 616                 fDoc2SystemId.put(schemaRoot, schemaId);
 617             }
 618         }
 619 
 620         // before constructing trees and traversing a schema, need to reset
 621         // all traversers and clear all registries
 622         prepareForTraverse();
 623 
 624         fRoot = constructTrees(schemaRoot, is.getSystemId(), desc, grammar != null);
 625         if (fRoot == null) {
 626             return null;
 627         }
 628 
 629         // second phase:  fill global registries.
 630         buildGlobalNameRegistries();
 631 
 632         // third phase:  call traversers
 633         ArrayList annotationInfo = fValidateAnnotations ? new ArrayList() : null;
 634         traverseSchemas(annotationInfo);
 635 
 636         // fourth phase: handle local element decls
 637         traverseLocalElements();
 638 
 639         // fifth phase:  handle Keyrefs
 640         resolveKeyRefs();
 641 
 642         // sixth phase:  validate attribute of non-schema namespaces
 643         // REVISIT: skip this for now. we really don't want to do it.
 644         //fAttributeChecker.checkNonSchemaAttributes(fGrammarBucket);
 645 
 646         // seventh phase:  store imported grammars
 647         // for all grammars with <import>s
 648         for (int i = fAllTNSs.size() - 1; i >= 0; i--) {
 649             // get its target namespace
 650             String tns = fAllTNSs.elementAt(i);
 651             // get all namespaces it imports
 652             Vector ins = (Vector)fImportMap.get(tns);
 653             // get the grammar
 654             SchemaGrammar sg = fGrammarBucket.getGrammar(emptyString2Null(tns));
 655             if (sg == null)
 656                 continue;
 657             SchemaGrammar isg;
 658             // for imported namespace
 659             int count = 0;
 660             for (int j = 0; j < ins.size(); j++) {
 661                 // get imported grammar
 662                 isg = fGrammarBucket.getGrammar((String)ins.elementAt(j));
 663                 // reuse the same vector
 664                 if (isg != null)
 665                     ins.setElementAt(isg, count++);
 666             }
 667             ins.setSize(count);
 668             // set the imported grammars
 669             sg.setImportedGrammars(ins);
 670         }
 671 
 672         /** validate annotations **/
 673         if (fValidateAnnotations && annotationInfo.size() > 0) {
 674             validateAnnotations(annotationInfo);
 675         }
 676 
 677         // and return.
 678         return fGrammarBucket.getGrammar(fRoot.fTargetNamespace);
 679     } // end parseSchema
 680 
 681     private void validateAnnotations(ArrayList annotationInfo) {
 682         if (fAnnotationValidator == null) {
 683             createAnnotationValidator();
 684         }
 685         final int size = annotationInfo.size();
 686         final XMLInputSource src = new XMLInputSource(null, null, null);
 687         fGrammarBucketAdapter.refreshGrammars(fGrammarBucket);
 688         for (int i = 0; i < size; i += 2) {
 689             src.setSystemId((String) annotationInfo.get(i));
 690             XSAnnotationInfo annotation = (XSAnnotationInfo) annotationInfo.get(i+1);
 691             while (annotation != null) {
 692                 src.setCharacterStream(new StringReader(annotation.fAnnotation));
 693                 try {
 694                     fAnnotationValidator.parse(src);
 695                 }
 696                 catch (IOException exc) {}
 697                 annotation = annotation.next;
 698             }
 699         }
 700     }
 701 
 702     private void createAnnotationValidator() {
 703         fAnnotationValidator = new XML11Configuration();
 704         fGrammarBucketAdapter = new XSAnnotationGrammarPool();
 705         fAnnotationValidator.setFeature(VALIDATION, true);
 706         fAnnotationValidator.setFeature(XMLSCHEMA_VALIDATION, true);
 707         fAnnotationValidator.setProperty(XMLGRAMMAR_POOL, fGrammarBucketAdapter);
 708         /** set security manager and XML Security Property Manager **/
 709         fAnnotationValidator.setProperty(SECURITY_MANAGER, (fSecurityManager != null) ? fSecurityManager : new XMLSecurityManager(true));
 710         fAnnotationValidator.setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
 711         /** Set error handler. **/
 712         fAnnotationValidator.setProperty(ERROR_HANDLER, (fErrorHandler != null) ? fErrorHandler : new DefaultErrorHandler());
 713         /** Set locale. **/
 714         fAnnotationValidator.setProperty(LOCALE, fLocale);
 715     }
 716 
 717     /**
 718      * Pull the grammar out of the bucket simply using
 719      * its TNS as a key
 720      */
 721     SchemaGrammar getGrammar(String tns) {
 722         return fGrammarBucket.getGrammar(tns);
 723     }
 724 
 725     /**
 726      * First try to find a grammar in the bucket, if failed, consult the
 727      * grammar pool. If a grammar is found in the pool, then add it (and all
 728      * imported ones) into the bucket.
 729      */
 730     protected SchemaGrammar findGrammar(XSDDescription desc, boolean ignoreConflict) {
 731         SchemaGrammar sg = fGrammarBucket.getGrammar(desc.getTargetNamespace());
 732         if (sg == null) {
 733             if (fGrammarPool != null) {
 734                 sg = (SchemaGrammar)fGrammarPool.retrieveGrammar(desc);
 735                 if (sg != null) {
 736                     // put this grammar into the bucket, along with grammars
 737                     // imported by it (directly or indirectly)
 738                     if (!fGrammarBucket.putGrammar(sg, true, ignoreConflict)) {
 739                         // REVISIT: a conflict between new grammar(s) and grammars
 740                         // in the bucket. What to do? A warning? An exception?
 741                         reportSchemaWarning("GrammarConflict", null, null);
 742                         sg = null;
 743                     }
 744                 }
 745             }
 746         }
 747         return sg;
 748     }
 749 
 750     // may wish to have setter methods for ErrorHandler,
 751     // EntityResolver...
 752 
 753     private static final String[][] NS_ERROR_CODES = {
 754             {"src-include.2.1", "src-include.2.1"},
 755             {"src-redefine.3.1", "src-redefine.3.1"},
 756             {"src-import.3.1", "src-import.3.2"},
 757             null,
 758             {"TargetNamespace.1", "TargetNamespace.2"},
 759             {"TargetNamespace.1", "TargetNamespace.2"},
 760             {"TargetNamespace.1", "TargetNamespace.2"},
 761             {"TargetNamespace.1", "TargetNamespace.2"}
 762     };
 763 
 764     private static final String[] ELE_ERROR_CODES = {
 765             "src-include.1", "src-redefine.2", "src-import.2", "schema_reference.4",
 766             "schema_reference.4", "schema_reference.4", "schema_reference.4", "schema_reference.4"
 767     };
 768 
 769     // This method does several things:
 770     // It constructs an instance of an XSDocumentInfo object using the
 771     // schemaRoot node.  Then, for each <include>,
 772     // <redefine>, and <import> children, it attempts to resolve the
 773     // requested schema document, initiates a DOM parse, and calls
 774     // itself recursively on that document's root.  It also records in
 775     // the DependencyMap object what XSDocumentInfo objects its XSDocumentInfo
 776     // depends on.
 777     // It also makes sure the targetNamespace of the schema it was
 778     // called to parse is correct.
 779     protected XSDocumentInfo constructTrees(Element schemaRoot, String locationHint, XSDDescription desc, boolean nsCollision) {
 780         if (schemaRoot == null) return null;
 781         String callerTNS = desc.getTargetNamespace();
 782         short referType = desc.getContextType();
 783 
 784         XSDocumentInfo currSchemaInfo = null;
 785         try {
 786             // note that attributes are freed at end of traverseSchemas()
 787             currSchemaInfo = new XSDocumentInfo(schemaRoot, fAttributeChecker, fSymbolTable);
 788         } catch (XMLSchemaException se) {
 789             reportSchemaError(ELE_ERROR_CODES[referType],
 790                     new Object[]{locationHint},
 791                                           schemaRoot);
 792             return null;
 793         }
 794         // targetNamespace="" is not valid, issue a warning, and ignore it
 795         if (currSchemaInfo.fTargetNamespace != null &&
 796                 currSchemaInfo.fTargetNamespace.length() == 0) {
 797             reportSchemaWarning("EmptyTargetNamespace",
 798                     new Object[]{locationHint},
 799                                         schemaRoot);
 800             currSchemaInfo.fTargetNamespace = null;
 801         }
 802 
 803         if (callerTNS != null) {
 804             // the second index to the NS_ERROR_CODES array
 805             // if the caller/expected NS is not absent, we use the first column
 806             int secondIdx = 0;
 807             // for include and redefine
 808             if (referType == XSDDescription.CONTEXT_INCLUDE ||
 809                     referType == XSDDescription.CONTEXT_REDEFINE) {
 810                 // if the referred document has no targetNamespace,
 811                 // it's a chameleon schema
 812                 if (currSchemaInfo.fTargetNamespace == null) {
 813                     currSchemaInfo.fTargetNamespace = callerTNS;
 814                     currSchemaInfo.fIsChameleonSchema = true;
 815                 }
 816                 // if the referred document has a target namespace differing
 817                 // from the caller, it's an error
 818                 else if (callerTNS != currSchemaInfo.fTargetNamespace) {
 819                     reportSchemaError(NS_ERROR_CODES[referType][secondIdx],
 820                             new Object [] {callerTNS, currSchemaInfo.fTargetNamespace},
 821                                                         schemaRoot);
 822                     return null;
 823                 }
 824             }
 825             // for instance and import, the two NS's must be the same
 826             else if (referType != XSDDescription.CONTEXT_PREPARSE && callerTNS != currSchemaInfo.fTargetNamespace) {
 827                 reportSchemaError(NS_ERROR_CODES[referType][secondIdx],
 828                         new Object [] {callerTNS, currSchemaInfo.fTargetNamespace},
 829                                                 schemaRoot);
 830                 return null;
 831             }
 832         }
 833         // now there is no caller/expected NS, it's an error for the referred
 834         // document to have a target namespace, unless we are preparsing a schema
 835         else if (currSchemaInfo.fTargetNamespace != null) {
 836             // set the target namespace of the description
 837             if (referType == XSDDescription.CONTEXT_PREPARSE) {
 838                 desc.setTargetNamespace(currSchemaInfo.fTargetNamespace);
 839                 callerTNS = currSchemaInfo.fTargetNamespace;
 840             }
 841             else {
 842                 // the second index to the NS_ERROR_CODES array
 843                 // if the caller/expected NS is absent, we use the second column
 844                 int secondIdx = 1;
 845                 reportSchemaError(NS_ERROR_CODES[referType][secondIdx],
 846                         new Object [] {callerTNS, currSchemaInfo.fTargetNamespace},
 847                                                 schemaRoot);
 848                 return null;
 849             }
 850         }
 851         // the other cases (callerTNS == currSchemaInfo.fTargetNamespce == null)
 852         // are valid
 853 
 854         // a schema document can always access it's own target namespace
 855         currSchemaInfo.addAllowedNS(currSchemaInfo.fTargetNamespace);
 856 
 857         SchemaGrammar sg = null;
 858 
 859         // we have a namespace collision
 860         if (nsCollision) {
 861             SchemaGrammar sg2 = fGrammarBucket.getGrammar(currSchemaInfo.fTargetNamespace);
 862             if (sg2.isImmutable()) {
 863                 sg = new SchemaGrammar(sg2);
 864                 fGrammarBucket.putGrammar(sg);
 865                 // update all the grammars in the bucket to point to the new grammar.
 866                 updateImportListWith(sg);
 867             }
 868             else {
 869                 sg = sg2;
 870             }
 871 
 872             // update import list of the new grammar
 873             updateImportListFor(sg);
 874         }
 875         else if (referType == XSDDescription.CONTEXT_INCLUDE ||
 876                 referType == XSDDescription.CONTEXT_REDEFINE) {
 877             sg = fGrammarBucket.getGrammar(currSchemaInfo.fTargetNamespace);
 878         }
 879         else if(fHonourAllSchemaLocations && referType == XSDDescription.CONTEXT_IMPORT) {
 880             sg = findGrammar(desc, false);
 881             if(sg == null) {
 882                 sg = new SchemaGrammar(currSchemaInfo.fTargetNamespace, desc.makeClone(), fSymbolTable);
 883                 fGrammarBucket.putGrammar(sg);
 884             }
 885         }
 886         else {
 887             sg = new SchemaGrammar(currSchemaInfo.fTargetNamespace, desc.makeClone(), fSymbolTable);
 888             fGrammarBucket.putGrammar(sg);
 889         }
 890 
 891         // store the document and its location
 892         // REVISIT: don't expose the DOM tree
 893         sg.addDocument(null, fDoc2SystemId.get(currSchemaInfo.fSchemaElement));
 894 
 895         fDoc2XSDocumentMap.put(schemaRoot, currSchemaInfo);
 896         Vector<XSDocumentInfo> dependencies = new Vector<>();
 897         Element rootNode = schemaRoot;
 898 
 899         Element newSchemaRoot = null;
 900         for (Element child = DOMUtil.getFirstChildElement(rootNode);
 901         child != null;
 902         child = DOMUtil.getNextSiblingElement(child)) {
 903             String schemaNamespace=null;
 904             String schemaHint=null;
 905             String localName = DOMUtil.getLocalName(child);
 906 
 907             short refType = -1;
 908             boolean importCollision = false;
 909 
 910             if (localName.equals(SchemaSymbols.ELT_ANNOTATION))
 911                 continue;
 912             else if (localName.equals(SchemaSymbols.ELT_IMPORT)) {
 913                 refType = XSDDescription.CONTEXT_IMPORT;
 914                 // have to handle some validation here too!
 915                 // call XSAttributeChecker to fill in attrs
 916                 Object[] importAttrs = fAttributeChecker.checkAttributes(child, true, currSchemaInfo);
 917                 schemaHint = (String)importAttrs[XSAttributeChecker.ATTIDX_SCHEMALOCATION];
 918                 schemaNamespace = (String)importAttrs[XSAttributeChecker.ATTIDX_NAMESPACE];
 919                 if (schemaNamespace != null)
 920                     schemaNamespace = fSymbolTable.addSymbol(schemaNamespace);
 921 
 922                 // check contents and process optional annotations
 923                 Element importChild = DOMUtil.getFirstChildElement(child);
 924                 if(importChild != null ) {
 925                     String importComponentType = DOMUtil.getLocalName(importChild);
 926                     if (importComponentType.equals(SchemaSymbols.ELT_ANNOTATION)) {
 927                         // promoting annotations to parent component
 928                         sg.addAnnotation(
 929                                 fElementTraverser.traverseAnnotationDecl(importChild, importAttrs, true, currSchemaInfo));
 930                     } else {
 931                         reportSchemaError("s4s-elt-must-match.1", new Object [] {localName, "annotation?", importComponentType}, child);
 932                     }
 933                     if(DOMUtil.getNextSiblingElement(importChild) != null) {
 934                         reportSchemaError("s4s-elt-must-match.1", new Object [] {localName, "annotation?", DOMUtil.getLocalName(DOMUtil.getNextSiblingElement(importChild))}, child);
 935                     }
 936                 }
 937                 else {
 938                     String text = DOMUtil.getSyntheticAnnotation(child);
 939                     if (text != null) {
 940                         sg.addAnnotation(fElementTraverser.traverseSyntheticAnnotation(child, text, importAttrs, true, currSchemaInfo));
 941                     }
 942                 }
 943                 fAttributeChecker.returnAttrArray(importAttrs, currSchemaInfo);
 944 
 945                 // a document can't import another document with the same namespace
 946                 if (schemaNamespace == currSchemaInfo.fTargetNamespace) {
 947                     reportSchemaError(schemaNamespace != null ?
 948                             "src-import.1.1" : "src-import.1.2", new Object [] {schemaNamespace}, child);
 949                     continue;
 950                 }
 951 
 952                 // if this namespace has not been imported by this document,
 953                 //  then import if multiple imports support is enabled.
 954                 if(currSchemaInfo.isAllowedNS(schemaNamespace)) {
 955                     if(!fHonourAllSchemaLocations && !fNamespaceGrowth)
 956                         continue;
 957                 }
 958                 else  {
 959                     currSchemaInfo.addAllowedNS(schemaNamespace);
 960                 }
 961                 // also record the fact that one namespace imports another one
 962                 // convert null to ""
 963                 String tns = null2EmptyString(currSchemaInfo.fTargetNamespace);
 964                 // get all namespaces imported by this one
 965                 Vector ins = (Vector)fImportMap.get(tns);
 966                 // if no namespace was imported, create new Vector
 967                 if (ins == null) {
 968                     // record that this one imports other(s)
 969                     fAllTNSs.addElement(tns);
 970                     ins = new Vector();
 971                     fImportMap.put(tns, ins);
 972                     ins.addElement(schemaNamespace);
 973                 }
 974                 else if (!ins.contains(schemaNamespace)){
 975                     ins.addElement(schemaNamespace);
 976                 }
 977 
 978                 fSchemaGrammarDescription.reset();
 979                 fSchemaGrammarDescription.setContextType(XSDDescription.CONTEXT_IMPORT);
 980                 fSchemaGrammarDescription.setBaseSystemId(doc2SystemId(schemaRoot));
 981                 fSchemaGrammarDescription.setLiteralSystemId(schemaHint);
 982                 fSchemaGrammarDescription.setLocationHints(new String[]{schemaHint});
 983                 fSchemaGrammarDescription.setTargetNamespace(schemaNamespace);
 984 
 985                 // if a grammar with the same namespace and location exists (or being
 986                 // built), ignore this one (don't traverse it).
 987                 SchemaGrammar isg = findGrammar(fSchemaGrammarDescription, fNamespaceGrowth);
 988                 if (isg != null) {
 989                     if (fNamespaceGrowth) {
 990                         try {
 991                             if (isg.getDocumentLocations().contains(XMLEntityManager.expandSystemId(schemaHint, fSchemaGrammarDescription.getBaseSystemId(), false))) {
 992                                 continue;
 993                             }
 994                             else {
 995                                 importCollision = true;
 996                             }
 997                         }
 998                         catch (MalformedURIException e) {
 999                         }
1000                     }
1001                     else if (!fHonourAllSchemaLocations || isExistingGrammar(fSchemaGrammarDescription, false)) {
1002                         continue;
1003                     }
1004                 }
1005                 //if ((!fHonourAllSchemaLocations && findGrammar(fSchemaGrammarDescription) != null) || isExistingGrammar(fSchemaGrammarDescription))
1006                 //    continue;
1007 
1008                 // If "findGrammar" returns a grammar, then this is not the
1009                 // the first time we see a location for a given namespace.
1010                 // Don't consult the location pair map in this case,
1011                 // otherwise the location will be ignored because it'll get
1012                 // resolved to the same location as the first hint.
1013                 newSchemaRoot = resolveSchema(fSchemaGrammarDescription, false, child, isg == null);
1014             }
1015             else if ((localName.equals(SchemaSymbols.ELT_INCLUDE)) ||
1016                     (localName.equals(SchemaSymbols.ELT_REDEFINE))) {
1017                 // validation for redefine/include will be the same here; just
1018                 // make sure TNS is right (don't care about redef contents
1019                 // yet).
1020                 Object[] includeAttrs = fAttributeChecker.checkAttributes(child, true, currSchemaInfo);
1021                 schemaHint = (String)includeAttrs[XSAttributeChecker.ATTIDX_SCHEMALOCATION];
1022                 // store the namespace decls of the redefine element
1023                 if (localName.equals(SchemaSymbols.ELT_REDEFINE)) {
1024                     if (fRedefine2NSSupport == null) fRedefine2NSSupport = new HashMap();
1025                     fRedefine2NSSupport.put(child, new SchemaNamespaceSupport(currSchemaInfo.fNamespaceSupport));
1026                 }
1027 
1028                 // check annotations.  Must do this here to avoid having to
1029                 // re-parse attributes later
1030                 if(localName.equals(SchemaSymbols.ELT_INCLUDE)) {
1031                     Element includeChild = DOMUtil.getFirstChildElement(child);
1032                     if(includeChild != null ) {
1033                         String includeComponentType = DOMUtil.getLocalName(includeChild);
1034                         if (includeComponentType.equals(SchemaSymbols.ELT_ANNOTATION)) {
1035                             // promoting annotations to parent component
1036                             sg.addAnnotation(
1037                                     fElementTraverser.traverseAnnotationDecl(includeChild, includeAttrs, true, currSchemaInfo));
1038                         } else {
1039                             reportSchemaError("s4s-elt-must-match.1", new Object [] {localName, "annotation?", includeComponentType}, child);
1040                         }
1041                         if(DOMUtil.getNextSiblingElement(includeChild) != null) {
1042                             reportSchemaError("s4s-elt-must-match.1", new Object [] {localName, "annotation?", DOMUtil.getLocalName(DOMUtil.getNextSiblingElement(includeChild))}, child);
1043                         }
1044                     }
1045                     else {
1046                         String text = DOMUtil.getSyntheticAnnotation(child);
1047                         if (text != null) {
1048                             sg.addAnnotation(fElementTraverser.traverseSyntheticAnnotation(child, text, includeAttrs, true, currSchemaInfo));
1049                         }
1050                     }
1051                 }
1052                 else {
1053                     for (Element redefinedChild = DOMUtil.getFirstChildElement(child);
1054                     redefinedChild != null;
1055                     redefinedChild = DOMUtil.getNextSiblingElement(redefinedChild)) {
1056                         String redefinedComponentType = DOMUtil.getLocalName(redefinedChild);
1057                         if (redefinedComponentType.equals(SchemaSymbols.ELT_ANNOTATION)) {
1058                             // promoting annotations to parent component
1059                             sg.addAnnotation(
1060                                     fElementTraverser.traverseAnnotationDecl(redefinedChild, includeAttrs, true, currSchemaInfo));
1061                             DOMUtil.setHidden(redefinedChild, fHiddenNodes);
1062                         }
1063                         else {
1064                             String text = DOMUtil.getSyntheticAnnotation(child);
1065                             if (text != null) {
1066                                 sg.addAnnotation(fElementTraverser.traverseSyntheticAnnotation(child, text, includeAttrs, true, currSchemaInfo));
1067                             }
1068                         }
1069                         // catch all other content errors later
1070                     }
1071                 }
1072                 fAttributeChecker.returnAttrArray(includeAttrs, currSchemaInfo);
1073                 // schemaLocation is required on <include> and <redefine>
1074                 if (schemaHint == null) {
1075                     reportSchemaError("s4s-att-must-appear", new Object [] {
1076                             "<include> or <redefine>", "schemaLocation"},
1077                             child);
1078                 }
1079                 // pass the systemId of the current document as the base systemId
1080                 boolean mustResolve = false;
1081                 refType = XSDDescription.CONTEXT_INCLUDE;
1082                 if(localName.equals(SchemaSymbols.ELT_REDEFINE)) {
1083                     mustResolve = nonAnnotationContent(child);
1084                     refType = XSDDescription.CONTEXT_REDEFINE;
1085                 }
1086                 fSchemaGrammarDescription.reset();
1087                 fSchemaGrammarDescription.setContextType(refType);
1088                 fSchemaGrammarDescription.setBaseSystemId(doc2SystemId(schemaRoot));
1089                 fSchemaGrammarDescription.setLocationHints(new String[]{schemaHint});
1090                 fSchemaGrammarDescription.setTargetNamespace(callerTNS);
1091 
1092                 boolean alreadyTraversed = false;
1093                 XMLInputSource schemaSource = resolveSchemaSource(fSchemaGrammarDescription, mustResolve, child, true);
1094                 if (fNamespaceGrowth && refType == XSDDescription.CONTEXT_INCLUDE) {
1095                     try {
1096                         final String schemaId = XMLEntityManager.expandSystemId(schemaSource.getSystemId(), schemaSource.getBaseSystemId(), false);
1097                         alreadyTraversed = sg.getDocumentLocations().contains(schemaId);
1098                     }
1099                     catch(MalformedURIException e) {
1100 
1101                     }
1102                 }
1103 
1104                 if (!alreadyTraversed) {
1105                     newSchemaRoot = resolveSchema(schemaSource, fSchemaGrammarDescription, mustResolve, child);
1106                     schemaNamespace = currSchemaInfo.fTargetNamespace;
1107                 }
1108                 else {
1109                     fLastSchemaWasDuplicate = true;
1110                 }
1111             }
1112             else {
1113                 // no more possibility of schema references in well-formed
1114                 // schema...
1115                 break;
1116             }
1117 
1118             // If the schema is duplicate, we needn't call constructTrees() again.
1119             // To handle mutual <include>s
1120             XSDocumentInfo newSchemaInfo = null;
1121             if (fLastSchemaWasDuplicate) {
1122                 newSchemaInfo = newSchemaRoot == null ? null : (XSDocumentInfo)fDoc2XSDocumentMap.get(newSchemaRoot);
1123             }
1124             else {
1125                 newSchemaInfo = constructTrees(newSchemaRoot, schemaHint, fSchemaGrammarDescription, importCollision);
1126             }
1127 
1128             if (localName.equals(SchemaSymbols.ELT_REDEFINE) &&
1129                     newSchemaInfo != null) {
1130                 // must record which schema we're redefining so that we can
1131                 // rename the right things later!
1132                 if (fRedefine2XSDMap == null) fRedefine2XSDMap = new HashMap();
1133                 fRedefine2XSDMap.put(child, newSchemaInfo);
1134             }
1135             if (newSchemaRoot != null) {
1136                 if (newSchemaInfo != null)
1137                     dependencies.addElement(newSchemaInfo);
1138                 newSchemaRoot = null;
1139             }
1140         }
1141 
1142         fDependencyMap.put(currSchemaInfo, dependencies);
1143         return currSchemaInfo;
1144     } // end constructTrees
1145 
1146     private boolean isExistingGrammar(XSDDescription desc, boolean ignoreConflict) {
1147         SchemaGrammar sg = fGrammarBucket.getGrammar(desc.getTargetNamespace());
1148         if (sg == null) {
1149             return findGrammar(desc, ignoreConflict) != null;
1150         }
1151         else if (sg.isImmutable()) {
1152             return true;
1153         }
1154         else {
1155             try {
1156                 return sg.getDocumentLocations().contains(XMLEntityManager.expandSystemId(desc.getLiteralSystemId(), desc.getBaseSystemId(), false));
1157             }
1158             catch (MalformedURIException e) {
1159                 return false;
1160             }
1161         }
1162     }
1163 
1164     /**
1165      * Namespace growth
1166      *
1167      * Go through the import list of a given grammar and for each imported
1168      * grammar, check to see if the grammar bucket has a newer version.
1169      * If a new instance is found, we update the import list with the
1170      * newer version.
1171      */
1172     private void updateImportListFor(SchemaGrammar grammar) {
1173         Vector importedGrammars = grammar.getImportedGrammars();
1174         if (importedGrammars != null) {
1175             for (int i=0; i<importedGrammars.size(); i++) {
1176                 SchemaGrammar isg1 = (SchemaGrammar) importedGrammars.elementAt(i);
1177                 SchemaGrammar isg2 = fGrammarBucket.getGrammar(isg1.getTargetNamespace());
1178                 if (isg2 != null && isg1 != isg2) {
1179                     importedGrammars.set(i, isg2);
1180                 }
1181             }
1182         }
1183     }
1184 
1185     /**
1186      * Namespace growth
1187      *
1188      * Go throuth the grammar bucket, and for each grammar in the bucket
1189      * check the import list. If there exists a grammar in import list
1190      * that has the same namespace as newGrammar, but a different instance,
1191      * then update the import list and replace the old grammar instance with
1192      * the new one
1193      */
1194     private void updateImportListWith(SchemaGrammar newGrammar) {
1195         SchemaGrammar[] schemaGrammars = fGrammarBucket.getGrammars();
1196         for (int i = 0; i < schemaGrammars.length; ++i) {
1197             SchemaGrammar sg = schemaGrammars[i];
1198             if (sg != newGrammar) {
1199                 Vector importedGrammars = sg.getImportedGrammars();
1200                 if (importedGrammars != null) {
1201                     for (int j=0; j<importedGrammars.size(); j++) {
1202                         SchemaGrammar isg = (SchemaGrammar) importedGrammars.elementAt(j);
1203                         if (null2EmptyString(isg.getTargetNamespace()).equals(null2EmptyString(newGrammar.getTargetNamespace()))) {
1204                             if (isg != newGrammar) {
1205                                 importedGrammars.set(j, newGrammar);
1206                             }
1207                             break;
1208                         }
1209                     }
1210                 }
1211             }
1212         }
1213     }
1214 
1215     // This method builds registries for all globally-referenceable
1216     // names.  A registry will be built for each symbol space defined
1217     // by the spec.  It is also this method's job to rename redefined
1218     // components, and to record which components redefine others (so
1219     // that implicit redefinitions of groups and attributeGroups can be handled).
1220     protected void buildGlobalNameRegistries() {
1221 
1222         registryEmpty = false;
1223         // Starting with fRoot, we examine each child of the schema
1224         // element.  Skipping all imports and includes, we record the names
1225         // of all other global components (and children of <redefine>).  We
1226         // also put <redefine> names in a registry that we look through in
1227         // case something needs renaming.  Once we're done with a schema we
1228         // set its Document node to hidden so that we don't try to traverse
1229         // it again; then we look to its Dependency map entry.  We keep a
1230         // stack of schemas that we haven't yet finished processing; this
1231         // is a depth-first traversal.
1232 
1233         Stack schemasToProcess = new Stack();
1234         schemasToProcess.push(fRoot);
1235 
1236         while (!schemasToProcess.empty()) {
1237             XSDocumentInfo currSchemaDoc =
1238                 (XSDocumentInfo)schemasToProcess.pop();
1239             Element currDoc = currSchemaDoc.fSchemaElement;
1240             if(DOMUtil.isHidden(currDoc, fHiddenNodes)){
1241                 // must have processed this already!
1242                 continue;
1243             }
1244 
1245             Element currRoot = currDoc;
1246             // process this schema's global decls
1247             boolean dependenciesCanOccur = true;
1248             for (Element globalComp =
1249                 DOMUtil.getFirstChildElement(currRoot);
1250             globalComp != null;
1251             globalComp = DOMUtil.getNextSiblingElement(globalComp)) {
1252                 // this loop makes sure the <schema> element ordering is
1253                 // also valid.
1254                 if (DOMUtil.getLocalName(globalComp).equals(SchemaSymbols.ELT_ANNOTATION)) {
1255                     //skip it; traverse it later
1256                     continue;
1257                 }
1258                 else if (DOMUtil.getLocalName(globalComp).equals(SchemaSymbols.ELT_INCLUDE) ||
1259                         DOMUtil.getLocalName(globalComp).equals(SchemaSymbols.ELT_IMPORT)) {
1260                     if (!dependenciesCanOccur) {
1261                         reportSchemaError("s4s-elt-invalid-content.3", new Object [] {DOMUtil.getLocalName(globalComp)}, globalComp);
1262                     }
1263                     DOMUtil.setHidden(globalComp, fHiddenNodes);
1264                 }
1265                 else if (DOMUtil.getLocalName(globalComp).equals(SchemaSymbols.ELT_REDEFINE)) {
1266                     if (!dependenciesCanOccur) {
1267                         reportSchemaError("s4s-elt-invalid-content.3", new Object [] {DOMUtil.getLocalName(globalComp)}, globalComp);
1268                     }
1269                     for (Element redefineComp = DOMUtil.getFirstChildElement(globalComp);
1270                     redefineComp != null;
1271                     redefineComp = DOMUtil.getNextSiblingElement(redefineComp)) {
1272                         String lName = DOMUtil.getAttrValue(redefineComp, SchemaSymbols.ATT_NAME);
1273                         if (lName.length() == 0) // an error we'll catch later
1274                             continue;
1275                         String qName = currSchemaDoc.fTargetNamespace == null ?
1276                                 ","+lName:
1277                                     currSchemaDoc.fTargetNamespace +","+lName;
1278                         String componentType = DOMUtil.getLocalName(redefineComp);
1279                         if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
1280                             checkForDuplicateNames(qName, ATTRIBUTEGROUP_TYPE, fUnparsedAttributeGroupRegistry, fUnparsedAttributeGroupRegistrySub, redefineComp, currSchemaDoc);
1281                             // the check will have changed our name;
1282                             String targetLName = DOMUtil.getAttrValue(redefineComp, SchemaSymbols.ATT_NAME)+REDEF_IDENTIFIER;
1283                             // and all we need to do is error-check+rename our kkids:
1284                             renameRedefiningComponents(currSchemaDoc, redefineComp, SchemaSymbols.ELT_ATTRIBUTEGROUP,
1285                                     lName, targetLName);
1286                         }
1287                         else if ((componentType.equals(SchemaSymbols.ELT_COMPLEXTYPE)) ||
1288                                 (componentType.equals(SchemaSymbols.ELT_SIMPLETYPE))) {
1289                             checkForDuplicateNames(qName, TYPEDECL_TYPE, fUnparsedTypeRegistry, fUnparsedTypeRegistrySub, redefineComp, currSchemaDoc);
1290                             // the check will have changed our name;
1291                             String targetLName = DOMUtil.getAttrValue(redefineComp, SchemaSymbols.ATT_NAME) + REDEF_IDENTIFIER;
1292                             // and all we need to do is error-check+rename our kkids:
1293                             if (componentType.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
1294                                 renameRedefiningComponents(currSchemaDoc, redefineComp, SchemaSymbols.ELT_COMPLEXTYPE,
1295                                         lName, targetLName);
1296                             }
1297                             else { // must be simpleType
1298                                 renameRedefiningComponents(currSchemaDoc, redefineComp, SchemaSymbols.ELT_SIMPLETYPE,
1299                                         lName, targetLName);
1300                             }
1301                         }
1302                         else if (componentType.equals(SchemaSymbols.ELT_GROUP)) {
1303                             checkForDuplicateNames(qName, GROUP_TYPE, fUnparsedGroupRegistry, fUnparsedGroupRegistrySub, redefineComp, currSchemaDoc);
1304                             // the check will have changed our name;
1305                             String targetLName = DOMUtil.getAttrValue(redefineComp, SchemaSymbols.ATT_NAME)+REDEF_IDENTIFIER;
1306                             // and all we need to do is error-check+rename our kids:
1307                             renameRedefiningComponents(currSchemaDoc, redefineComp, SchemaSymbols.ELT_GROUP,
1308                                     lName, targetLName);
1309                         }
1310                     } // end march through <redefine> children
1311                     // and now set as traversed
1312                     //DOMUtil.setHidden(globalComp);
1313                 }
1314                 else {
1315                     dependenciesCanOccur = false;
1316                     String lName = DOMUtil.getAttrValue(globalComp, SchemaSymbols.ATT_NAME);
1317                     if (lName.length() == 0) // an error we'll catch later
1318                         continue;
1319                     String qName = currSchemaDoc.fTargetNamespace == null?
1320                             ","+lName:
1321                                 currSchemaDoc.fTargetNamespace +","+lName;
1322                     String componentType = DOMUtil.getLocalName(globalComp);
1323 
1324                     if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
1325                         checkForDuplicateNames(qName, ATTRIBUTE_TYPE, fUnparsedAttributeRegistry, fUnparsedAttributeRegistrySub, globalComp, currSchemaDoc);
1326                     }
1327                     else if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
1328                         checkForDuplicateNames(qName, ATTRIBUTEGROUP_TYPE, fUnparsedAttributeGroupRegistry, fUnparsedAttributeGroupRegistrySub, globalComp, currSchemaDoc);
1329                     }
1330                     else if ((componentType.equals(SchemaSymbols.ELT_COMPLEXTYPE)) ||
1331                             (componentType.equals(SchemaSymbols.ELT_SIMPLETYPE))) {
1332                         checkForDuplicateNames(qName, TYPEDECL_TYPE, fUnparsedTypeRegistry, fUnparsedTypeRegistrySub, globalComp, currSchemaDoc);
1333                     }
1334                     else if (componentType.equals(SchemaSymbols.ELT_ELEMENT)) {
1335                         checkForDuplicateNames(qName, ELEMENT_TYPE, fUnparsedElementRegistry, fUnparsedElementRegistrySub, globalComp, currSchemaDoc);
1336                     }
1337                     else if (componentType.equals(SchemaSymbols.ELT_GROUP)) {
1338                         checkForDuplicateNames(qName, GROUP_TYPE, fUnparsedGroupRegistry, fUnparsedGroupRegistrySub, globalComp, currSchemaDoc);
1339                     }
1340                     else if (componentType.equals(SchemaSymbols.ELT_NOTATION)) {
1341                         checkForDuplicateNames(qName, NOTATION_TYPE, fUnparsedNotationRegistry, fUnparsedNotationRegistrySub, globalComp, currSchemaDoc);
1342                     }
1343                 }
1344             } // end for
1345 
1346             // now we're done with this one!
1347             DOMUtil.setHidden(currDoc, fHiddenNodes);
1348             // now add the schemas this guy depends on
1349             Vector<XSDocumentInfo> currSchemaDepends = fDependencyMap.get(currSchemaDoc);
1350             for (int i = 0; i < currSchemaDepends.size(); i++) {
1351                 schemasToProcess.push(currSchemaDepends.elementAt(i));
1352             }
1353         } // while
1354 
1355     } // end buildGlobalNameRegistries
1356 
1357     // Beginning at the first schema processing was requested for
1358     // (fRoot), this method
1359     // examines each child (global schema information item) of each
1360     // schema document (and of each <redefine> element)
1361     // corresponding to an XSDocumentInfo object.  If the
1362     // readOnly field on that node has not been set, it calls an
1363     // appropriate traverser to traverse it.  Once all global decls in
1364     // an XSDocumentInfo object have been traversed, it marks that object
1365     // as traversed (or hidden) in order to avoid infinite loops.  It completes
1366     // when it has visited all XSDocumentInfo objects in the
1367     // DependencyMap and marked them as traversed.
1368     protected void traverseSchemas(ArrayList annotationInfo) {
1369         // the process here is very similar to that in
1370         // buildGlobalRegistries, except we can't set our schemas as
1371         // hidden for a second time; so make them all visible again
1372         // first!
1373         setSchemasVisible(fRoot);
1374         Stack schemasToProcess = new Stack();
1375         schemasToProcess.push(fRoot);
1376         while (!schemasToProcess.empty()) {
1377             XSDocumentInfo currSchemaDoc =
1378                 (XSDocumentInfo)schemasToProcess.pop();
1379             Element currDoc = currSchemaDoc.fSchemaElement;
1380 
1381             SchemaGrammar currSG = fGrammarBucket.getGrammar(currSchemaDoc.fTargetNamespace);
1382 
1383             if(DOMUtil.isHidden(currDoc, fHiddenNodes)) {
1384                 // must have processed this already!
1385                 continue;
1386             }
1387             Element currRoot = currDoc;
1388             boolean sawAnnotation = false;
1389             // traverse this schema's global decls
1390             for (Element globalComp =
1391                 DOMUtil.getFirstVisibleChildElement(currRoot, fHiddenNodes);
1392             globalComp != null;
1393             globalComp = DOMUtil.getNextVisibleSiblingElement(globalComp, fHiddenNodes)) {
1394                 DOMUtil.setHidden(globalComp, fHiddenNodes);
1395                 String componentType = DOMUtil.getLocalName(globalComp);
1396                 // includes and imports will not show up here!
1397                 if (DOMUtil.getLocalName(globalComp).equals(SchemaSymbols.ELT_REDEFINE)) {
1398                     // use the namespace decls for the redefine, instead of for the parent <schema>
1399                     currSchemaDoc.backupNSSupport((fRedefine2NSSupport!=null)?(SchemaNamespaceSupport)fRedefine2NSSupport.get(globalComp):null);
1400                     for (Element redefinedComp = DOMUtil.getFirstVisibleChildElement(globalComp, fHiddenNodes);
1401                     redefinedComp != null;
1402                     redefinedComp = DOMUtil.getNextVisibleSiblingElement(redefinedComp, fHiddenNodes)) {
1403                         String redefinedComponentType = DOMUtil.getLocalName(redefinedComp);
1404                         DOMUtil.setHidden(redefinedComp, fHiddenNodes);
1405                         if (redefinedComponentType.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
1406                             fAttributeGroupTraverser.traverseGlobal(redefinedComp, currSchemaDoc, currSG);
1407                         }
1408                         else if (redefinedComponentType.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
1409                             fComplexTypeTraverser.traverseGlobal(redefinedComp, currSchemaDoc, currSG);
1410                         }
1411                         else if (redefinedComponentType.equals(SchemaSymbols.ELT_GROUP)) {
1412                             fGroupTraverser.traverseGlobal(redefinedComp, currSchemaDoc, currSG);
1413                         }
1414                         else if (redefinedComponentType.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
1415                             fSimpleTypeTraverser.traverseGlobal(redefinedComp, currSchemaDoc, currSG);
1416                         }
1417                         // annotations will have been processed already; this is now
1418                         // unnecessary
1419                         //else if (redefinedComponentType.equals(SchemaSymbols.ELT_ANNOTATION)) {
1420                         //    fElementTraverser.traverseAnnotationDecl(redefinedComp, null, true, currSchemaDoc);
1421                         //}
1422                         else {
1423                             reportSchemaError("s4s-elt-must-match.1", new Object [] {DOMUtil.getLocalName(globalComp), "(annotation | (simpleType | complexType | group | attributeGroup))*", redefinedComponentType}, redefinedComp);
1424                         }
1425                     } // end march through <redefine> children
1426                     currSchemaDoc.restoreNSSupport();
1427                 }
1428                 else if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
1429                     fAttributeTraverser.traverseGlobal(globalComp, currSchemaDoc, currSG);
1430                 }
1431                 else if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
1432                     fAttributeGroupTraverser.traverseGlobal(globalComp, currSchemaDoc, currSG);
1433                 }
1434                 else if (componentType.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
1435                     fComplexTypeTraverser.traverseGlobal(globalComp, currSchemaDoc, currSG);
1436                 }
1437                 else if (componentType.equals(SchemaSymbols.ELT_ELEMENT)) {
1438                     fElementTraverser.traverseGlobal(globalComp, currSchemaDoc, currSG);
1439                 }
1440                 else if (componentType.equals(SchemaSymbols.ELT_GROUP)) {
1441                     fGroupTraverser.traverseGlobal(globalComp, currSchemaDoc, currSG);
1442                 }
1443                 else if (componentType.equals(SchemaSymbols.ELT_NOTATION)) {
1444                     fNotationTraverser.traverse(globalComp, currSchemaDoc, currSG);
1445                 }
1446                 else if (componentType.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
1447                     fSimpleTypeTraverser.traverseGlobal(globalComp, currSchemaDoc, currSG);
1448                 }
1449                 else if (componentType.equals(SchemaSymbols.ELT_ANNOTATION)) {
1450                     currSG.addAnnotation(fElementTraverser.traverseAnnotationDecl(globalComp, currSchemaDoc.getSchemaAttrs(), true, currSchemaDoc));
1451                     sawAnnotation = true;
1452                 }
1453                 else {
1454                     reportSchemaError("s4s-elt-invalid-content.1", new Object [] {SchemaSymbols.ELT_SCHEMA, DOMUtil.getLocalName(globalComp)}, globalComp);
1455                 }
1456             } // end for
1457 
1458             if (!sawAnnotation) {
1459                 String text = DOMUtil.getSyntheticAnnotation(currRoot);
1460                 if (text != null) {
1461                     currSG.addAnnotation(fElementTraverser.traverseSyntheticAnnotation(currRoot, text, currSchemaDoc.getSchemaAttrs(), true, currSchemaDoc));
1462                 }
1463             }
1464 
1465             /** Collect annotation information for validation. **/
1466             if (annotationInfo != null) {
1467                 XSAnnotationInfo info = currSchemaDoc.getAnnotations();
1468                 /** Only add annotations to the list if there were any in this document. **/
1469                 if (info != null) {
1470                     annotationInfo.add(doc2SystemId(currDoc));
1471                     annotationInfo.add(info);
1472                 }
1473             }
1474             // now we're done with this one!
1475             currSchemaDoc.returnSchemaAttrs();
1476             DOMUtil.setHidden(currDoc, fHiddenNodes);
1477 
1478             // now add the schemas this guy depends on
1479             Vector<XSDocumentInfo> currSchemaDepends = fDependencyMap.get(currSchemaDoc);
1480             for (int i = 0; i < currSchemaDepends.size(); i++) {
1481                 schemasToProcess.push(currSchemaDepends.elementAt(i));
1482             }
1483         } // while
1484     } // end traverseSchemas
1485 
1486     // store whether we have reported an error about that no grammar
1487     // is found for the given namespace uri
1488     private Vector fReportedTNS = null;
1489     // check whether we need to report an error against the given uri.
1490     // if we have reported an error, then we don't need to report again;
1491     // otherwise we reported the error, and remember this fact.
1492     private final boolean needReportTNSError(String uri) {
1493         if (fReportedTNS == null)
1494             fReportedTNS = new Vector();
1495         else if (fReportedTNS.contains(uri))
1496             return false;
1497         fReportedTNS.addElement(uri);
1498         return true;
1499     }
1500 
1501     private static final String[] COMP_TYPE = {
1502             null,               // index 0
1503             "attribute declaration",
1504             "attribute group",
1505             "element declaration",
1506             "group",
1507             "identity constraint",
1508             "notation",
1509             "type definition",
1510     };
1511 
1512     private static final String[] CIRCULAR_CODES = {
1513             "Internal-Error",
1514             "Internal-Error",
1515             "src-attribute_group.3",
1516             "e-props-correct.6",
1517             "mg-props-correct.2",
1518             "Internal-Error",
1519             "Internal-Error",
1520             "st-props-correct.2",       //or ct-props-correct.3
1521     };
1522 
1523     // add a global attribute decl from a current schema load (only if no existing decl is found)
1524     void addGlobalAttributeDecl(XSAttributeDecl decl) {
1525         final String namespace = decl.getNamespace();
1526         final String declKey = (namespace == null || namespace.length() == 0)
1527             ? "," + decl.getName() : namespace + "," + decl.getName();
1528 
1529         if (fGlobalAttrDecls.get(declKey) == null) {
1530             fGlobalAttrDecls.put(declKey, decl);
1531         }
1532     }
1533 
1534     // add a global attribute group decl from a current schema load (only if no existing decl is found)
1535     void addGlobalAttributeGroupDecl(XSAttributeGroupDecl decl) {
1536         final String namespace = decl.getNamespace();
1537         final String declKey = (namespace == null || namespace.length() == 0)
1538             ? "," + decl.getName() : namespace + "," + decl.getName();
1539 
1540         if (fGlobalAttrGrpDecls.get(declKey) == null) {
1541             fGlobalAttrGrpDecls.put(declKey, decl);
1542         }
1543     }
1544 
1545     // add a global element decl from a current schema load (only if no existing decl is found)
1546     void addGlobalElementDecl(XSElementDecl decl) {
1547         final String namespace = decl.getNamespace();
1548         final String declKey = (namespace == null || namespace.length() == 0)
1549             ? "," + decl.getName() : namespace + "," + decl.getName();
1550 
1551         if (fGlobalElemDecls.get(declKey) == null) {
1552             fGlobalElemDecls.put(declKey, decl);
1553         }
1554     }
1555 
1556     // add a global group decl from a current schema load (only if no existing decl is found)
1557     void addGlobalGroupDecl(XSGroupDecl decl) {
1558         final String namespace = decl.getNamespace();
1559         final String declKey = (namespace == null || namespace.length() == 0)
1560             ? "," + decl.getName() : namespace + "," + decl.getName();
1561 
1562         if (fGlobalGroupDecls.get(declKey) == null) {
1563             fGlobalGroupDecls.put(declKey, decl);
1564         }
1565     }
1566 
1567     // add a global notation decl from a current schema load (only if no existing decl is found)
1568     void addGlobalNotationDecl(XSNotationDecl decl) {
1569         final String namespace = decl.getNamespace();
1570         final String declKey = (namespace == null || namespace.length() == 0)
1571             ? "," + decl.getName() : namespace + "," + decl.getName();
1572 
1573         if (fGlobalNotationDecls.get(declKey) == null) {
1574             fGlobalNotationDecls.put(declKey, decl);
1575         }
1576     }
1577 
1578     // add a global type decl from a current schema load (only if no existing decl is found)
1579     void addGlobalTypeDecl(XSTypeDefinition decl) {
1580         final String namespace = decl.getNamespace();
1581         final String declKey = (namespace == null || namespace.length() == 0)
1582             ? "," + decl.getName() : namespace + "," + decl.getName();
1583 
1584         if (fGlobalTypeDecls.get(declKey) == null) {
1585             fGlobalTypeDecls.put(declKey, decl);
1586         }
1587     }
1588 
1589     // add a identity constraint decl from a current schema load (only if no existing decl is found)
1590     void addIDConstraintDecl(IdentityConstraint decl) {
1591         final String namespace = decl.getNamespace();
1592         final String declKey = (namespace == null || namespace.length() == 0)
1593             ? "," + decl.getIdentityConstraintName() : namespace + "," + decl.getIdentityConstraintName();
1594 
1595         if (fGlobalIDConstraintDecls.get(declKey) == null) {
1596             fGlobalIDConstraintDecls.put(declKey, decl);
1597         }
1598     }
1599 
1600     private XSAttributeDecl getGlobalAttributeDecl(String declKey) {
1601         return (XSAttributeDecl)fGlobalAttrDecls.get(declKey);
1602     }
1603 
1604     private XSAttributeGroupDecl getGlobalAttributeGroupDecl(String declKey) {
1605         return (XSAttributeGroupDecl)fGlobalAttrGrpDecls.get(declKey);
1606     }
1607 
1608     private XSElementDecl getGlobalElementDecl(String declKey) {
1609         return (XSElementDecl)fGlobalElemDecls.get(declKey);
1610     }
1611 
1612     private XSGroupDecl getGlobalGroupDecl(String declKey) {
1613         return (XSGroupDecl)fGlobalGroupDecls.get(declKey);
1614     }
1615 
1616     private XSNotationDecl getGlobalNotationDecl(String declKey) {
1617         return (XSNotationDecl)fGlobalNotationDecls.get(declKey);
1618     }
1619 
1620     private XSTypeDefinition getGlobalTypeDecl(String declKey) {
1621         return (XSTypeDefinition)fGlobalTypeDecls.get(declKey);
1622     }
1623 
1624     private IdentityConstraint getIDConstraintDecl(String declKey) {
1625         return (IdentityConstraint)fGlobalIDConstraintDecls.get(declKey);
1626     }
1627 
1628     // since it is forbidden for traversers to talk to each other
1629     // directly (except wen a traverser encounters a local declaration),
1630     // this provides a generic means for a traverser to call
1631     // for the traversal of some declaration.  An XSDocumentInfo is
1632     // required because the XSDocumentInfo that the traverser is traversing
1633     // may bear no relation to the one the handler is operating on.
1634     // This method will:
1635     // 1.  See if a global definition matching declToTraverse exists;
1636     // 2. if so, determine if there is a path from currSchema to the
1637     // schema document where declToTraverse lives (i.e., do a lookup
1638     // in DependencyMap);
1639     // 3. depending on declType (which will be relevant to step 1 as
1640     // well), call the appropriate traverser with the appropriate
1641     // XSDocumentInfo object.
1642     // This method returns whatever the traverser it called returned;
1643     // this will be an Object of some kind
1644     // that lives in the Grammar.
1645     protected Object getGlobalDecl(XSDocumentInfo currSchema,
1646             int declType,
1647             QName declToTraverse,
1648             Element elmNode) {
1649 
1650         if (DEBUG_NODE_POOL) {
1651             System.out.println("TRAVERSE_GL: "+declToTraverse.toString());
1652         }
1653 
1654         // from the schema spec, all built-in types are present in all schemas,
1655         // so if the requested component is a type, and could be found in the
1656         // default schema grammar, we should return that type.
1657         // otherwise (since we would support user-defined schema grammar) we'll
1658         // use the normal way to get the decl
1659         if (declToTraverse.uri != null &&
1660                 declToTraverse.uri == SchemaSymbols.URI_SCHEMAFORSCHEMA) {
1661             if (declType == TYPEDECL_TYPE) {
1662                 Object retObj = SchemaGrammar.SG_SchemaNS.getGlobalTypeDecl(declToTraverse.localpart);
1663                 if (retObj != null)
1664                     return retObj;
1665             }
1666         }
1667 
1668         // now check whether this document can access the requsted namespace
1669         if (!currSchema.isAllowedNS(declToTraverse.uri)) {
1670             // cannot get to this schema from the one containing the requesting decl
1671             if (currSchema.needReportTNSError(declToTraverse.uri)) {
1672                 String code = declToTraverse.uri == null ? "src-resolve.4.1" : "src-resolve.4.2";
1673                 reportSchemaError(code, new Object[]{fDoc2SystemId.get(currSchema.fSchemaElement), declToTraverse.uri, declToTraverse.rawname}, elmNode);
1674             }
1675             // Recover and continue to look for the component.
1676             // return null;
1677         }
1678 
1679         // check whether there is grammar for the requested namespace
1680         SchemaGrammar sGrammar = fGrammarBucket.getGrammar(declToTraverse.uri);
1681         if (sGrammar == null) {
1682             if (needReportTNSError(declToTraverse.uri))
1683                 reportSchemaError("src-resolve", new Object[]{declToTraverse.rawname, COMP_TYPE[declType]}, elmNode);
1684             return null;
1685         }
1686 
1687         // if there is such grammar, check whether the requested component is in the grammar
1688         Object retObj = getGlobalDeclFromGrammar(sGrammar, declType, declToTraverse.localpart);
1689         String declKey = declToTraverse.uri == null? ","+declToTraverse.localpart:
1690             declToTraverse.uri+","+declToTraverse.localpart;
1691 
1692         // if the component is parsed, return it
1693         if (!fTolerateDuplicates) {
1694             if (retObj != null) {
1695                 return retObj;
1696             }
1697         }
1698         else {
1699             Object retObj2 = getGlobalDecl(declKey, declType);
1700             if (retObj2 != null) {
1701                 return retObj2;
1702             }
1703         }
1704 
1705         XSDocumentInfo schemaWithDecl = null;
1706         Element decl = null;
1707         XSDocumentInfo declDoc = null;
1708 
1709         // the component is not parsed, try to find a DOM element for it
1710         switch (declType) {
1711         case ATTRIBUTE_TYPE :
1712             decl = getElementFromMap(fUnparsedAttributeRegistry, declKey);
1713             declDoc = getDocInfoFromMap(fUnparsedAttributeRegistrySub, declKey);
1714             break;
1715         case ATTRIBUTEGROUP_TYPE :
1716             decl = getElementFromMap(fUnparsedAttributeGroupRegistry, declKey);
1717             declDoc = getDocInfoFromMap(fUnparsedAttributeGroupRegistrySub, declKey);
1718             break;
1719         case ELEMENT_TYPE :
1720             decl = getElementFromMap(fUnparsedElementRegistry, declKey);
1721             declDoc = getDocInfoFromMap(fUnparsedElementRegistrySub, declKey);
1722             break;
1723         case GROUP_TYPE :
1724             decl = getElementFromMap(fUnparsedGroupRegistry, declKey);
1725             declDoc = getDocInfoFromMap(fUnparsedGroupRegistrySub, declKey);
1726             break;
1727         case IDENTITYCONSTRAINT_TYPE :
1728             decl = getElementFromMap(fUnparsedIdentityConstraintRegistry, declKey);
1729             declDoc = getDocInfoFromMap(fUnparsedIdentityConstraintRegistrySub, declKey);
1730             break;
1731         case NOTATION_TYPE :
1732             decl = getElementFromMap(fUnparsedNotationRegistry, declKey);
1733             declDoc = getDocInfoFromMap(fUnparsedNotationRegistrySub, declKey);
1734             break;
1735         case TYPEDECL_TYPE :
1736             decl = getElementFromMap(fUnparsedTypeRegistry, declKey);
1737             declDoc = getDocInfoFromMap(fUnparsedTypeRegistrySub, declKey);
1738             break;
1739         default:
1740             reportSchemaError("Internal-Error", new Object [] {"XSDHandler asked to locate component of type " + declType + "; it does not recognize this type!"}, elmNode);
1741         }
1742 
1743         // no DOM element found, so the component can't be located
1744         if (decl == null) {
1745             if (retObj == null) {
1746                 reportSchemaError("src-resolve", new Object[]{declToTraverse.rawname, COMP_TYPE[declType]}, elmNode);
1747             }
1748             return retObj;
1749         }
1750 
1751         // get the schema doc containing the component to be parsed
1752         // it should always return non-null value, but since null-checking
1753         // comes for free, let's be safe and check again
1754         schemaWithDecl = findXSDocumentForDecl(currSchema, decl, declDoc);
1755         if (schemaWithDecl == null) {
1756             // cannot get to this schema from the one containing the requesting decl
1757             if (retObj == null) {
1758                 String code = declToTraverse.uri == null ? "src-resolve.4.1" : "src-resolve.4.2";
1759                 reportSchemaError(code, new Object[]{fDoc2SystemId.get(currSchema.fSchemaElement), declToTraverse.uri, declToTraverse.rawname}, elmNode);
1760             }
1761             return retObj;
1762         }
1763 
1764         // a component is hidden, meaning either it's traversed, or being traversed.
1765         // but we didn't find it in the grammar, so it's the latter case, and
1766         // a circular reference. error!
1767         if (DOMUtil.isHidden(decl, fHiddenNodes)) {
1768             if (retObj == null) {
1769                 String code = CIRCULAR_CODES[declType];
1770                 if (declType == TYPEDECL_TYPE) {
1771                     if (SchemaSymbols.ELT_COMPLEXTYPE.equals(DOMUtil.getLocalName(decl))) {
1772                         code = "ct-props-correct.3";
1773                     }
1774                 }
1775                 // decl must not be null if we're here...
1776                 reportSchemaError(code, new Object [] {declToTraverse.prefix+":"+declToTraverse.localpart}, elmNode);
1777             }
1778             return retObj;
1779         }
1780 
1781         return traverseGlobalDecl(declType, decl, schemaWithDecl, sGrammar);
1782     } // getGlobalDecl(XSDocumentInfo, int, QName):  Object
1783 
1784     // If we are tolerating duplicate declarations and allowing namespace growth
1785     // use the declaration from the current schema load (if it exists)
1786     protected Object getGlobalDecl(String declKey, int declType) {
1787         Object retObj = null;
1788 
1789         switch (declType) {
1790         case ATTRIBUTE_TYPE :
1791             retObj = getGlobalAttributeDecl(declKey);
1792             break;
1793         case ATTRIBUTEGROUP_TYPE :
1794             retObj = getGlobalAttributeGroupDecl(declKey);
1795             break;
1796         case ELEMENT_TYPE :
1797             retObj = getGlobalElementDecl(declKey);
1798             break;
1799         case GROUP_TYPE :
1800             retObj = getGlobalGroupDecl(declKey);
1801             break;
1802         case IDENTITYCONSTRAINT_TYPE :
1803             retObj = getIDConstraintDecl(declKey);
1804             break;
1805         case NOTATION_TYPE :
1806             retObj = getGlobalNotationDecl(declKey);
1807             break;
1808         case TYPEDECL_TYPE :
1809             retObj = getGlobalTypeDecl(declKey);
1810             break;
1811         }
1812 
1813         return retObj;
1814     }
1815 
1816     protected Object getGlobalDeclFromGrammar(SchemaGrammar sGrammar, int declType, String localpart) {
1817         Object retObj = null;
1818 
1819         switch (declType) {
1820         case ATTRIBUTE_TYPE :
1821             retObj = sGrammar.getGlobalAttributeDecl(localpart);
1822             break;
1823         case ATTRIBUTEGROUP_TYPE :
1824             retObj = sGrammar.getGlobalAttributeGroupDecl(localpart);
1825             break;
1826         case ELEMENT_TYPE :
1827             retObj = sGrammar.getGlobalElementDecl(localpart);
1828             break;
1829         case GROUP_TYPE :
1830             retObj = sGrammar.getGlobalGroupDecl(localpart);
1831             break;
1832         case IDENTITYCONSTRAINT_TYPE :
1833             retObj = sGrammar.getIDConstraintDecl(localpart);
1834             break;
1835         case NOTATION_TYPE :
1836             retObj = sGrammar.getGlobalNotationDecl(localpart);
1837             break;
1838         case TYPEDECL_TYPE :
1839             retObj = sGrammar.getGlobalTypeDecl(localpart);
1840             break;
1841         }
1842 
1843         return retObj;
1844     }
1845 
1846     protected Object getGlobalDeclFromGrammar(SchemaGrammar sGrammar, int declType, String localpart, String schemaLoc) {
1847         Object retObj = null;
1848 
1849         switch (declType) {
1850         case ATTRIBUTE_TYPE :
1851             retObj = sGrammar.getGlobalAttributeDecl(localpart, schemaLoc);
1852             break;
1853         case ATTRIBUTEGROUP_TYPE :
1854             retObj = sGrammar.getGlobalAttributeGroupDecl(localpart, schemaLoc);
1855             break;
1856         case ELEMENT_TYPE :
1857             retObj = sGrammar.getGlobalElementDecl(localpart, schemaLoc);
1858             break;
1859         case GROUP_TYPE :
1860             retObj = sGrammar.getGlobalGroupDecl(localpart, schemaLoc);
1861             break;
1862         case IDENTITYCONSTRAINT_TYPE :
1863             retObj = sGrammar.getIDConstraintDecl(localpart, schemaLoc);
1864             break;
1865         case NOTATION_TYPE :
1866             retObj = sGrammar.getGlobalNotationDecl(localpart, schemaLoc);
1867             break;
1868         case TYPEDECL_TYPE :
1869             retObj = sGrammar.getGlobalTypeDecl(localpart, schemaLoc);
1870             break;
1871         }
1872 
1873         return retObj;
1874     }
1875 
1876     protected Object traverseGlobalDecl(int declType, Element decl, XSDocumentInfo schemaDoc, SchemaGrammar grammar) {
1877         Object retObj = null;
1878 
1879         DOMUtil.setHidden(decl, fHiddenNodes);
1880         SchemaNamespaceSupport nsSupport = null;
1881         // if the parent is <redefine> use the namespace delcs for it.
1882         Element parent = DOMUtil.getParent(decl);
1883         if (DOMUtil.getLocalName(parent).equals(SchemaSymbols.ELT_REDEFINE))
1884             nsSupport = (fRedefine2NSSupport!=null)?(SchemaNamespaceSupport)fRedefine2NSSupport.get(parent):null;
1885         // back up the current SchemaNamespaceSupport, because we need to provide
1886         // a fresh one to the traverseGlobal methods.
1887         schemaDoc.backupNSSupport(nsSupport);
1888 
1889         // traverse the referenced global component
1890         switch (declType) {
1891         case TYPEDECL_TYPE :
1892             if (DOMUtil.getLocalName(decl).equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
1893                 retObj = fComplexTypeTraverser.traverseGlobal(decl, schemaDoc, grammar);
1894             }
1895             else {
1896                 retObj = fSimpleTypeTraverser.traverseGlobal(decl, schemaDoc, grammar);
1897             }
1898             break;
1899         case ATTRIBUTE_TYPE :
1900             retObj = fAttributeTraverser.traverseGlobal(decl, schemaDoc, grammar);
1901             break;
1902         case ELEMENT_TYPE :
1903             retObj = fElementTraverser.traverseGlobal(decl, schemaDoc, grammar);
1904             break;
1905         case ATTRIBUTEGROUP_TYPE :
1906             retObj = fAttributeGroupTraverser.traverseGlobal(decl, schemaDoc, grammar);
1907             break;
1908         case GROUP_TYPE :
1909             retObj = fGroupTraverser.traverseGlobal(decl, schemaDoc, grammar);
1910             break;
1911         case NOTATION_TYPE :
1912             retObj = fNotationTraverser.traverse(decl, schemaDoc, grammar);
1913             break;
1914         case IDENTITYCONSTRAINT_TYPE :
1915             // identity constraints should have been parsed already...
1916             // we should never get here
1917             break;
1918         }
1919 
1920         // restore the previous SchemaNamespaceSupport, so that the caller can get
1921         // proper namespace binding.
1922         schemaDoc.restoreNSSupport();
1923 
1924         return retObj;
1925     }
1926 
1927     public String schemaDocument2SystemId(XSDocumentInfo schemaDoc) {
1928         return fDoc2SystemId.get(schemaDoc.fSchemaElement);
1929     }
1930 
1931     // This method determines whether there is a group
1932     // (attributeGroup) which the given one has redefined by
1933     // restriction.  If so, it returns it; else it returns null.
1934     // @param type:  whether what's been redefined is an
1935     // attributeGroup or a group;
1936     // @param name:  the QName of the component doing the redefining.
1937     // @param currSchema:  schema doc in which the redefining component lives.
1938     // @return:  Object representing decl redefined if present, null
1939     // otherwise.
1940     Object getGrpOrAttrGrpRedefinedByRestriction(int type, QName name, XSDocumentInfo currSchema, Element elmNode) {
1941         String realName = name.uri != null?name.uri+","+name.localpart:
1942             ","+name.localpart;
1943         String nameToFind = null;
1944         switch (type) {
1945         case ATTRIBUTEGROUP_TYPE:
1946             nameToFind = (String)fRedefinedRestrictedAttributeGroupRegistry.get(realName);
1947             break;
1948         case GROUP_TYPE:
1949             nameToFind = (String)fRedefinedRestrictedGroupRegistry.get(realName);
1950             break;
1951         default:
1952             return null;
1953         }
1954         if (nameToFind == null) return null;
1955         int commaPos = nameToFind.indexOf(",");
1956         QName qNameToFind = new QName(XMLSymbols.EMPTY_STRING, nameToFind.substring(commaPos+1),
1957                 nameToFind.substring(commaPos), (commaPos == 0)? null : nameToFind.substring(0, commaPos));
1958         Object retObj = getGlobalDecl(currSchema, type, qNameToFind, elmNode);
1959         if(retObj == null) {
1960             switch (type) {
1961             case ATTRIBUTEGROUP_TYPE:
1962                 reportSchemaError("src-redefine.7.2.1", new Object []{name.localpart}, elmNode);
1963                 break;
1964             case GROUP_TYPE:
1965                 reportSchemaError("src-redefine.6.2.1", new Object []{name.localpart}, elmNode);
1966                 break;
1967             }
1968             return null;
1969         }
1970         return retObj;
1971     } // getGrpOrAttrGrpRedefinedByRestriction(int, QName, XSDocumentInfo):  Object
1972 
1973     // Since ID constraints can occur in local elements, unless we
1974     // wish to completely traverse all our DOM trees looking for ID
1975     // constraints while we're building our global name registries,
1976     // which seems terribly inefficient, we need to resolve keyrefs
1977     // after all parsing is complete.  This we can simply do by running through
1978     // fIdentityConstraintRegistry and calling traverseKeyRef on all
1979     // of the KeyRef nodes.  This unfortunately removes this knowledge
1980     // from the elementTraverser class (which must ignore keyrefs),
1981     // but there seems to be no efficient way around this...
1982     protected void resolveKeyRefs() {
1983         for (int i=0; i<fKeyrefStackPos; i++) {
1984             XSDocumentInfo keyrefSchemaDoc = fKeyrefsMapXSDocumentInfo[i];
1985             keyrefSchemaDoc.fNamespaceSupport.makeGlobal();
1986             keyrefSchemaDoc.fNamespaceSupport.setEffectiveContext( fKeyrefNamespaceContext[i] );
1987             SchemaGrammar keyrefGrammar = fGrammarBucket.getGrammar(keyrefSchemaDoc.fTargetNamespace);
1988             // need to set <keyref> to hidden before traversing it,
1989             // because it has global scope
1990                 DOMUtil.setHidden(fKeyrefs[i], fHiddenNodes);
1991             fKeyrefTraverser.traverse(fKeyrefs[i], fKeyrefElems[i], keyrefSchemaDoc, keyrefGrammar);
1992         }
1993     } // end resolveKeyRefs
1994 
1995     // an accessor method.  Just makes sure callers
1996     // who want the Identity constraint registry vaguely know what they're about.
1997     protected Map getIDRegistry() {
1998         return fUnparsedIdentityConstraintRegistry;
1999     }
2000     // an accessor method.
2001     protected Map getIDRegistry_sub() {
2002         return fUnparsedIdentityConstraintRegistrySub;
2003     }
2004 
2005 
2006 
2007     // This method squirrels away <keyref> declarations--along with the element
2008     // decls and namespace bindings they might find handy.
2009     protected void storeKeyRef (Element keyrefToStore, XSDocumentInfo schemaDoc,
2010             XSElementDecl currElemDecl) {
2011         String keyrefName = DOMUtil.getAttrValue(keyrefToStore, SchemaSymbols.ATT_NAME);
2012         if (keyrefName.length() != 0) {
2013             String keyrefQName = schemaDoc.fTargetNamespace == null?
2014                     "," + keyrefName: schemaDoc.fTargetNamespace+","+keyrefName;
2015             checkForDuplicateNames(keyrefQName, IDENTITYCONSTRAINT_TYPE, fUnparsedIdentityConstraintRegistry, fUnparsedIdentityConstraintRegistrySub, keyrefToStore, schemaDoc);
2016         }
2017         // now set up all the registries we'll need...
2018 
2019         // check array sizes
2020         if (fKeyrefStackPos == fKeyrefs.length) {
2021             Element [] elemArray = new Element [fKeyrefStackPos + INC_KEYREF_STACK_AMOUNT];
2022             System.arraycopy(fKeyrefs, 0, elemArray, 0, fKeyrefStackPos);
2023             fKeyrefs = elemArray;
2024             XSElementDecl [] declArray = new XSElementDecl [fKeyrefStackPos + INC_KEYREF_STACK_AMOUNT];
2025             System.arraycopy(fKeyrefElems, 0, declArray, 0, fKeyrefStackPos);
2026             fKeyrefElems = declArray;
2027             String[][] stringArray = new String [fKeyrefStackPos + INC_KEYREF_STACK_AMOUNT][];
2028             System.arraycopy(fKeyrefNamespaceContext, 0, stringArray, 0, fKeyrefStackPos);
2029             fKeyrefNamespaceContext = stringArray;
2030 
2031             XSDocumentInfo [] xsDocumentInfo = new XSDocumentInfo [fKeyrefStackPos + INC_KEYREF_STACK_AMOUNT];
2032             System.arraycopy(fKeyrefsMapXSDocumentInfo, 0, xsDocumentInfo, 0, fKeyrefStackPos);
2033             fKeyrefsMapXSDocumentInfo = xsDocumentInfo;
2034 
2035         }
2036         fKeyrefs[fKeyrefStackPos] = keyrefToStore;
2037         fKeyrefElems[fKeyrefStackPos] = currElemDecl;
2038         fKeyrefNamespaceContext[fKeyrefStackPos] = schemaDoc.fNamespaceSupport.getEffectiveLocalContext();
2039 
2040         fKeyrefsMapXSDocumentInfo[fKeyrefStackPos++] = schemaDoc;
2041     } // storeKeyref (Element, XSDocumentInfo, XSElementDecl): void
2042 
2043 
2044     /**
2045      * resolveSchema method is responsible for resolving location of the schema (using XMLEntityResolver),
2046      * and if it was succefully resolved getting the schema Document.
2047      * @param desc
2048      * @param mustResolve
2049      * @param referElement
2050      * @return A schema Element or null.
2051      */
2052     private Element resolveSchema(XSDDescription desc, boolean mustResolve,
2053                                   Element referElement, boolean usePairs) {
2054         XMLInputSource schemaSource = null;
2055         try {
2056             Map<String, XMLSchemaLoader.LocationArray> pairs = usePairs ? fLocationPairs : Collections.emptyMap();
2057             schemaSource = XMLSchemaLoader.resolveDocument(desc, pairs, fEntityManager);
2058         }
2059         catch (IOException ex) {
2060             if (mustResolve) {
2061                 reportSchemaError("schema_reference.4",
2062                         new Object[]{desc.getLocationHints()[0]},
2063                         referElement);
2064             }
2065             else {
2066                 reportSchemaWarning("schema_reference.4",
2067                         new Object[]{desc.getLocationHints()[0]},
2068                         referElement);
2069             }
2070         }
2071         if (schemaSource instanceof DOMInputSource) {
2072             return getSchemaDocument(desc.getTargetNamespace(), (DOMInputSource) schemaSource, mustResolve, desc.getContextType(), referElement);
2073         } // DOMInputSource
2074         else if (schemaSource instanceof SAXInputSource) {
2075             return getSchemaDocument(desc.getTargetNamespace(), (SAXInputSource) schemaSource, mustResolve, desc.getContextType(), referElement);
2076         } // SAXInputSource
2077         else if (schemaSource instanceof StAXInputSource) {
2078             return getSchemaDocument(desc.getTargetNamespace(), (StAXInputSource) schemaSource, mustResolve, desc.getContextType(), referElement);
2079         } // StAXInputSource
2080         else if (schemaSource instanceof XSInputSource) {
2081             return getSchemaDocument((XSInputSource) schemaSource, desc);
2082         } // XSInputSource
2083         return getSchemaDocument(desc.getTargetNamespace(), schemaSource, mustResolve, desc.getContextType(), referElement);
2084     } // getSchema(String, String, String, boolean, short):  Document
2085 
2086     private Element resolveSchema(XMLInputSource schemaSource, XSDDescription desc,
2087             boolean mustResolve, Element referElement) {
2088 
2089         if (schemaSource instanceof DOMInputSource) {
2090             return getSchemaDocument(desc.getTargetNamespace(), (DOMInputSource) schemaSource, mustResolve, desc.getContextType(), referElement);
2091         } // DOMInputSource
2092         else if (schemaSource instanceof SAXInputSource) {
2093             return getSchemaDocument(desc.getTargetNamespace(), (SAXInputSource) schemaSource, mustResolve, desc.getContextType(), referElement);
2094         } // SAXInputSource
2095         else if (schemaSource instanceof StAXInputSource) {
2096             return getSchemaDocument(desc.getTargetNamespace(), (StAXInputSource) schemaSource, mustResolve, desc.getContextType(), referElement);
2097         } // StAXInputSource
2098         else if (schemaSource instanceof XSInputSource) {
2099             return getSchemaDocument((XSInputSource) schemaSource, desc);
2100         } // XSInputSource
2101         return getSchemaDocument(desc.getTargetNamespace(), schemaSource, mustResolve, desc.getContextType(), referElement);
2102     }
2103 
2104     private XMLInputSource resolveSchemaSource(XSDDescription desc, boolean mustResolve,
2105             Element referElement, boolean usePairs) {
2106 
2107         XMLInputSource schemaSource = null;
2108         try {
2109             Map<String, XMLSchemaLoader.LocationArray> pairs = usePairs ? fLocationPairs : Collections.emptyMap();
2110             schemaSource = XMLSchemaLoader.resolveDocument(desc, pairs, fEntityManager);
2111         }
2112         catch (IOException ex) {
2113             if (mustResolve) {
2114                 reportSchemaError("schema_reference.4",
2115                         new Object[]{desc.getLocationHints()[0]},
2116                         referElement);
2117             }
2118             else {
2119                 reportSchemaWarning("schema_reference.4",
2120                         new Object[]{desc.getLocationHints()[0]},
2121                         referElement);
2122             }
2123         }
2124 
2125         return schemaSource;
2126     }
2127 
2128     /**
2129      * getSchemaDocument method uses XMLInputSource to parse a schema document.
2130      * @param schemaNamespace
2131      * @param schemaSource
2132      * @param mustResolve
2133      * @param referType
2134      * @param referElement
2135      * @return A schema Element.
2136      */
2137     private Element getSchemaDocument(String schemaNamespace, XMLInputSource schemaSource,
2138             boolean mustResolve, short referType, Element referElement) {
2139 
2140         boolean hasInput = true;
2141         IOException exception = null;
2142         // contents of this method will depend on the system we adopt for entity resolution--i.e., XMLEntityHandler, EntityHandler, etc.
2143         Element schemaElement = null;
2144         try {
2145             // when the system id and byte stream and character stream
2146             // of the input source are all null, it's
2147             // impossible to find the schema document. so we skip in
2148             // this case. otherwise we'll receive some NPE or
2149             // file not found errors. but schemaHint=="" is perfectly
2150             // legal for import.
2151             if (schemaSource != null &&
2152                     (schemaSource.getSystemId() != null ||
2153                             schemaSource.getByteStream() != null ||
2154                             schemaSource.getCharacterStream() != null)) {
2155 
2156                 // When the system id of the input source is used, first try to
2157                 // expand it, and check whether the same document has been
2158                 // parsed before. If so, return the document corresponding to
2159                 // that system id.
2160                 XSDKey key = null;
2161                 String schemaId = null;
2162                 if (referType != XSDDescription.CONTEXT_PREPARSE){
2163                     schemaId = XMLEntityManager.expandSystemId(schemaSource.getSystemId(), schemaSource.getBaseSystemId(), false);
2164                     key = new XSDKey(schemaId, referType, schemaNamespace);
2165                     if((schemaElement = fTraversed.get(key)) != null) {
2166                         fLastSchemaWasDuplicate = true;
2167                         return schemaElement;
2168                     }
2169                     if (referType == XSDDescription.CONTEXT_IMPORT || referType == XSDDescription.CONTEXT_INCLUDE
2170                             || referType == XSDDescription.CONTEXT_REDEFINE) {
2171                         String accessError = SecuritySupport.checkAccess(schemaId, fAccessExternalSchema, Constants.ACCESS_EXTERNAL_ALL);
2172                         if (accessError != null) {
2173                             reportSchemaFatalError("schema_reference.access",
2174                                     new Object[] { SecuritySupport.sanitizePath(schemaId), accessError },
2175                                     referElement);
2176                         }
2177                     }
2178                 }
2179 
2180                 fSchemaParser.parse(schemaSource);
2181                 Document schemaDocument = fSchemaParser.getDocument();
2182                 schemaElement = schemaDocument != null ? DOMUtil.getRoot(schemaDocument) : null;
2183                 return getSchemaDocument0(key, schemaId, schemaElement);
2184             }
2185             else {
2186                 hasInput = false;
2187             }
2188         }
2189         catch (IOException ex) {
2190             exception = ex;
2191         }
2192         return getSchemaDocument1(mustResolve, hasInput, schemaSource, referElement, exception);
2193     } // getSchemaDocument(String, XMLInputSource, boolean, short, Element): Element
2194 
2195     /**
2196      * getSchemaDocument method uses SAXInputSource to parse a schema document.
2197      * @param schemaNamespace
2198      * @param schemaSource
2199      * @param mustResolve
2200      * @param referType
2201      * @param referElement
2202      * @return A schema Element.
2203      */
2204     private Element getSchemaDocument(String schemaNamespace, SAXInputSource schemaSource,
2205             boolean mustResolve, short referType, Element referElement) {
2206         XMLReader parser = schemaSource.getXMLReader();
2207         InputSource inputSource = schemaSource.getInputSource();
2208         boolean hasInput = true;
2209         IOException exception = null;
2210         Element schemaElement = null;
2211         try {
2212             if (inputSource != null &&
2213                     (inputSource.getSystemId() != null ||
2214                      inputSource.getByteStream() != null ||
2215                      inputSource.getCharacterStream() != null)) {
2216 
2217                 // check whether the same document has been parsed before.
2218                 // If so, return the document corresponding to that system id.
2219                 XSDKey key = null;
2220                 String schemaId = null;
2221                 if (referType != XSDDescription.CONTEXT_PREPARSE) {
2222                     schemaId = XMLEntityManager.expandSystemId(inputSource.getSystemId(),
2223                             schemaSource.getBaseSystemId(), false);
2224                     key = new XSDKey(schemaId, referType, schemaNamespace);
2225                     if ((schemaElement = fTraversed.get(key)) != null) {
2226                         fLastSchemaWasDuplicate = true;
2227                         return schemaElement;
2228                     }
2229                 }
2230 
2231                 boolean namespacePrefixes = false;
2232                 if (parser != null) {
2233                     try {
2234                         namespacePrefixes = parser.getFeature(NAMESPACE_PREFIXES);
2235                     }
2236                     catch (SAXException se) {}
2237                 }
2238                 else {
2239                     parser = JdkXmlUtils.getXMLReader(fOverrideDefaultParser,
2240                             fSecurityManager.isSecureProcessing());
2241 
2242                     try {
2243                         parser.setFeature(NAMESPACE_PREFIXES, true);
2244                         namespacePrefixes = true;
2245                         // If this is a Xerces SAX parser set the security manager if there is one
2246                         if (parser instanceof SAXParser) {
2247                             if (fSecurityManager != null) {
2248                                 parser.setProperty(SECURITY_MANAGER, fSecurityManager);
2249                             }
2250                         }
2251                     }
2252                     catch (SAXException se) {}
2253 
2254                     try {
2255                         parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, fAccessExternalDTD);
2256                     } catch (SAXNotRecognizedException exc) {
2257                         XMLSecurityManager.printWarning(parser.getClass().getName(),
2258                                 XMLConstants.ACCESS_EXTERNAL_DTD, exc);
2259                     }
2260                 }
2261                 // If XML names and Namespace URIs are already internalized we
2262                 // can avoid running them through the SymbolTable.
2263                 boolean stringsInternalized = false;
2264                 try {
2265                     stringsInternalized = parser.getFeature(STRING_INTERNING);
2266                 }
2267                 catch (SAXException exc) {
2268                     // The feature isn't recognized or getting it is not supported.
2269                     // In either case, assume that strings are not internalized.
2270                 }
2271                 if (fXSContentHandler == null) {
2272                     fXSContentHandler = new SchemaContentHandler();
2273                 }
2274                 fXSContentHandler.reset(fSchemaParser, fSymbolTable,
2275                         namespacePrefixes, stringsInternalized);
2276                 parser.setContentHandler(fXSContentHandler);
2277                 parser.setErrorHandler(fErrorReporter.getSAXErrorHandler());
2278 
2279                 parser.parse(inputSource);
2280                 // Disconnect the schema loader and other objects from the XMLReader
2281                 try {
2282                     parser.setContentHandler(null);
2283                     parser.setErrorHandler(null);
2284                 }
2285                 // Ignore any exceptions thrown by the XMLReader. Old versions of SAX
2286                 // required an XMLReader to throw a NullPointerException if an attempt
2287                 // to set a handler to null was made.
2288                 catch (Exception e) {}
2289 
2290                 Document schemaDocument = fXSContentHandler.getDocument();
2291                 schemaElement = schemaDocument != null ? DOMUtil.getRoot(schemaDocument) : null;
2292                 return getSchemaDocument0(key, schemaId, schemaElement);
2293             }
2294             else {
2295                 hasInput = false;
2296             }
2297         }
2298         catch (SAXParseException spe) {
2299             throw SAX2XNIUtil.createXMLParseException0(spe);
2300         }
2301         catch (SAXException se) {
2302             throw SAX2XNIUtil.createXNIException0(se);
2303         }
2304         catch (IOException ioe) {
2305             exception = ioe;
2306         }
2307         return getSchemaDocument1(mustResolve, hasInput, schemaSource, referElement, exception);
2308     } // getSchemaDocument(String, SAXInputSource, boolean, short, Element): Element
2309 
2310     /**
2311      * getSchemaDocument method uses DOMInputSource to parse a schema document.
2312      * @param schemaNamespace
2313      * @param schemaSource
2314      * @param mustResolve
2315      * @param referType
2316      * @param referElement
2317      * @return A schema Element.
2318      */
2319     private Element getSchemaDocument(String schemaNamespace, DOMInputSource schemaSource,
2320             boolean mustResolve, short referType, Element referElement) {
2321         boolean hasInput = true;
2322         IOException exception = null;
2323         Element schemaElement = null;
2324         Element schemaRootElement = null;
2325 
2326         final Node node = schemaSource.getNode();
2327         short nodeType = -1;
2328         if (node != null) {
2329             nodeType = node.getNodeType();
2330             if (nodeType == Node.DOCUMENT_NODE) {
2331                 schemaRootElement = DOMUtil.getRoot((Document) node);
2332             }
2333             else if (nodeType == Node.ELEMENT_NODE) {
2334                 schemaRootElement = (Element) node;
2335             }
2336         }
2337 
2338         try {
2339             if (schemaRootElement != null) {
2340                 // check whether the same document has been parsed before.
2341                 // If so, return the document corresponding to that system id.
2342                 XSDKey key = null;
2343                 String schemaId = null;
2344                 if (referType != XSDDescription.CONTEXT_PREPARSE) {
2345                     schemaId = XMLEntityManager.expandSystemId(schemaSource.getSystemId(), schemaSource.getBaseSystemId(), false);
2346                     boolean isDocument = (nodeType == Node.DOCUMENT_NODE);
2347                     if (!isDocument) {
2348                         Node parent = schemaRootElement.getParentNode();
2349                         if (parent != null) {
2350                             isDocument = (parent.getNodeType() == Node.DOCUMENT_NODE);
2351                         }
2352                     }
2353                     if (isDocument) {
2354                         key = new XSDKey(schemaId, referType, schemaNamespace);
2355                         if ((schemaElement = fTraversed.get(key)) != null) {
2356                             fLastSchemaWasDuplicate = true;
2357                             return schemaElement;
2358                         }
2359                     }
2360                 }
2361 
2362                 schemaElement = schemaRootElement;
2363                 return getSchemaDocument0(key, schemaId, schemaElement);
2364             }
2365             else {
2366                 hasInput = false;
2367             }
2368         }
2369         catch (IOException ioe) {
2370             exception = ioe;
2371         }
2372         return getSchemaDocument1(mustResolve, hasInput, schemaSource, referElement, exception);
2373     } // getSchemaDocument(String, DOMInputSource, boolean, short, Element): Element
2374 
2375     /**
2376      * getSchemaDocument method uses StAXInputSource to parse a schema document.
2377      * @param schemaNamespace
2378      * @param schemaSource
2379      * @param mustResolve
2380      * @param referType
2381      * @param referElement
2382      * @return A schema Element.
2383      */
2384     private Element getSchemaDocument(String schemaNamespace, StAXInputSource schemaSource,
2385             boolean mustResolve, short referType, Element referElement) {
2386         IOException exception = null;
2387         Element schemaElement = null;
2388         try {
2389             final boolean consumeRemainingContent = schemaSource.shouldConsumeRemainingContent();
2390             final XMLStreamReader streamReader = schemaSource.getXMLStreamReader();
2391             final XMLEventReader eventReader = schemaSource.getXMLEventReader();
2392 
2393             // check whether the same document has been parsed before.
2394             // If so, return the document corresponding to that system id.
2395             XSDKey key = null;
2396             String schemaId = null;
2397             if (referType != XSDDescription.CONTEXT_PREPARSE) {
2398                 schemaId = XMLEntityManager.expandSystemId(schemaSource.getSystemId(), schemaSource.getBaseSystemId(), false);
2399                 boolean isDocument = consumeRemainingContent;
2400                 if (!isDocument) {
2401                     if (streamReader != null) {
2402                         isDocument = (streamReader.getEventType() == XMLStreamReader.START_DOCUMENT);
2403                     }
2404                     else {
2405                         isDocument = eventReader.peek().isStartDocument();
2406                     }
2407                 }
2408                 if (isDocument) {
2409                     key = new XSDKey(schemaId, referType, schemaNamespace);
2410                     if ((schemaElement = fTraversed.get(key)) != null) {
2411                         fLastSchemaWasDuplicate = true;
2412                         return schemaElement;
2413                     }
2414                 }
2415             }
2416 
2417             if (fStAXSchemaParser == null) {
2418                 fStAXSchemaParser = new StAXSchemaParser();
2419             }
2420             fStAXSchemaParser.reset(fSchemaParser, fSymbolTable);
2421 
2422             if (streamReader != null) {
2423                 fStAXSchemaParser.parse(streamReader);
2424                 if (consumeRemainingContent) {
2425                     while (streamReader.hasNext()) {
2426                         streamReader.next();
2427                     }
2428                 }
2429             }
2430             else {
2431                 fStAXSchemaParser.parse(eventReader);
2432                 if (consumeRemainingContent) {
2433                     while (eventReader.hasNext()) {
2434                         eventReader.nextEvent();
2435                     }
2436                 }
2437             }
2438             Document schemaDocument = fStAXSchemaParser.getDocument();
2439             schemaElement = schemaDocument != null ? DOMUtil.getRoot(schemaDocument) : null;
2440             return getSchemaDocument0(key, schemaId, schemaElement);
2441         }
2442         catch (XMLStreamException e) {
2443             StAXLocationWrapper slw = new StAXLocationWrapper();
2444             slw.setLocation(e.getLocation());
2445             throw new XMLParseException(slw, e.getMessage(), e);
2446         }
2447         catch (IOException e) {
2448             exception = e;
2449         }
2450         return getSchemaDocument1(mustResolve, true, schemaSource, referElement, exception);
2451     } // getSchemaDocument(String, StAXInputSource, boolean, short, Element): Element
2452 
2453     /**
2454      * Code shared between the various getSchemaDocument() methods which
2455      * stores mapping information for the document.
2456      */
2457     private Element getSchemaDocument0(XSDKey key, String schemaId, Element schemaElement) {
2458         // now we need to store the mapping information from system id
2459         // to the document. also from the document to the system id.
2460         if (key != null) {
2461             fTraversed.put(key, schemaElement);
2462         }
2463         if (schemaId != null) {
2464             fDoc2SystemId.put(schemaElement, schemaId);
2465         }
2466         fLastSchemaWasDuplicate = false;
2467         return schemaElement;
2468     } // getSchemaDocument0(XSDKey, String, Element): Element
2469 
2470     /**
2471      * Error handling code shared between the various getSchemaDocument() methods.
2472      */
2473     private Element getSchemaDocument1(boolean mustResolve, boolean hasInput,
2474             XMLInputSource schemaSource, Element referElement, IOException ioe) {
2475         // either an error occured (exception), or empty input source was
2476         // returned, we need to report an error or a warning
2477         if (mustResolve) {
2478             if (hasInput) {
2479                 reportSchemaError("schema_reference.4",
2480                         new Object[]{schemaSource.getSystemId()},
2481                         referElement, ioe);
2482             }
2483             else {
2484                 reportSchemaError("schema_reference.4",
2485                         new Object[]{schemaSource == null ? "" : schemaSource.getSystemId()},
2486                         referElement, ioe);
2487             }
2488         }
2489         else if (hasInput) {
2490             reportSchemaWarning("schema_reference.4",
2491                     new Object[]{schemaSource.getSystemId()},
2492                     referElement, ioe);
2493         }
2494 
2495         fLastSchemaWasDuplicate = false;
2496         return null;
2497     } // getSchemaDocument1(boolean, boolean, XMLInputSource, Element): Element
2498 
2499     /**
2500      * getSchemaDocument method uses XMLInputSource to parse a schema document.
2501      * @param schemaNamespace
2502      * @param schemaSource
2503      * @param mustResolve
2504      * @param referType
2505      * @param referElement
2506      * @return A schema Element.
2507      */
2508     private Element getSchemaDocument(XSInputSource schemaSource, XSDDescription desc) {
2509 
2510         SchemaGrammar[] grammars = schemaSource.getGrammars();
2511         short referType = desc.getContextType();
2512 
2513         if (grammars != null && grammars.length > 0) {
2514             Vector expandedGrammars = expandGrammars(grammars);
2515             // check for existing grammars in our bucket
2516             // and if there exist any, and namespace growth is
2517             // not enabled - we do nothing
2518             if (fNamespaceGrowth || !existingGrammars(expandedGrammars)) {
2519                 addGrammars(expandedGrammars);
2520                 if (referType == XSDDescription.CONTEXT_PREPARSE) {
2521                     desc.setTargetNamespace(grammars[0].getTargetNamespace());
2522                 }
2523             }
2524         }
2525         else {
2526             XSObject[] components = schemaSource.getComponents();
2527             if (components != null && components.length > 0) {
2528                 Map<String, Vector> importDependencies = new HashMap();
2529                 Vector expandedComponents = expandComponents(components, importDependencies);
2530                 if (fNamespaceGrowth || canAddComponents(expandedComponents)) {
2531                     addGlobalComponents(expandedComponents, importDependencies);
2532                     if (referType == XSDDescription.CONTEXT_PREPARSE) {
2533                         desc.setTargetNamespace(components[0].getNamespace());
2534                     }
2535                 }
2536             }
2537         }
2538         return null;
2539     } // getSchemaDocument(String, XSInputSource, boolean, short, Element): Element
2540 
2541     private Vector expandGrammars(SchemaGrammar[] grammars) {
2542         Vector currGrammars = new Vector();
2543 
2544         for (int i=0; i<grammars.length; i++) {
2545             if (!currGrammars.contains(grammars[i])) {
2546                 currGrammars.add(grammars[i]);
2547             }
2548         }
2549 
2550         // for all (recursively) imported grammars
2551         SchemaGrammar sg1, sg2;
2552         Vector gs;
2553         for (int i = 0; i < currGrammars.size(); i++) {
2554             // get the grammar
2555             sg1 = (SchemaGrammar)currGrammars.elementAt(i);
2556             // we need to add grammars imported by sg1 too
2557             gs = sg1.getImportedGrammars();
2558             // for all grammars imported by sg2, but not in the vector
2559             // we add them to the vector
2560             if (gs == null) {
2561                 continue;
2562             }
2563 
2564             for (int j = gs.size() - 1; j >= 0; j--) {
2565                 sg2 = (SchemaGrammar)gs.elementAt(j);
2566                 if (!currGrammars.contains(sg2)) {
2567                     currGrammars.addElement(sg2);
2568                 }
2569             }
2570         }
2571 
2572         return currGrammars;
2573     }
2574 
2575     private boolean existingGrammars(Vector grammars) {
2576         int length = grammars.size();
2577         final XSDDescription desc = new XSDDescription();
2578 
2579         for (int i=0; i < length; i++) {
2580             final SchemaGrammar sg1 = (SchemaGrammar)grammars.elementAt(i);
2581             desc.setNamespace(sg1.getTargetNamespace());
2582 
2583             final SchemaGrammar sg2 = findGrammar(desc, false);
2584             if (sg2 != null) {
2585                 return true;
2586             }
2587         }
2588 
2589         return false;
2590     }
2591 
2592     private boolean canAddComponents(Vector components) {
2593         final int size = components.size();
2594         final XSDDescription desc = new XSDDescription();
2595         for (int i=0; i<size; i++) {
2596             XSObject component = (XSObject) components.elementAt(i);
2597             if (!canAddComponent(component, desc)) {
2598                 return false;
2599             }
2600         }
2601         return true;
2602     }
2603 
2604     private boolean canAddComponent(XSObject component, XSDDescription desc) {
2605         desc.setNamespace(component.getNamespace());
2606 
2607         final SchemaGrammar sg = findGrammar(desc, false);
2608         if (sg == null) {
2609             return true;
2610         }
2611         else if (sg.isImmutable()) {
2612             return false;
2613         }
2614 
2615         short componentType = component.getType();
2616         final String name = component.getName();
2617 
2618         switch (componentType) {
2619         case XSConstants.TYPE_DEFINITION :
2620             if (sg.getGlobalTypeDecl(name) == component) {
2621                 return true;
2622             }
2623             break;
2624         case XSConstants.ATTRIBUTE_DECLARATION :
2625             if (sg.getGlobalAttributeDecl(name) == component) {
2626                 return true;
2627             }
2628             break;
2629         case XSConstants.ATTRIBUTE_GROUP :
2630             if (sg.getGlobalAttributeDecl(name) == component) {
2631                 return true;
2632             }
2633             break;
2634         case XSConstants.ELEMENT_DECLARATION :
2635             if (sg.getGlobalElementDecl(name) == component) {
2636                 return true;
2637             }
2638             break;
2639         case XSConstants.MODEL_GROUP_DEFINITION :
2640             if (sg.getGlobalGroupDecl(name) == component) {
2641                 return true;
2642             }
2643             break;
2644         case XSConstants.NOTATION_DECLARATION :
2645             if (sg.getGlobalNotationDecl(name) == component) {
2646                 return true;
2647             }
2648             break;
2649         case XSConstants.IDENTITY_CONSTRAINT :
2650         case XSConstants.ATTRIBUTE_USE :
2651         default :
2652             return true;
2653         }
2654         return false;
2655     }
2656 
2657     private void addGrammars(Vector grammars) {
2658         int length = grammars.size();
2659         XSDDescription desc = new XSDDescription();
2660 
2661         for (int i=0; i < length; i++) {
2662             final SchemaGrammar sg1 = (SchemaGrammar)grammars.elementAt(i);
2663             desc.setNamespace(sg1.getTargetNamespace());
2664 
2665             final SchemaGrammar sg2 = findGrammar(desc, fNamespaceGrowth);
2666             if (sg1 != sg2) {
2667                 addGrammarComponents(sg1, sg2);
2668             }
2669         }
2670     }
2671 
2672     private void addGrammarComponents(SchemaGrammar srcGrammar, SchemaGrammar dstGrammar) {
2673         if (dstGrammar == null) {
2674             createGrammarFrom(srcGrammar);
2675             return;
2676         }
2677 
2678         SchemaGrammar tmpGrammar = dstGrammar;
2679         if (tmpGrammar.isImmutable()) {
2680             tmpGrammar = createGrammarFrom(dstGrammar);
2681         }
2682 
2683         // add any new locations
2684         addNewGrammarLocations(srcGrammar, tmpGrammar);
2685 
2686         // add any new imported grammars
2687         addNewImportedGrammars(srcGrammar, tmpGrammar);
2688 
2689         // add any new global components
2690         addNewGrammarComponents(srcGrammar, tmpGrammar);
2691     }
2692 
2693     private SchemaGrammar createGrammarFrom(SchemaGrammar grammar) {
2694         SchemaGrammar newGrammar = new SchemaGrammar(grammar);
2695         fGrammarBucket.putGrammar(newGrammar);
2696         // update all the grammars in the bucket to point to the new grammar.
2697         updateImportListWith(newGrammar);
2698         // update import list of the new grammar
2699         updateImportListFor(newGrammar);
2700         return newGrammar;
2701     }
2702 
2703     private void addNewGrammarLocations(SchemaGrammar srcGrammar, SchemaGrammar dstGrammar) {
2704         final StringList locations = srcGrammar.getDocumentLocations();
2705         final int locSize = locations.size();
2706         final StringList locations2 = dstGrammar.getDocumentLocations();
2707 
2708         for (int i=0; i<locSize; i++) {
2709             String loc = locations.item(i);
2710             if (!locations2.contains(loc)) {
2711                 dstGrammar.addDocument(null, loc);
2712             }
2713         }
2714     }
2715 
2716     private void addNewImportedGrammars(SchemaGrammar srcGrammar, SchemaGrammar dstGrammar) {
2717         final Vector igs1 = srcGrammar.getImportedGrammars();
2718         if (igs1 != null) {
2719             Vector igs2 = dstGrammar.getImportedGrammars();
2720 
2721             if (igs2 == null) {
2722                 igs2 = ((Vector) igs1.clone());
2723                 dstGrammar.setImportedGrammars(igs2);
2724             }
2725             else {
2726                 updateImportList(igs1, igs2);
2727             }
2728         }
2729     }
2730 
2731     private void updateImportList(Vector importedSrc, Vector importedDst)
2732     {
2733         final int size = importedSrc.size();
2734 
2735         for (int i=0; i<size; i++) {
2736             final SchemaGrammar sg = (SchemaGrammar) importedSrc.elementAt(i);
2737             if (!containedImportedGrammar(importedDst, sg)) {
2738                 importedDst.add(sg);
2739             }
2740         }
2741     }
2742 
2743     private void addNewGrammarComponents(SchemaGrammar srcGrammar, SchemaGrammar dstGrammar) {
2744         dstGrammar.resetComponents();
2745         addGlobalElementDecls(srcGrammar, dstGrammar);
2746         addGlobalAttributeDecls(srcGrammar, dstGrammar);
2747         addGlobalAttributeGroupDecls(srcGrammar, dstGrammar);
2748         addGlobalGroupDecls(srcGrammar, dstGrammar);
2749         addGlobalTypeDecls(srcGrammar, dstGrammar);
2750         addGlobalNotationDecls(srcGrammar, dstGrammar);
2751     }
2752 
2753     private void addGlobalElementDecls(SchemaGrammar srcGrammar, SchemaGrammar dstGrammar) {
2754         XSNamedMap components = srcGrammar.getComponents(XSConstants.ELEMENT_DECLARATION);
2755         int len = components.getLength();
2756         XSElementDecl srcDecl, dstDecl;
2757 
2758         // add global components
2759         for (int i=0; i<len; i++) {
2760             srcDecl = (XSElementDecl) components.item(i);
2761             dstDecl = dstGrammar.getGlobalElementDecl(srcDecl.getName());
2762             if (dstDecl == null) {
2763                 dstGrammar.addGlobalElementDecl(srcDecl);
2764             }
2765             else if (dstDecl != srcDecl){
2766                 // TODO: if not tolerating duplicate, generate an error message
2767             }
2768         }
2769 
2770         // add any extended (duplicate) global components
2771         ObjectList componentsExt = srcGrammar.getComponentsExt(XSConstants.ELEMENT_DECLARATION);
2772         len = componentsExt.getLength();
2773 
2774         for (int i=0; i<len; i+= 2) {
2775             final String key = (String) componentsExt.item(i);
2776             final int index = key.indexOf(',');
2777             final String location = key.substring(0, index);
2778             final String name = key.substring(index + 1, key.length());
2779 
2780             srcDecl = (XSElementDecl)componentsExt.item(i+1);
2781             dstDecl = dstGrammar.getGlobalElementDecl(name, location);
2782             if ( dstDecl == null) {
2783                 dstGrammar.addGlobalElementDecl(srcDecl, location);
2784             }
2785             else if (dstDecl != srcDecl){
2786                 // TODO: if not tolerating duplicate, generate an error message
2787             }
2788         }
2789     }
2790 
2791     private void addGlobalAttributeDecls(SchemaGrammar srcGrammar, SchemaGrammar dstGrammar) {
2792         XSNamedMap components = srcGrammar.getComponents(XSConstants.ATTRIBUTE_DECLARATION);
2793         int len = components.getLength();
2794         XSAttributeDecl srcDecl, dstDecl;
2795 
2796         // add global components
2797         for (int i=0; i<len; i++) {
2798             srcDecl = (XSAttributeDecl) components.item(i);
2799             dstDecl = dstGrammar.getGlobalAttributeDecl(srcDecl.getName());
2800             if (dstDecl == null) {
2801                 dstGrammar.addGlobalAttributeDecl(srcDecl);
2802             }
2803             else if (dstDecl != srcDecl && !fTolerateDuplicates) {
2804                 reportSharingError(srcDecl.getNamespace(), srcDecl.getName());
2805             }
2806         }
2807 
2808         // add any extended (duplicate) global components
2809         ObjectList componentsExt = srcGrammar.getComponentsExt(XSConstants.ATTRIBUTE_DECLARATION);
2810         len = componentsExt.getLength();
2811 
2812         for (int i=0; i<len; i+= 2) {
2813             final String key = (String) componentsExt.item(i);
2814             final int index = key.indexOf(',');
2815             final String location = key.substring(0, index);
2816             final String name = key.substring(index + 1, key.length());
2817 
2818             srcDecl = (XSAttributeDecl)componentsExt.item(i+1);
2819             dstDecl = dstGrammar.getGlobalAttributeDecl(name, location);
2820             if (dstDecl == null) {
2821                 dstGrammar.addGlobalAttributeDecl(srcDecl, location);
2822             }
2823             // REVISIT - do we report an error?
2824             else if (dstDecl != srcDecl) {
2825             }
2826         }
2827     }
2828 
2829     private void addGlobalAttributeGroupDecls(SchemaGrammar srcGrammar, SchemaGrammar dstGrammar) {
2830         XSNamedMap components = srcGrammar.getComponents(XSConstants.ATTRIBUTE_GROUP);
2831         int len = components.getLength();
2832         XSAttributeGroupDecl srcDecl, dstDecl;
2833 
2834         // add global components
2835         for (int i=0; i<len; i++) {
2836             srcDecl = (XSAttributeGroupDecl) components.item(i);
2837             dstDecl = dstGrammar.getGlobalAttributeGroupDecl(srcDecl.getName());
2838             if (dstDecl == null) {
2839                 dstGrammar.addGlobalAttributeGroupDecl(srcDecl);
2840             }
2841             else if (dstDecl != srcDecl && !fTolerateDuplicates) {
2842                 reportSharingError(srcDecl.getNamespace(), srcDecl.getName());
2843             }
2844         }
2845 
2846         // add any extended (duplicate) global components
2847         ObjectList componentsExt = srcGrammar.getComponentsExt(XSConstants.ATTRIBUTE_GROUP);
2848         len = componentsExt.getLength();
2849 
2850         for (int i=0; i<len; i+= 2) {
2851             final String key = (String) componentsExt.item(i);
2852             final int index = key.indexOf(',');
2853             final String location = key.substring(0, index);
2854             final String name = key.substring(index + 1, key.length());
2855 
2856             srcDecl = (XSAttributeGroupDecl)componentsExt.item(i+1);
2857             dstDecl = dstGrammar.getGlobalAttributeGroupDecl(name, location);
2858             if (dstDecl == null) {
2859                 dstGrammar.addGlobalAttributeGroupDecl(srcDecl, location);
2860             }
2861             // REVISIT - do we report an error?
2862             else if (dstDecl != srcDecl) {
2863             }
2864         }
2865     }
2866 
2867     private void addGlobalNotationDecls(SchemaGrammar srcGrammar, SchemaGrammar dstGrammar) {
2868         XSNamedMap components = srcGrammar.getComponents(XSConstants.NOTATION_DECLARATION);
2869         int len = components.getLength();
2870         XSNotationDecl srcDecl, dstDecl;
2871 
2872         // add global components
2873         for (int i=0; i<len; i++) {
2874             srcDecl = (XSNotationDecl) components.item(i);
2875             dstDecl = dstGrammar.getGlobalNotationDecl(srcDecl.getName());
2876             if (dstDecl == null) {
2877                 dstGrammar.addGlobalNotationDecl(srcDecl);
2878             }
2879             else if (dstDecl != srcDecl && !fTolerateDuplicates) {
2880                 reportSharingError(srcDecl.getNamespace(), srcDecl.getName());
2881             }
2882         }
2883 
2884         // add any extended (duplicate) global components
2885         ObjectList componentsExt = srcGrammar.getComponentsExt(XSConstants.NOTATION_DECLARATION);
2886         len = componentsExt.getLength();
2887 
2888         for (int i=0; i<len; i+= 2) {
2889             final String key = (String) componentsExt.item(i);
2890             final int index = key.indexOf(',');
2891             final String location = key.substring(0, index);
2892             final String name = key.substring(index + 1, key.length());
2893 
2894             srcDecl = (XSNotationDecl)componentsExt.item(i+1);
2895             dstDecl = dstGrammar.getGlobalNotationDecl(name, location);
2896             if (dstDecl == null) {
2897                 dstGrammar.addGlobalNotationDecl(srcDecl, location);
2898             }
2899             // REVISIT - do we report an error?
2900             else if (dstDecl != srcDecl) {
2901             }
2902         }
2903     }
2904 
2905     private void addGlobalGroupDecls(SchemaGrammar srcGrammar, SchemaGrammar dstGrammar) {
2906         XSNamedMap components = srcGrammar.getComponents(XSConstants.MODEL_GROUP_DEFINITION);
2907         int len = components.getLength();
2908         XSGroupDecl srcDecl, dstDecl;
2909 
2910         // add global components
2911         for (int i=0; i<len; i++) {
2912             srcDecl = (XSGroupDecl) components.item(i);
2913             dstDecl = dstGrammar.getGlobalGroupDecl(srcDecl.getName());
2914             if (dstDecl == null) {
2915                 dstGrammar.addGlobalGroupDecl(srcDecl);
2916             }
2917             else if (srcDecl != dstDecl && !fTolerateDuplicates) {
2918                 reportSharingError(srcDecl.getNamespace(), srcDecl.getName());
2919             }
2920         }
2921 
2922         // add any extended (duplicate) global components
2923         ObjectList componentsExt = srcGrammar.getComponentsExt(XSConstants.MODEL_GROUP_DEFINITION);
2924         len = componentsExt.getLength();
2925 
2926         for (int i=0; i<len; i+= 2) {
2927             final String key = (String) componentsExt.item(i);
2928             final int index = key.indexOf(',');
2929             final String location = key.substring(0, index);
2930             final String name = key.substring(index + 1, key.length());
2931 
2932             srcDecl = (XSGroupDecl)componentsExt.item(i+1);
2933             dstDecl = dstGrammar.getGlobalGroupDecl(name, location);
2934             if (dstDecl == null) {
2935                 dstGrammar.addGlobalGroupDecl(srcDecl, location);
2936             }
2937             // REVIST - do we report an error?
2938             else if (dstDecl != srcDecl) {
2939             }
2940         }
2941     }
2942 
2943     private void addGlobalTypeDecls(SchemaGrammar srcGrammar, SchemaGrammar dstGrammar) {
2944         XSNamedMap components = srcGrammar.getComponents(XSConstants.TYPE_DEFINITION);
2945         int len = components.getLength();
2946         XSTypeDefinition srcDecl, dstDecl;
2947 
2948         // add global components
2949         for (int i=0; i<len; i++) {
2950             srcDecl = (XSTypeDefinition) components.item(i);
2951             dstDecl = dstGrammar.getGlobalTypeDecl(srcDecl.getName());
2952             if (dstDecl == null) {
2953                 dstGrammar.addGlobalTypeDecl(srcDecl);
2954             }
2955             else if (dstDecl != srcDecl && !fTolerateDuplicates) {
2956                 reportSharingError(srcDecl.getNamespace(), srcDecl.getName());
2957             }
2958         }
2959 
2960         // add any extended (duplicate) global components
2961         ObjectList componentsExt = srcGrammar.getComponentsExt(XSConstants.TYPE_DEFINITION);
2962         len = componentsExt.getLength();
2963 
2964         for (int i=0; i<len; i+= 2) {
2965             final String key = (String) componentsExt.item(i);
2966             final int index = key.indexOf(',');
2967             final String location = key.substring(0, index);
2968             final String name = key.substring(index + 1, key.length());
2969 
2970             srcDecl = (XSTypeDefinition)componentsExt.item(i+1);
2971             dstDecl = dstGrammar.getGlobalTypeDecl(name, location);
2972             if (dstDecl == null) {
2973                 dstGrammar.addGlobalTypeDecl(srcDecl, location);
2974             }
2975             // REVISIT - do we report an error?
2976             else if (dstDecl != srcDecl) {
2977             }
2978         }
2979     }
2980 
2981     private Vector expandComponents(XSObject[] components, Map<String, Vector> dependencies) {
2982         Vector newComponents = new Vector();
2983 
2984         for (int i=0; i<components.length; i++) {
2985             if (!newComponents.contains(components[i])) {
2986                 newComponents.add(components[i]);
2987             }
2988         }
2989 
2990         for (int i=0; i<newComponents.size(); i++) {
2991             final XSObject component = (XSObject) newComponents.elementAt(i);
2992             expandRelatedComponents(component, newComponents, dependencies);
2993         }
2994 
2995         return newComponents;
2996     }
2997 
2998     private void expandRelatedComponents(XSObject component, Vector componentList, Map<String, Vector> dependencies) {
2999         short componentType = component.getType();
3000         switch (componentType) {
3001         case XSConstants.TYPE_DEFINITION :
3002             expandRelatedTypeComponents((XSTypeDefinition) component, componentList, component.getNamespace(), dependencies);
3003             break;
3004         case XSConstants.ATTRIBUTE_DECLARATION :
3005             expandRelatedAttributeComponents((XSAttributeDeclaration) component, componentList, component.getNamespace(), dependencies);
3006             break;
3007         case XSConstants.ATTRIBUTE_GROUP :
3008             expandRelatedAttributeGroupComponents((XSAttributeGroupDefinition) component, componentList, component.getNamespace(), dependencies);
3009         case XSConstants.ELEMENT_DECLARATION :
3010             expandRelatedElementComponents((XSElementDeclaration) component, componentList, component.getNamespace(), dependencies);
3011             break;
3012         case XSConstants.MODEL_GROUP_DEFINITION :
3013             expandRelatedModelGroupDefinitionComponents((XSModelGroupDefinition) component, componentList, component.getNamespace(), dependencies);
3014         case XSConstants.ATTRIBUTE_USE :
3015             //expandRelatedAttributeUseComponents((XSAttributeUse)component, componentList, dependencies);
3016         case XSConstants.NOTATION_DECLARATION :
3017         case XSConstants.IDENTITY_CONSTRAINT :
3018         default :
3019             break;
3020         }
3021     }
3022 
3023     private void expandRelatedAttributeComponents(XSAttributeDeclaration decl, Vector componentList, String namespace, Map<String, Vector> dependencies) {
3024         addRelatedType(decl.getTypeDefinition(), componentList, namespace, dependencies);
3025 
3026         /*final XSComplexTypeDefinition enclosingType = decl.getEnclosingCTDefinition();
3027         if (enclosingType != null) {
3028             addRelatedType(enclosingType, componentList, namespace, dependencies);
3029         }*/
3030     }
3031 
3032     private void expandRelatedElementComponents(XSElementDeclaration decl, Vector componentList, String namespace, Map<String, Vector> dependencies) {
3033         addRelatedType(decl.getTypeDefinition(), componentList, namespace, dependencies);
3034 
3035         /*final XSTypeDefinition enclosingType = decl.getEnclosingCTDefinition();
3036         if (enclosingType != null) {
3037             addRelatedType(enclosingType, componentList, namespace, dependencies);
3038         }*/
3039 
3040         final XSElementDeclaration subElemDecl = decl.getSubstitutionGroupAffiliation();
3041         if (subElemDecl != null) {
3042             addRelatedElement(subElemDecl, componentList, namespace, dependencies);
3043         }
3044     }
3045 
3046     private void expandRelatedTypeComponents(XSTypeDefinition type, Vector componentList, String namespace, Map<String, Vector> dependencies) {
3047         if (type instanceof XSComplexTypeDecl) {
3048             expandRelatedComplexTypeComponents((XSComplexTypeDecl) type, componentList, namespace, dependencies);
3049         }
3050         else if (type instanceof XSSimpleTypeDecl) {
3051             expandRelatedSimpleTypeComponents((XSSimpleTypeDefinition) type, componentList, namespace, dependencies);
3052         }
3053     }
3054 
3055     private void expandRelatedModelGroupDefinitionComponents(XSModelGroupDefinition modelGroupDef, Vector componentList,
3056             String namespace, Map<String, Vector> dependencies) {
3057         expandRelatedModelGroupComponents(modelGroupDef.getModelGroup(), componentList, namespace, dependencies);
3058     }
3059 
3060     private void expandRelatedAttributeGroupComponents(XSAttributeGroupDefinition attrGroup, Vector componentList
3061             , String namespace, Map<String, Vector> dependencies) {
3062         expandRelatedAttributeUsesComponents(attrGroup.getAttributeUses(), componentList, namespace, dependencies);
3063     }
3064 
3065     private void expandRelatedComplexTypeComponents(XSComplexTypeDecl type, Vector componentList, String namespace, Map<String, Vector> dependencies) {
3066         addRelatedType(type.getBaseType(), componentList, namespace, dependencies);
3067         expandRelatedAttributeUsesComponents(type.getAttributeUses(), componentList, namespace, dependencies);
3068         final XSParticle particle = type.getParticle();
3069         if (particle != null) {
3070             expandRelatedParticleComponents(particle, componentList, namespace, dependencies);
3071         }
3072     }
3073 
3074     private void expandRelatedSimpleTypeComponents(XSSimpleTypeDefinition type, Vector componentList, String namespace, Map<String, Vector> dependencies) {
3075         final XSTypeDefinition baseType = type.getBaseType();
3076         if (baseType != null) {
3077             addRelatedType(baseType, componentList, namespace, dependencies);
3078         }
3079 
3080         final XSTypeDefinition itemType = type.getItemType();
3081         if (itemType != null) {
3082             addRelatedType(itemType, componentList, namespace, dependencies);
3083         }
3084 
3085         final XSTypeDefinition primitiveType = type.getPrimitiveType();
3086         if (primitiveType != null) {
3087             addRelatedType(primitiveType, componentList, namespace, dependencies);
3088         }
3089 
3090         final XSObjectList memberTypes = type.getMemberTypes();
3091         if (memberTypes.size() > 0) {
3092             for (int i=0; i<memberTypes.size(); i++) {
3093                 addRelatedType((XSTypeDefinition)memberTypes.item(i), componentList, namespace, dependencies);
3094             }
3095         }
3096     }
3097 
3098     private void expandRelatedAttributeUsesComponents(XSObjectList attrUses, Vector componentList,
3099             String namespace, Map<String, Vector> dependencies) {
3100         final int attrUseSize = (attrUses == null) ? 0 : attrUses.size();
3101         for (int i=0; i<attrUseSize; i++) {
3102             expandRelatedAttributeUseComponents((XSAttributeUse)attrUses.item(i), componentList, namespace, dependencies);
3103         }
3104     }
3105 
3106     private void expandRelatedAttributeUseComponents(XSAttributeUse component, Vector componentList,
3107             String namespace, Map<String, Vector> dependencies) {
3108         addRelatedAttribute(component.getAttrDeclaration(), componentList, namespace, dependencies);
3109     }
3110 
3111     private void expandRelatedParticleComponents(XSParticle component, Vector componentList,
3112             String namespace, Map<String, Vector> dependencies) {
3113         XSTerm term = component.getTerm();
3114         switch (term.getType()) {
3115         case XSConstants.ELEMENT_DECLARATION :
3116             addRelatedElement((XSElementDeclaration) term, componentList, namespace, dependencies);
3117             break;
3118         case XSConstants.MODEL_GROUP :
3119             expandRelatedModelGroupComponents((XSModelGroup) term, componentList, namespace, dependencies);
3120             break;
3121         default:
3122             break;
3123         }
3124     }
3125 
3126     private void expandRelatedModelGroupComponents(XSModelGroup modelGroup, Vector componentList,
3127             String namespace, Map<String, Vector> dependencies) {
3128         XSObjectList particles = modelGroup.getParticles();
3129         final int length = (particles == null) ? 0 : particles.getLength();
3130         for (int i=0; i<length; i++) {
3131             expandRelatedParticleComponents((XSParticle)particles.item(i), componentList, namespace, dependencies);
3132         }
3133     }
3134 
3135     private void addRelatedType(XSTypeDefinition type, Vector componentList, String namespace, Map<String, Vector> dependencies) {
3136         if (!type.getAnonymous()) {
3137             if (!type.getNamespace().equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)) { //REVISIT - do we use == instead
3138                 if (!componentList.contains(type)) {
3139                     final Vector importedNamespaces = findDependentNamespaces(namespace, dependencies);
3140                     addNamespaceDependency(namespace, type.getNamespace(), importedNamespaces);
3141                     componentList.add(type);
3142                 }
3143             }
3144         }
3145         else {
3146             expandRelatedTypeComponents(type, componentList, namespace, dependencies);
3147         }
3148     }
3149 
3150     private void addRelatedElement(XSElementDeclaration decl, Vector componentList, String namespace, Map<String, Vector> dependencies) {
3151         if (decl.getScope() == XSConstants.SCOPE_GLOBAL) {
3152             if (!componentList.contains(decl)) {
3153                 Vector importedNamespaces = findDependentNamespaces(namespace, dependencies);
3154                 addNamespaceDependency(namespace, decl.getNamespace(), importedNamespaces);
3155                 componentList.add(decl);
3156             }
3157         }
3158         else {
3159             expandRelatedElementComponents(decl, componentList, namespace, dependencies);
3160         }
3161     }
3162 
3163     private void addRelatedAttribute(XSAttributeDeclaration decl, Vector componentList, String namespace, Map<String, Vector> dependencies) {
3164         if (decl.getScope() == XSConstants.SCOPE_GLOBAL) {
3165             if (!componentList.contains(decl)) {
3166                 Vector importedNamespaces = findDependentNamespaces(namespace, dependencies);
3167                 addNamespaceDependency(namespace, decl.getNamespace(), importedNamespaces);
3168                 componentList.add(decl);
3169             }
3170         }
3171         else {
3172             expandRelatedAttributeComponents(decl, componentList, namespace, dependencies);
3173         }
3174     }
3175 
3176     private void addGlobalComponents(Vector components, Map<String, Vector> importDependencies) {
3177         final XSDDescription desc = new XSDDescription();
3178         final int size = components.size();
3179 
3180         for (int i=0; i<size; i++) {
3181             addGlobalComponent((XSObject) components.elementAt(i), desc);
3182         }
3183         updateImportDependencies(importDependencies);
3184     }
3185 
3186     private void addGlobalComponent(XSObject component, XSDDescription desc) {
3187         final String namespace = component.getNamespace();
3188 
3189         desc.setNamespace(namespace);
3190         final SchemaGrammar sg = getSchemaGrammar(desc);
3191 
3192         short componentType = component.getType();
3193         final String name = component.getName();
3194 
3195         switch (componentType) {
3196         case XSConstants.TYPE_DEFINITION :
3197             if (!((XSTypeDefinition) component).getAnonymous()) {
3198                 if (sg.getGlobalTypeDecl(name) == null) {
3199                     sg.addGlobalTypeDecl((XSTypeDefinition) component);
3200                 }
3201                 // store the declaration in the extended map, using an empty location
3202                 if (sg.getGlobalTypeDecl(name, "") == null) {
3203                     sg.addGlobalTypeDecl((XSTypeDefinition) component, "");
3204                 }
3205             }
3206             break;
3207         case XSConstants.ATTRIBUTE_DECLARATION :
3208             if (((XSAttributeDecl) component).getScope() == XSAttributeDecl.SCOPE_GLOBAL) {
3209                 if (sg.getGlobalAttributeDecl(name) == null) {
3210                     sg.addGlobalAttributeDecl((XSAttributeDecl) component);
3211                 }
3212                 // store the declaration in the extended map, using an empty location
3213                 if (sg.getGlobalAttributeDecl(name, "") == null) {
3214                     sg.addGlobalAttributeDecl((XSAttributeDecl) component, "");
3215                 }
3216             }
3217             break;
3218         case XSConstants.ATTRIBUTE_GROUP :
3219             if (sg.getGlobalAttributeDecl(name) == null) {
3220                 sg.addGlobalAttributeGroupDecl((XSAttributeGroupDecl) component);
3221             }
3222             // store the declaration in the extended map, using an empty location
3223             if (sg.getGlobalAttributeDecl(name, "") == null) {
3224                 sg.addGlobalAttributeGroupDecl((XSAttributeGroupDecl) component, "");
3225             }
3226             break;
3227         case XSConstants.ELEMENT_DECLARATION :
3228             if (((XSElementDecl) component).getScope() == XSElementDecl.SCOPE_GLOBAL) {
3229                 sg.addGlobalElementDeclAll((XSElementDecl) component);
3230 
3231                 if (sg.getGlobalElementDecl(name) == null) {
3232                     sg.addGlobalElementDecl((XSElementDecl) component);
3233                 }
3234                 // store the declaration in the extended map, using an empty location
3235                 if (sg.getGlobalElementDecl(name, "") == null) {
3236                     sg.addGlobalElementDecl((XSElementDecl) component, "");
3237                 }
3238             }
3239             break;
3240         case XSConstants.MODEL_GROUP_DEFINITION :
3241             if (sg.getGlobalGroupDecl(name) == null) {
3242                 sg.addGlobalGroupDecl((XSGroupDecl) component);
3243             }
3244             // store the declaration in the extended map, using an empty location
3245             if (sg.getGlobalGroupDecl(name, "") == null) {
3246                 sg.addGlobalGroupDecl((XSGroupDecl) component, "");
3247             }
3248             break;
3249         case XSConstants.NOTATION_DECLARATION :
3250             if (sg.getGlobalNotationDecl(name) == null) {
3251                 sg.addGlobalNotationDecl((XSNotationDecl) component);
3252             }
3253             // store the declaration in the extended map, using an empty location
3254             if (sg.getGlobalNotationDecl(name, "") == null) {
3255                 sg.addGlobalNotationDecl((XSNotationDecl) component, "");
3256             }
3257             break;
3258         case XSConstants.IDENTITY_CONSTRAINT :
3259         case XSConstants.ATTRIBUTE_USE :
3260         default :
3261             break;
3262         }
3263     }
3264 
3265     private void updateImportDependencies(Map<String, Vector> table) {
3266         if (table == null) return;
3267         String namespace;
3268         Vector importList;
3269 
3270         for(Map.Entry<String, Vector> entry : table.entrySet()){
3271             namespace = entry.getKey();
3272             importList = entry.getValue();
3273             if (importList.size() > 0) {
3274                 expandImportList(namespace, importList);
3275             }
3276         }
3277     }
3278 
3279     private void expandImportList(String namespace, Vector namespaceList) {
3280         SchemaGrammar sg = fGrammarBucket.getGrammar(namespace);
3281         // shouldn't be null
3282         if (sg != null) {
3283             Vector isgs = sg.getImportedGrammars();
3284             if (isgs == null) {
3285                 isgs = new Vector();
3286                 addImportList(sg, isgs, namespaceList);
3287                 sg.setImportedGrammars(isgs);
3288             }
3289             else {
3290                 updateImportList(sg, isgs, namespaceList);
3291             }
3292         }
3293     }
3294 
3295     private void addImportList(SchemaGrammar sg, Vector importedGrammars, Vector namespaceList) {
3296         final int size = namespaceList.size();
3297         SchemaGrammar isg;
3298 
3299         for (int i=0; i<size; i++) {
3300             isg = fGrammarBucket.getGrammar((String)namespaceList.elementAt(i));
3301             if (isg != null) {
3302                 importedGrammars.add(isg);
3303             }
3304             else {
3305                 //REVIST: report an error message
3306             }
3307         }
3308     }
3309 
3310     private void updateImportList(SchemaGrammar sg, Vector importedGrammars, Vector namespaceList) {
3311         final int size = namespaceList.size();
3312         SchemaGrammar isg;
3313 
3314         for (int i=0; i<size; i++) {
3315             isg = fGrammarBucket.getGrammar((String)namespaceList.elementAt(i));
3316             if (isg != null) {
3317                 if (!containedImportedGrammar(importedGrammars, isg)) {
3318                     importedGrammars.add(isg);
3319                 }
3320             }
3321             else {
3322                 //REVIST: report an error message
3323             }
3324         }
3325     }
3326 
3327     private boolean containedImportedGrammar(Vector importedGrammar, SchemaGrammar grammar) {
3328         final int size = importedGrammar.size();
3329         SchemaGrammar sg;
3330 
3331         for (int i=0; i<size; i++) {
3332             sg = (SchemaGrammar) importedGrammar.elementAt(i);
3333             if (null2EmptyString(sg.getTargetNamespace()).equals(null2EmptyString(grammar.getTargetNamespace()))) {
3334                 return true;
3335             }
3336         }
3337         return false;
3338     }
3339 
3340     // NOTE: always assuming that fNamespaceGrowth is enabled
3341     //       otherwise the grammar should have existed
3342     private SchemaGrammar getSchemaGrammar(XSDDescription desc) {
3343         SchemaGrammar sg = findGrammar(desc, fNamespaceGrowth);
3344 
3345         if (sg == null) {
3346             sg = new SchemaGrammar(desc.getNamespace(), desc.makeClone(), fSymbolTable);
3347             fGrammarBucket.putGrammar(sg);
3348         }
3349         else if (sg.isImmutable()){
3350             sg = createGrammarFrom(sg);
3351         }
3352 
3353         return sg;
3354     }
3355 
3356     private Vector findDependentNamespaces(String namespace, Map table) {
3357         final String ns = null2EmptyString(namespace);
3358         Vector namespaceList = (Vector) getFromMap(table, ns);
3359 
3360         if (namespaceList == null) {
3361             namespaceList = new Vector();
3362             table.put(ns, namespaceList);
3363         }
3364 
3365         return namespaceList;
3366     }
3367 
3368     private void addNamespaceDependency(String namespace1, String namespace2, Vector list) {
3369         final String ns1 = null2EmptyString(namespace1);
3370         final String ns2 = null2EmptyString(namespace2);
3371         if (!ns1.equals(ns2)) {
3372             if (!list.contains(ns2)) {
3373                 list.add(ns2);
3374             }
3375         }
3376     }
3377 
3378     private void reportSharingError(String namespace, String name) {
3379         final String qName = (namespace == null)
3380             ? "," + name : namespace + "," + name;
3381 
3382         reportSchemaError("sch-props-correct.2", new Object [] {qName}, null);
3383     }
3384 
3385     // initialize all the traversers.
3386     // this should only need to be called once during the construction
3387     // of this object; it creates the traversers that will be used to
3388 
3389     // construct schemaGrammars.
3390     private void createTraversers() {
3391         fAttributeChecker = new XSAttributeChecker(this);
3392         fAttributeGroupTraverser = new XSDAttributeGroupTraverser(this, fAttributeChecker);
3393         fAttributeTraverser = new XSDAttributeTraverser(this, fAttributeChecker);
3394         fComplexTypeTraverser = new XSDComplexTypeTraverser(this, fAttributeChecker);
3395         fElementTraverser = new XSDElementTraverser(this, fAttributeChecker);
3396         fGroupTraverser = new XSDGroupTraverser(this, fAttributeChecker);
3397         fKeyrefTraverser = new XSDKeyrefTraverser(this, fAttributeChecker);
3398         fNotationTraverser = new XSDNotationTraverser(this, fAttributeChecker);
3399         fSimpleTypeTraverser = new XSDSimpleTypeTraverser(this, fAttributeChecker);
3400         fUniqueOrKeyTraverser = new XSDUniqueOrKeyTraverser(this, fAttributeChecker);
3401         fWildCardTraverser = new XSDWildcardTraverser(this, fAttributeChecker);
3402     } // createTraversers()
3403 
3404     // before parsing a schema, need to clear registries associated with
3405     // parsing schemas
3406     void prepareForParse() {
3407         fTraversed.clear();
3408         fDoc2SystemId.clear();
3409         fHiddenNodes.clear();
3410         fLastSchemaWasDuplicate = false;
3411     }
3412 
3413     // before traversing a schema's parse tree, need to reset all traversers and
3414     // clear all registries
3415     void prepareForTraverse() {
3416         if (!registryEmpty) {
3417         fUnparsedAttributeRegistry.clear();
3418         fUnparsedAttributeGroupRegistry.clear();
3419         fUnparsedElementRegistry.clear();
3420         fUnparsedGroupRegistry.clear();
3421         fUnparsedIdentityConstraintRegistry.clear();
3422         fUnparsedNotationRegistry.clear();
3423         fUnparsedTypeRegistry.clear();
3424 
3425         fUnparsedAttributeRegistrySub.clear();
3426         fUnparsedAttributeGroupRegistrySub.clear();
3427         fUnparsedElementRegistrySub.clear();
3428         fUnparsedGroupRegistrySub.clear();
3429         fUnparsedIdentityConstraintRegistrySub.clear();
3430         fUnparsedNotationRegistrySub.clear();
3431         fUnparsedTypeRegistrySub.clear();
3432         }
3433 
3434         for (int i=1; i<= TYPEDECL_TYPE; i++) {
3435             if (fUnparsedRegistriesExt[i] != null)
3436                 fUnparsedRegistriesExt[i].clear();
3437         }
3438 
3439         fDependencyMap.clear();
3440         fDoc2XSDocumentMap.clear();
3441         if (fRedefine2XSDMap != null) fRedefine2XSDMap.clear();
3442         if (fRedefine2NSSupport != null) fRedefine2NSSupport.clear();
3443         fAllTNSs.removeAllElements();
3444         fImportMap.clear();
3445         fRoot = null;
3446 
3447         // clear local element stack
3448         for (int i = 0; i < fLocalElemStackPos; i++) {
3449             fParticle[i] = null;
3450             fLocalElementDecl[i] = null;
3451             fLocalElementDecl_schema[i] = null;
3452             fLocalElemNamespaceContext[i] = null;
3453         }
3454         fLocalElemStackPos = 0;
3455 
3456         // and do same for keyrefs.
3457         for (int i = 0; i < fKeyrefStackPos; i++) {
3458             fKeyrefs[i] = null;
3459             fKeyrefElems[i] = null;
3460             fKeyrefNamespaceContext[i] = null;
3461             fKeyrefsMapXSDocumentInfo[i] = null;
3462         }
3463         fKeyrefStackPos = 0;
3464 
3465         // create traversers if necessary
3466         if (fAttributeChecker == null) {
3467             createTraversers();
3468         }
3469 
3470         // reset traversers
3471         Locale locale = fErrorReporter.getLocale();
3472         fAttributeChecker.reset(fSymbolTable);
3473         fAttributeGroupTraverser.reset(fSymbolTable, fValidateAnnotations, locale);
3474         fAttributeTraverser.reset(fSymbolTable, fValidateAnnotations, locale);
3475         fComplexTypeTraverser.reset(fSymbolTable, fValidateAnnotations, locale);
3476         fElementTraverser.reset(fSymbolTable, fValidateAnnotations, locale);
3477         fGroupTraverser.reset(fSymbolTable, fValidateAnnotations, locale);
3478         fKeyrefTraverser.reset(fSymbolTable, fValidateAnnotations, locale);
3479         fNotationTraverser.reset(fSymbolTable, fValidateAnnotations, locale);
3480         fSimpleTypeTraverser.reset(fSymbolTable, fValidateAnnotations, locale);
3481         fUniqueOrKeyTraverser.reset(fSymbolTable, fValidateAnnotations, locale);
3482         fWildCardTraverser.reset(fSymbolTable, fValidateAnnotations, locale);
3483 
3484         fRedefinedRestrictedAttributeGroupRegistry.clear();
3485         fRedefinedRestrictedGroupRegistry.clear();
3486 
3487         fGlobalAttrDecls.clear();
3488         fGlobalAttrGrpDecls.clear();
3489         fGlobalElemDecls.clear();
3490         fGlobalGroupDecls.clear();
3491         fGlobalNotationDecls.clear();
3492         fGlobalIDConstraintDecls.clear();
3493         fGlobalTypeDecls.clear();
3494     }
3495     public void setDeclPool (XSDeclarationPool declPool){
3496         fDeclPool = declPool;
3497     }
3498     public void setDVFactory(SchemaDVFactory dvFactory){
3499         fDVFactory = dvFactory;
3500     }
3501     public SchemaDVFactory getDVFactory(){
3502         return fDVFactory;
3503     }
3504 
3505     public void reset(XMLComponentManager componentManager) {
3506 
3507         // set symbol table
3508         fSymbolTable = (SymbolTable) componentManager.getProperty(SYMBOL_TABLE);
3509 
3510         // set security manager
3511         fSecurityManager = (XMLSecurityManager) componentManager.getProperty(SECURITY_MANAGER, null);
3512 
3513         //set entity manager
3514         fEntityManager = (XMLEntityResolver) componentManager.getProperty(ENTITY_MANAGER);
3515 
3516         //set entity resolver
3517         XMLEntityResolver er = (XMLEntityResolver)componentManager.getProperty(ENTITY_RESOLVER);
3518         if (er != null)
3519             fSchemaParser.setEntityResolver(er);
3520 
3521         // set error reporter
3522         fErrorReporter = (XMLErrorReporter) componentManager.getProperty(ERROR_REPORTER);
3523         fErrorHandler = fErrorReporter.getErrorHandler();
3524         fLocale = fErrorReporter.getLocale();
3525 
3526         fValidateAnnotations = componentManager.getFeature(VALIDATE_ANNOTATIONS, false);
3527         fHonourAllSchemaLocations = componentManager.getFeature(HONOUR_ALL_SCHEMALOCATIONS, false);
3528         fNamespaceGrowth = componentManager.getFeature(NAMESPACE_GROWTH, false);
3529         fTolerateDuplicates = componentManager.getFeature(TOLERATE_DUPLICATES, false);
3530 
3531         try {
3532             // Setting a parser property can be much more expensive
3533             // than checking its value.  Don't set the ERROR_HANDLER
3534             // or LOCALE properties unless they've actually changed.
3535             if (fErrorHandler != fSchemaParser.getProperty(ERROR_HANDLER)) {
3536                 fSchemaParser.setProperty(ERROR_HANDLER, (fErrorHandler != null) ? fErrorHandler : new DefaultErrorHandler());
3537                 if (fAnnotationValidator != null) {
3538                     fAnnotationValidator.setProperty(ERROR_HANDLER, (fErrorHandler != null) ? fErrorHandler : new DefaultErrorHandler());
3539                 }
3540             }
3541             if (fLocale != fSchemaParser.getProperty(LOCALE)) {
3542                 fSchemaParser.setProperty(LOCALE, fLocale);
3543                 if (fAnnotationValidator != null) {
3544                     fAnnotationValidator.setProperty(LOCALE, fLocale);
3545                 }
3546             }
3547         }
3548         catch (XMLConfigurationException e) {}
3549 
3550         try {
3551             fSchemaParser.setFeature(CONTINUE_AFTER_FATAL_ERROR, fErrorReporter.getFeature(CONTINUE_AFTER_FATAL_ERROR));
3552         } catch (XMLConfigurationException e) {}
3553 
3554         try {
3555             if (componentManager.getFeature(ALLOW_JAVA_ENCODINGS, false)) {
3556                 fSchemaParser.setFeature(ALLOW_JAVA_ENCODINGS, true);
3557             }
3558         } catch (XMLConfigurationException e) {}
3559 
3560         try {
3561             if (componentManager.getFeature(STANDARD_URI_CONFORMANT_FEATURE, false)) {
3562                 fSchemaParser.setFeature(STANDARD_URI_CONFORMANT_FEATURE, true);
3563             }
3564         } catch (XMLConfigurationException e) {}
3565 
3566         try {
3567             fGrammarPool = (XMLGrammarPool) componentManager.getProperty(XMLGRAMMAR_POOL);
3568         } catch (XMLConfigurationException e) {
3569             fGrammarPool = null;
3570         }
3571 
3572         // security features
3573         try {
3574             if (componentManager.getFeature(DISALLOW_DOCTYPE, false)) {
3575                 fSchemaParser.setFeature(DISALLOW_DOCTYPE, true);
3576             }
3577         } catch (XMLConfigurationException e) {}
3578 
3579         try {
3580             if (fSecurityManager != null) {
3581                 fSchemaParser.setProperty(SECURITY_MANAGER, fSecurityManager);
3582             }
3583         } catch (XMLConfigurationException e) {}
3584 
3585         fSecurityPropertyMgr = (XMLSecurityPropertyManager) componentManager.getProperty(XML_SECURITY_PROPERTY_MANAGER);
3586 
3587         //Passing on the setting to the parser
3588         fSchemaParser.setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
3589 
3590         fAccessExternalDTD = fSecurityPropertyMgr.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD);
3591         fAccessExternalSchema = fSecurityPropertyMgr.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA);
3592         fOverrideDefaultParser = componentManager.getFeature(JdkXmlUtils.OVERRIDE_PARSER);
3593         fSchemaParser.setFeature(JdkXmlUtils.OVERRIDE_PARSER, fOverrideDefaultParser);
3594     } // reset(XMLComponentManager)
3595 
3596     /**
3597      * Traverse all the deferred local elements. This method should be called
3598      * by traverseSchemas after we've done with all the global declarations.
3599      */
3600     void traverseLocalElements() {
3601         fElementTraverser.fDeferTraversingLocalElements = false;
3602 
3603         for (int i = 0; i < fLocalElemStackPos; i++) {
3604             Element currElem = fLocalElementDecl[i];
3605             //XSDocumentInfo currSchema = (XSDocumentInfo)fDoc2XSDocumentMap.get(DOMUtil.getDocument(currElem));
3606             //XSDocumentInfo currSchema = (XSDocumentInfo)fDoc2XSDocumentMap.get(DOMUtil.getRoot(DOMUtil.getDocument(currElem)));
3607             XSDocumentInfo currSchema = fLocalElementDecl_schema[i];
3608             SchemaGrammar currGrammar = fGrammarBucket.getGrammar(currSchema.fTargetNamespace);
3609             fElementTraverser.traverseLocal (fParticle[i], currElem, currSchema, currGrammar, fAllContext[i], fParent[i], fLocalElemNamespaceContext[i]);
3610             // If it's an empty particle, remove it from the containing component.
3611             if (fParticle[i].fType == XSParticleDecl.PARTICLE_EMPTY) {
3612                 XSModelGroupImpl group = null;
3613                 if (fParent[i] instanceof XSComplexTypeDecl) {
3614                     XSParticle p = ((XSComplexTypeDecl)fParent[i]).getParticle();
3615                     if (p != null)
3616                         group = (XSModelGroupImpl)p.getTerm();
3617                 }
3618                 else {
3619                     group = ((XSGroupDecl)fParent[i]).fModelGroup;
3620                 }
3621                 if (group != null)
3622                     removeParticle(group, fParticle[i]);
3623             }
3624         }
3625     }
3626 
3627     private boolean removeParticle(XSModelGroupImpl group, XSParticleDecl particle) {
3628         XSParticleDecl member;
3629         for (int i = 0; i < group.fParticleCount; i++) {
3630             member = group.fParticles[i];
3631             if (member == particle) {
3632                 for (int j = i; j < group.fParticleCount-1; j++)
3633                     group.fParticles[j] = group.fParticles[j+1];
3634                 group.fParticleCount--;
3635                 return true;
3636             }
3637             if (member.fType == XSParticleDecl.PARTICLE_MODELGROUP) {
3638                 if (removeParticle((XSModelGroupImpl)member.fValue, particle))
3639                     return true;
3640             }
3641         }
3642         return false;
3643     }
3644 
3645     // the purpose of this method is to keep up-to-date structures
3646     // we'll need for the feferred traversal of local elements.
3647     void fillInLocalElemInfo(Element elmDecl,
3648             XSDocumentInfo schemaDoc,
3649             int allContextFlags,
3650             XSObject parent,
3651             XSParticleDecl particle) {
3652 
3653         // if the stack is full, increase the size
3654         if (fParticle.length == fLocalElemStackPos) {
3655             // increase size
3656             XSParticleDecl[] newStackP = new XSParticleDecl[fLocalElemStackPos+INC_STACK_SIZE];
3657             System.arraycopy(fParticle, 0, newStackP, 0, fLocalElemStackPos);
3658             fParticle = newStackP;
3659             Element[] newStackE = new Element[fLocalElemStackPos+INC_STACK_SIZE];
3660             System.arraycopy(fLocalElementDecl, 0, newStackE, 0, fLocalElemStackPos);
3661             fLocalElementDecl = newStackE;
3662             XSDocumentInfo [] newStackE_schema = new XSDocumentInfo[fLocalElemStackPos+INC_STACK_SIZE];
3663             System.arraycopy(fLocalElementDecl_schema, 0, newStackE_schema, 0, fLocalElemStackPos);
3664             fLocalElementDecl_schema = newStackE_schema;
3665             int[] newStackI = new int[fLocalElemStackPos+INC_STACK_SIZE];
3666             System.arraycopy(fAllContext, 0, newStackI, 0, fLocalElemStackPos);
3667             fAllContext = newStackI;
3668             XSObject[] newStackC = new XSObject[fLocalElemStackPos+INC_STACK_SIZE];
3669             System.arraycopy(fParent, 0, newStackC, 0, fLocalElemStackPos);
3670             fParent = newStackC;
3671             String [][] newStackN = new String [fLocalElemStackPos+INC_STACK_SIZE][];
3672             System.arraycopy(fLocalElemNamespaceContext, 0, newStackN, 0, fLocalElemStackPos);
3673             fLocalElemNamespaceContext = newStackN;
3674         }
3675 
3676         fParticle[fLocalElemStackPos] = particle;
3677         fLocalElementDecl[fLocalElemStackPos] = elmDecl;
3678         fLocalElementDecl_schema[fLocalElemStackPos] = schemaDoc;
3679         fAllContext[fLocalElemStackPos] = allContextFlags;
3680         fParent[fLocalElemStackPos] = parent;
3681         fLocalElemNamespaceContext[fLocalElemStackPos++] = schemaDoc.fNamespaceSupport.getEffectiveLocalContext();
3682     } // end fillInLocalElemInfo(...)
3683 
3684     /** This method makes sure that
3685      * if this component is being redefined that it lives in the
3686      * right schema.  It then renames the component correctly.  If it
3687      * detects a collision--a duplicate definition--then it complains.
3688      * Note that redefines must be handled carefully:  if there
3689      * is a collision, it may be because we're redefining something we know about
3690      * or because we've found the thing we're redefining.
3691      */
3692     void checkForDuplicateNames(String qName, int declType,
3693             Map<String,Element> registry, Map<String,XSDocumentInfo> registry_sub, Element currComp,
3694             XSDocumentInfo currSchema) {
3695         Object objElem = null;
3696         // REVISIT:  when we add derivation checking, we'll have to make
3697         // sure that ID constraint collisions don't necessarily result in error messages.
3698         if ((objElem = registry.get(qName)) == null) {
3699             // need to check whether we have a global declaration in the corresponding
3700             // grammar
3701             if (fNamespaceGrowth && !fTolerateDuplicates) {
3702                 checkForDuplicateNames(qName, declType, currComp);
3703             }
3704             // just add it in!
3705             registry.put(qName, currComp);
3706             registry_sub.put(qName, currSchema);
3707         }
3708         else {
3709             Element collidingElem = (Element)objElem;
3710             XSDocumentInfo collidingElemSchema = (XSDocumentInfo)registry_sub.get(qName);
3711             if (collidingElem == currComp) return;
3712             Element elemParent = null;
3713             XSDocumentInfo redefinedSchema = null;
3714             // case where we've collided with a redefining element
3715             // (the parent of the colliding element is a redefine)
3716             boolean collidedWithRedefine = true;
3717             if ((DOMUtil.getLocalName((elemParent = DOMUtil.getParent(collidingElem))).equals(SchemaSymbols.ELT_REDEFINE))) {
3718                 redefinedSchema = (fRedefine2XSDMap != null)?(XSDocumentInfo) (fRedefine2XSDMap.get(elemParent)): null;
3719                 // case where we're a redefining element.
3720             }
3721             else if ((DOMUtil.getLocalName(DOMUtil.getParent(currComp)).equals(SchemaSymbols.ELT_REDEFINE))) {
3722                 redefinedSchema = collidingElemSchema;
3723                 collidedWithRedefine = false;
3724             }
3725             if (redefinedSchema != null) { //redefinition involved somehow
3726                 // If both components belong to the same document then
3727                 // report an error and return.
3728                 if(collidingElemSchema == currSchema){
3729                     reportSchemaError("sch-props-correct.2", new Object[]{qName}, currComp);
3730                     return;
3731                 }
3732 
3733                 String newName = qName.substring(qName.lastIndexOf(',')+1)+REDEF_IDENTIFIER;
3734                 if (redefinedSchema == currSchema) { // object comp. okay here
3735                     // now have to do some renaming...
3736                     currComp.setAttribute(SchemaSymbols.ATT_NAME, newName);
3737                     if (currSchema.fTargetNamespace == null){
3738                         registry.put(","+newName, currComp);
3739                         registry_sub.put(","+newName, currSchema);
3740                     }
3741                     else{
3742                         registry.put(currSchema.fTargetNamespace+","+newName, currComp);
3743                         registry_sub.put(currSchema.fTargetNamespace+","+newName, currSchema);
3744                     }
3745                     // and take care of nested redefines by calling recursively:
3746                     if (currSchema.fTargetNamespace == null)
3747                         checkForDuplicateNames(","+newName, declType, registry, registry_sub, currComp, currSchema);
3748                     else
3749                         checkForDuplicateNames(currSchema.fTargetNamespace+","+newName, declType, registry, registry_sub, currComp, currSchema);
3750                 }
3751                 else { // we may be redefining the wrong schema
3752                     if (collidedWithRedefine) {
3753                         if (currSchema.fTargetNamespace == null)
3754                             checkForDuplicateNames(","+newName, declType, registry, registry_sub, currComp, currSchema);
3755                         else
3756                             checkForDuplicateNames(currSchema.fTargetNamespace+","+newName, declType, registry, registry_sub, currComp, currSchema);
3757                     }
3758                     else {
3759                         // error that redefined element in wrong schema
3760                         reportSchemaError("sch-props-correct.2", new Object [] {qName}, currComp);
3761                     }
3762                 }
3763             }
3764             else {
3765                 // we've just got a flat-out collision (we tolerate duplicate
3766                 // declarations, only if they are defined in different schema
3767                 // documents)
3768                 if (!fTolerateDuplicates) {
3769                     reportSchemaError("sch-props-correct.2", new Object []{qName}, currComp);
3770                 } else if (fUnparsedRegistriesExt[declType] != null) {
3771                     if (fUnparsedRegistriesExt[declType].get(qName) == currSchema) {
3772                         reportSchemaError("sch-props-correct.2", new Object []{qName}, currComp);
3773                     }
3774                 }
3775             }
3776         }
3777 
3778         // store the lastest current document info
3779         if (fTolerateDuplicates) {
3780             if (fUnparsedRegistriesExt[declType] == null)
3781                 fUnparsedRegistriesExt[declType] = new HashMap();
3782             fUnparsedRegistriesExt[declType].put(qName, currSchema);
3783         }
3784 
3785     } // checkForDuplicateNames(String, Map, Element, XSDocumentInfo):void
3786 
3787     void checkForDuplicateNames(String qName, int declType, Element currComp) {
3788         int namespaceEnd = qName.indexOf(',');
3789         String namespace = qName.substring(0, namespaceEnd);
3790         SchemaGrammar grammar = fGrammarBucket.getGrammar(emptyString2Null(namespace));
3791 
3792         if (grammar != null) {
3793             Object obj = getGlobalDeclFromGrammar(grammar, declType, qName.substring(namespaceEnd + 1));
3794             if (obj != null) {
3795                 reportSchemaError("sch-props-correct.2", new Object []{qName}, currComp);
3796             }
3797         }
3798     }
3799 
3800     // the purpose of this method is to take the component of the
3801     // specified type and rename references to itself so that they
3802     // refer to the object being redefined.  It takes special care of
3803     // <group>s and <attributeGroup>s to ensure that information
3804     // relating to implicit restrictions is preserved for those
3805     // traversers.
3806     private void renameRedefiningComponents(XSDocumentInfo currSchema,
3807             Element child, String componentType,
3808             String oldName, String newName) {
3809         if (componentType.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
3810             Element grandKid = DOMUtil.getFirstChildElement(child);
3811             if (grandKid == null) {
3812                 reportSchemaError("src-redefine.5.a.a", null, child);
3813             }
3814             else {
3815                 String grandKidName = DOMUtil.getLocalName(grandKid);
3816                 if (grandKidName.equals(SchemaSymbols.ELT_ANNOTATION)) {
3817                     grandKid = DOMUtil.getNextSiblingElement(grandKid);
3818                 }
3819                 if (grandKid == null) {
3820                     reportSchemaError("src-redefine.5.a.a", null, child);
3821                 }
3822                 else {
3823                     grandKidName = DOMUtil.getLocalName(grandKid);
3824                     if (!grandKidName.equals(SchemaSymbols.ELT_RESTRICTION)) {
3825                         reportSchemaError("src-redefine.5.a.b", new Object[]{grandKidName}, child);
3826                     }
3827                     else {
3828                         Object[] attrs = fAttributeChecker.checkAttributes(grandKid, false, currSchema);
3829                         QName derivedBase = (QName)attrs[XSAttributeChecker.ATTIDX_BASE];
3830                         if (derivedBase == null ||
3831                                 derivedBase.uri != currSchema.fTargetNamespace ||
3832                                 !derivedBase.localpart.equals(oldName)) {
3833                             reportSchemaError("src-redefine.5.a.c",
3834                                     new Object[]{grandKidName,
3835                                     (currSchema.fTargetNamespace==null?"":currSchema.fTargetNamespace)
3836                                     + "," + oldName},
3837                                     child);
3838                         }
3839                         else {
3840                             // now we have to do the renaming...
3841                             if (derivedBase.prefix != null && derivedBase.prefix.length() > 0)
3842                                 grandKid.setAttribute( SchemaSymbols.ATT_BASE,
3843                                         derivedBase.prefix + ":" + newName );
3844                             else
3845                                 grandKid.setAttribute( SchemaSymbols.ATT_BASE, newName );
3846                             //                            return true;
3847                         }
3848                         fAttributeChecker.returnAttrArray(attrs, currSchema);
3849                     }
3850                 }
3851             }
3852         }
3853         else if (componentType.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
3854             Element grandKid = DOMUtil.getFirstChildElement(child);
3855             if (grandKid == null) {
3856                 reportSchemaError("src-redefine.5.b.a", null, child);
3857             }
3858             else {
3859                 if (DOMUtil.getLocalName(grandKid).equals(SchemaSymbols.ELT_ANNOTATION)) {
3860                     grandKid = DOMUtil.getNextSiblingElement(grandKid);
3861                 }
3862                 if (grandKid == null) {
3863                     reportSchemaError("src-redefine.5.b.a", null, child);
3864                 }
3865                 else {
3866                     // have to go one more level down; let another pass worry whether complexType is valid.
3867                     Element greatGrandKid = DOMUtil.getFirstChildElement(grandKid);
3868                     if (greatGrandKid == null) {
3869                         reportSchemaError("src-redefine.5.b.b", null, grandKid);
3870                     }
3871                     else {
3872                         String greatGrandKidName = DOMUtil.getLocalName(greatGrandKid);
3873                         if (greatGrandKidName.equals(SchemaSymbols.ELT_ANNOTATION)) {
3874                             greatGrandKid = DOMUtil.getNextSiblingElement(greatGrandKid);
3875                         }
3876                         if (greatGrandKid == null) {
3877                             reportSchemaError("src-redefine.5.b.b", null, grandKid);
3878                         }
3879                         else {
3880                             greatGrandKidName = DOMUtil.getLocalName(greatGrandKid);
3881                             if (!greatGrandKidName.equals(SchemaSymbols.ELT_RESTRICTION) &&
3882                                     !greatGrandKidName.equals(SchemaSymbols.ELT_EXTENSION)) {
3883                                 reportSchemaError("src-redefine.5.b.c", new Object[]{greatGrandKidName}, greatGrandKid);
3884                             }
3885                             else {
3886                                 Object[] attrs = fAttributeChecker.checkAttributes(greatGrandKid, false, currSchema);
3887                                 QName derivedBase = (QName)attrs[XSAttributeChecker.ATTIDX_BASE];
3888                                 if (derivedBase == null ||
3889                                         derivedBase.uri != currSchema.fTargetNamespace ||
3890                                         !derivedBase.localpart.equals(oldName)) {
3891                                     reportSchemaError("src-redefine.5.b.d",
3892                                             new Object[]{greatGrandKidName,
3893                                             (currSchema.fTargetNamespace==null?"":currSchema.fTargetNamespace)
3894                                             + "," + oldName},
3895                                             greatGrandKid);
3896                                 }
3897                                 else {
3898                                     // now we have to do the renaming...
3899                                     if (derivedBase.prefix != null && derivedBase.prefix.length() > 0)
3900                                         greatGrandKid.setAttribute( SchemaSymbols.ATT_BASE,
3901                                                 derivedBase.prefix + ":" + newName );
3902                                     else
3903                                         greatGrandKid.setAttribute( SchemaSymbols.ATT_BASE,
3904                                                 newName );
3905                                     //                                    return true;
3906                                 }
3907                             }
3908                         }
3909                     }
3910                 }
3911             }
3912         }
3913         else if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
3914             String processedBaseName = (currSchema.fTargetNamespace == null)?
3915                     ","+oldName:currSchema.fTargetNamespace+","+oldName;
3916             int attGroupRefsCount = changeRedefineGroup(processedBaseName, componentType, newName, child, currSchema);
3917             if (attGroupRefsCount > 1) {
3918                 reportSchemaError("src-redefine.7.1", new Object []{new Integer(attGroupRefsCount)}, child);
3919             }
3920             else if (attGroupRefsCount == 1) {
3921                 //                return true;
3922             }
3923             else
3924                 if (currSchema.fTargetNamespace == null)
3925                     fRedefinedRestrictedAttributeGroupRegistry.put(processedBaseName, ","+newName);
3926                 else
3927                     fRedefinedRestrictedAttributeGroupRegistry.put(processedBaseName, currSchema.fTargetNamespace+","+newName);
3928         }
3929         else if (componentType.equals(SchemaSymbols.ELT_GROUP)) {
3930             String processedBaseName = (currSchema.fTargetNamespace == null)?
3931                     ","+oldName:currSchema.fTargetNamespace+","+oldName;
3932             int groupRefsCount = changeRedefineGroup(processedBaseName, componentType, newName, child, currSchema);
3933             if (groupRefsCount > 1) {
3934                 reportSchemaError("src-redefine.6.1.1", new Object []{new Integer(groupRefsCount)}, child);
3935             }
3936             else if (groupRefsCount == 1) {
3937                 //                return true;
3938             }
3939             else {
3940                 if (currSchema.fTargetNamespace == null)
3941                     fRedefinedRestrictedGroupRegistry.put(processedBaseName, ","+newName);
3942                 else
3943                     fRedefinedRestrictedGroupRegistry.put(processedBaseName, currSchema.fTargetNamespace+","+newName);
3944             }
3945         }
3946         else {
3947             reportSchemaError("Internal-Error", new Object [] {"could not handle this particular <redefine>; please submit your schemas and instance document in a bug report!"}, child);
3948         }
3949         // if we get here then we must have reported an error and failed somewhere...
3950         //        return false;
3951     } // renameRedefiningComponents(XSDocumentInfo, Element, String, String, String):void
3952 
3953     // this method takes a name of the form a:b, determines the URI mapped
3954     // to by a in the current SchemaNamespaceSupport object, and returns this
3955     // information in the form (nsURI,b) suitable for lookups in the global
3956     // decl maps.
3957     // REVISIT: should have it return QName, instead of String. this would
3958     //          save lots of string concatenation time. we can use
3959     //          QName#equals() to compare two QNames, and use QName directly
3960     //          as a key to the SymbolHash.
3961     //          And when the DV's are ready to return compiled values from
3962     //          validate() method, we should just call QNameDV.validate()
3963     //          in this method.
3964     private String findQName(String name, XSDocumentInfo schemaDoc) {
3965         SchemaNamespaceSupport currNSMap = schemaDoc.fNamespaceSupport;
3966         int colonPtr = name.indexOf(':');
3967         String prefix = XMLSymbols.EMPTY_STRING;
3968         if (colonPtr > 0)
3969             prefix = name.substring(0, colonPtr);
3970         String uri = currNSMap.getURI(fSymbolTable.addSymbol(prefix));
3971         String localpart = (colonPtr == 0)?name:name.substring(colonPtr+1);
3972         if (prefix == XMLSymbols.EMPTY_STRING && uri == null && schemaDoc.fIsChameleonSchema)
3973             uri = schemaDoc.fTargetNamespace;
3974         if (uri == null)
3975             return ","+localpart;
3976         return uri+","+localpart;
3977     } // findQName(String, XSDocumentInfo):  String
3978 
3979     // This function looks among the children of curr for an element of type elementSought.
3980     // If it finds one, it evaluates whether its ref attribute contains a reference
3981     // to originalQName.  If it does, it returns 1 + the value returned by
3982     // calls to itself on all other children.  In all other cases it returns 0 plus
3983     // the sum of the values returned by calls to itself on curr's children.
3984     // It also resets the value of ref so that it will refer to the renamed type from the schema
3985     // being redefined.
3986     private int changeRedefineGroup(String originalQName, String elementSought,
3987             String newName, Element curr, XSDocumentInfo schemaDoc) {
3988         int result = 0;
3989         for (Element child = DOMUtil.getFirstChildElement(curr);
3990         child != null; child = DOMUtil.getNextSiblingElement(child)) {
3991             String name = DOMUtil.getLocalName(child);
3992             if (!name.equals(elementSought))
3993                 result += changeRedefineGroup(originalQName, elementSought, newName, child, schemaDoc);
3994             else {
3995                 String ref = child.getAttribute( SchemaSymbols.ATT_REF );
3996                 if (ref.length() != 0) {
3997                     String processedRef = findQName(ref, schemaDoc);
3998                     if (originalQName.equals(processedRef)) {
3999                         String prefix = XMLSymbols.EMPTY_STRING;
4000                         int colonptr = ref.indexOf(":");
4001                         if (colonptr > 0) {
4002                             prefix = ref.substring(0,colonptr);
4003                             child.setAttribute(SchemaSymbols.ATT_REF, prefix + ":" + newName);
4004                         }
4005                         else
4006                             child.setAttribute(SchemaSymbols.ATT_REF, newName);
4007                         result++;
4008                         if (elementSought.equals(SchemaSymbols.ELT_GROUP)) {
4009                             String minOccurs = child.getAttribute( SchemaSymbols.ATT_MINOCCURS );
4010                             String maxOccurs = child.getAttribute( SchemaSymbols.ATT_MAXOCCURS );
4011                             if (!((maxOccurs.length() == 0 || maxOccurs.equals("1"))
4012                                     && (minOccurs.length() == 0 || minOccurs.equals("1")))) {
4013                                 reportSchemaError("src-redefine.6.1.2", new Object [] {ref}, child);
4014                             }
4015                         }
4016                     }
4017                 } // if ref was null some other stage of processing will flag the error
4018             }
4019         }
4020         return result;
4021     } // changeRedefineGroup
4022 
4023     // this method returns the XSDocumentInfo object that contains the
4024     // component corresponding to decl.  If components from this
4025     // document cannot be referred to from those of currSchema, this
4026     // method returns null; it's up to the caller to throw an error.
4027     // @param:  currSchema:  the XSDocumentInfo object containing the
4028     // decl ref'ing us.
4029     // @param:  decl:  the declaration being ref'd.
4030     // this method is superficial now. ---Jack
4031     private XSDocumentInfo findXSDocumentForDecl(XSDocumentInfo currSchema,
4032             Element decl, XSDocumentInfo decl_Doc) {
4033 
4034         if (DEBUG_NODE_POOL) {
4035             System.out.println("DOCUMENT NS:"+ currSchema.fTargetNamespace+" hashcode:"+ ((Object)currSchema.fSchemaElement).hashCode());
4036         }
4037         Object temp = decl_Doc;
4038         if (temp == null) {
4039             // something went badly wrong; we don't know this doc?
4040             return null;
4041         }
4042         XSDocumentInfo declDocInfo = (XSDocumentInfo)temp;
4043         return declDocInfo;
4044         /*********
4045          Logic here is unnecessary after schema WG's recent decision to allow
4046          schema components from one document to refer to components of any other,
4047          so long as there's some include/import/redefine path amongst them.
4048          If they rver reverse this decision the code's right here though...  - neilg
4049          // now look in fDependencyMap to see if this is reachable
4050           if((fDependencyMap.get(currSchema)).contains(declDocInfo)) {
4051           return declDocInfo;
4052           }
4053           // obviously the requesting doc didn't include, redefine or
4054            // import the one containing decl...
4055             return null;
4056             **********/
4057     } // findXSDocumentForDecl(XSDocumentInfo, Element):  XSDocumentInfo
4058 
4059     // returns whether more than <annotation>s occur in children of elem
4060     private boolean nonAnnotationContent(Element elem) {
4061         for(Element child = DOMUtil.getFirstChildElement(elem); child != null; child = DOMUtil.getNextSiblingElement(child)) {
4062             if(!(DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION))) return true;
4063         }
4064         return false;
4065     } // nonAnnotationContent(Element):  boolean
4066 
4067     private void setSchemasVisible(XSDocumentInfo startSchema) {
4068         if (DOMUtil.isHidden(startSchema.fSchemaElement, fHiddenNodes)) {
4069             // make it visible
4070             DOMUtil.setVisible(startSchema.fSchemaElement, fHiddenNodes);
4071             Vector<XSDocumentInfo> dependingSchemas = fDependencyMap.get(startSchema);
4072             for (int i = 0; i < dependingSchemas.size(); i++) {
4073                 setSchemasVisible(dependingSchemas.elementAt(i));
4074             }
4075         }
4076         // if it's visible already than so must be its children
4077     } // setSchemasVisible(XSDocumentInfo): void
4078 
4079     private SimpleLocator xl = new SimpleLocator();
4080 
4081     /**
4082      * Extract location information from an Element node, and create a
4083      * new SimpleLocator object from such information. Returning null means
4084      * no information can be retrieved from the element.
4085      */
4086     public SimpleLocator element2Locator(Element e) {
4087         if (!( e instanceof ElementImpl))
4088             return null;
4089 
4090         SimpleLocator l = new SimpleLocator();
4091         return element2Locator(e, l) ? l : null;
4092     }
4093 
4094     /**
4095      * Extract location information from an Element node, store such
4096      * information in the passed-in SimpleLocator object, then return
4097      * true. Returning false means can't extract or store such information.
4098      */
4099     public boolean element2Locator(Element e, SimpleLocator l) {
4100         if (l == null)
4101             return false;
4102         if (e instanceof ElementImpl) {
4103             ElementImpl ele = (ElementImpl)e;
4104             // get system id from document object
4105             Document doc = ele.getOwnerDocument();
4106             String sid = fDoc2SystemId.get(DOMUtil.getRoot(doc));
4107             // line/column numbers are stored in the element node
4108             int line = ele.getLineNumber();
4109             int column = ele.getColumnNumber();
4110             l.setValues(sid, sid, line, column, ele.getCharacterOffset());
4111             return true;
4112         }
4113         return false;
4114     }
4115 
4116     private Element getElementFromMap(Map<String, Element> registry, String declKey) {
4117         if (registry == null) return null;
4118         return registry.get(declKey);
4119     }
4120 
4121     private XSDocumentInfo getDocInfoFromMap(Map<String, XSDocumentInfo> registry, String declKey) {
4122         if (registry == null) return null;
4123         return registry.get(declKey);
4124     }
4125 
4126     private Object getFromMap(Map registry, String key) {
4127         if (registry == null) return null;
4128         return registry.get(key);
4129     }
4130 
4131     void reportSchemaFatalError(String key, Object[] args, Element ele) {
4132         reportSchemaErr(key, args, ele, XMLErrorReporter.SEVERITY_FATAL_ERROR, null);
4133     }
4134 
4135     void reportSchemaError(String key, Object[] args, Element ele) {
4136         reportSchemaErr(key, args, ele, XMLErrorReporter.SEVERITY_ERROR, null);
4137     }
4138 
4139     void reportSchemaError(String key, Object[] args, Element ele, Exception exception) {
4140         reportSchemaErr(key, args, ele, XMLErrorReporter.SEVERITY_ERROR, exception);
4141     }
4142 
4143     void reportSchemaWarning(String key, Object[] args, Element ele) {
4144         reportSchemaErr(key, args, ele, XMLErrorReporter.SEVERITY_WARNING, null);
4145     }
4146 
4147     void reportSchemaWarning(String key, Object[] args, Element ele, Exception exception) {
4148         reportSchemaErr(key, args, ele, XMLErrorReporter.SEVERITY_WARNING, exception);
4149     }
4150 
4151     void reportSchemaErr(String key, Object[] args, Element ele, short type, Exception exception) {
4152         if (element2Locator(ele, xl)) {
4153             fErrorReporter.reportError(xl, XSMessageFormatter.SCHEMA_DOMAIN,
4154                     key, args, type, exception);
4155         }
4156         else {
4157             fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
4158                     key, args, type, exception);
4159         }
4160     }
4161 
4162     /**
4163      * Grammar pool used for validating annotations. This will return all of the
4164      * grammars from the grammar bucket. It will also return an object for the
4165      * schema for schemas which will contain at least the relevant declarations
4166      * for annotations.
4167      */
4168     private static class XSAnnotationGrammarPool implements XMLGrammarPool {
4169 
4170         private XSGrammarBucket fGrammarBucket;
4171         private Grammar [] fInitialGrammarSet;
4172 
4173         public Grammar[] retrieveInitialGrammarSet(String grammarType) {
4174             if (grammarType == XMLGrammarDescription.XML_SCHEMA) {
4175                 if (fInitialGrammarSet == null) {
4176                     if (fGrammarBucket == null) {
4177                         fInitialGrammarSet = new Grammar [] {SchemaGrammar.Schema4Annotations.INSTANCE};
4178                     }
4179                     else {
4180                         SchemaGrammar [] schemaGrammars = fGrammarBucket.getGrammars();
4181                         /**
4182                          * If the grammar bucket already contains the schema for schemas
4183                          * then we already have the definitions for the parts relevant
4184                          * to annotations.
4185                          */
4186                         for (int i = 0; i < schemaGrammars.length; ++i) {
4187                             if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(schemaGrammars[i].getTargetNamespace())) {
4188                                 fInitialGrammarSet = schemaGrammars;
4189                                 return fInitialGrammarSet;
4190                             }
4191                         }
4192                         Grammar [] grammars = new Grammar[schemaGrammars.length + 1];
4193                         System.arraycopy(schemaGrammars, 0, grammars, 0, schemaGrammars.length);
4194                         grammars[grammars.length - 1] = SchemaGrammar.Schema4Annotations.INSTANCE;
4195                         fInitialGrammarSet = grammars;
4196                     }
4197                 }
4198                 return fInitialGrammarSet;
4199             }
4200             return new Grammar[0];
4201         }
4202 
4203         public void cacheGrammars(String grammarType, Grammar[] grammars) {
4204 
4205         }
4206 
4207         public Grammar retrieveGrammar(XMLGrammarDescription desc) {
4208             if (desc.getGrammarType() == XMLGrammarDescription.XML_SCHEMA) {
4209                 final String tns = ((XMLSchemaDescription) desc).getTargetNamespace();
4210                 if (fGrammarBucket != null) {
4211                     Grammar grammar = fGrammarBucket.getGrammar(tns);
4212                     if (grammar != null) {
4213                         return grammar;
4214                     }
4215                 }
4216                 if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(tns)) {
4217                     return SchemaGrammar.Schema4Annotations.INSTANCE;
4218                 }
4219             }
4220             return null;
4221         }
4222 
4223         public void refreshGrammars(XSGrammarBucket gBucket) {
4224             fGrammarBucket = gBucket;
4225             fInitialGrammarSet = null;
4226         }
4227 
4228         public void lockPool() {}
4229 
4230         public void unlockPool() {}
4231 
4232         public void clear() {}
4233     }
4234 
4235     /**
4236      * used to identify a reference to a schema document
4237      * if the same document is referenced twice with the same key, then
4238      * we only need to parse it once.
4239      *
4240      * When 2 XSDKey's are compared, the following table can be used to
4241      * determine whether they are equal:
4242      *      inc     red     imp     pre     ins
4243      * inc  N/L      ?      N/L     N/L     N/L
4244      * red   ?      N/L      ?       ?       ?
4245      * imp  N/L      ?      N/P     N/P     N/P
4246      * pre  N/L      ?      N/P     N/P     N/P
4247      * ins  N/L      ?      N/P     N/P     N/P
4248      *
4249      * Where: N/L: duplicate when they have the same namespace and location.
4250      *         ? : not clear from the spec.
4251      *             REVISIT: to simplify the process, also considering
4252      *             it's very rare, we treat them as not duplicate.
4253      *        N/P: not possible. imp/pre/ins are referenced by namespace.
4254      *             when the first time we encounter a schema document for a
4255      *             namespace, we create a grammar and store it in the grammar
4256      *             bucket. when we see another reference to the same namespace,
4257      *             we first check whether a grammar with the same namespace is
4258      *             already in the bucket, which is true in this case, so we
4259      *             won't create another XSDKey.
4260      *
4261      * Conclusion from the table: two XSDKey's are duplicate only when all of
4262      * the following are true:
4263      * 1. They are both "redefine", or neither is "redefine";
4264      * 2. They have the same namespace;
4265      * 3. They have the same non-null location.
4266      *
4267      * About 3: if neither has a non-null location, then it's the case where
4268      * 2 input streams are provided, but no system ID is provided. We can't tell
4269      * whether the 2 streams have the same content, so we treat them as not
4270      * duplicate.
4271      */
4272     private static class XSDKey {
4273         String systemId;
4274         short  referType;
4275         // for inclue/redefine, this is the enclosing namespace
4276         // for import/preparse/instance, this is the target namespace
4277         String referNS;
4278 
4279         XSDKey(String systemId, short referType, String referNS) {
4280             this.systemId = systemId;
4281             this.referType = referType;
4282             this.referNS = referNS;
4283         }
4284 
4285         public int hashCode() {
4286             // according to the description at the beginning of this class,
4287             // we use the hashcode of the namespace as the hashcoe of this key.
4288             return referNS == null ? 0 : referNS.hashCode();
4289         }
4290 
4291         public boolean equals(Object obj) {
4292             if (!(obj instanceof XSDKey)) {
4293                 return false;
4294             }
4295             XSDKey key = (XSDKey)obj;
4296 
4297             // condition 1: both are redefine
4298             /** if (referType == XSDDescription.CONTEXT_REDEFINE ||
4299                     key.referType == XSDDescription.CONTEXT_REDEFINE) {
4300                 if (referType != key.referType)
4301                     return false;
4302             }**/
4303 
4304             // condition 2: same namespace
4305             if (referNS != key.referNS)
4306                 return false;
4307 
4308             // condition 3: same non-null location
4309             if (systemId == null || !systemId.equals(key.systemId)) {
4310                 return false;
4311             }
4312 
4313             return true;
4314         }
4315     }
4316 
4317     private static final class SAX2XNIUtil extends ErrorHandlerWrapper {
4318         public static XMLParseException createXMLParseException0(SAXParseException exception) {
4319             return createXMLParseException(exception);
4320         }
4321         public static XNIException createXNIException0(SAXException exception) {
4322             return createXNIException(exception);
4323         }
4324     }
4325 
4326     /**
4327      * @param state
4328      */
4329     public void setGenerateSyntheticAnnotations(boolean state) {
4330         fSchemaParser.setFeature(GENERATE_SYNTHETIC_ANNOTATIONS, state);
4331     }
4332 
4333 } // XSDHandler