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