Source Code Cross Referenced for XSDHandler.java in  » XML » xerces-2_9_1 » org » apache » xerces » impl » xs » traversers » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML » xerces 2_9_1 » org.apache.xerces.impl.xs.traversers 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         *
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:
0018:        package org.apache.xerces.impl.xs.traversers;
0019:
0020:        import java.io.IOException;
0021:        import java.io.StringReader;
0022:        import java.util.ArrayList;
0023:        import java.util.Hashtable;
0024:        import java.util.Stack;
0025:        import java.util.Vector;
0026:
0027:        import org.apache.xerces.impl.Constants;
0028:        import org.apache.xerces.impl.XMLEntityManager;
0029:        import org.apache.xerces.impl.XMLErrorReporter;
0030:        import org.apache.xerces.impl.xs.SchemaGrammar;
0031:        import org.apache.xerces.impl.xs.SchemaNamespaceSupport;
0032:        import org.apache.xerces.impl.xs.SchemaSymbols;
0033:        import org.apache.xerces.impl.xs.XMLSchemaException;
0034:        import org.apache.xerces.impl.xs.XMLSchemaLoader;
0035:        import org.apache.xerces.impl.xs.XSComplexTypeDecl;
0036:        import org.apache.xerces.impl.xs.XSDDescription;
0037:        import org.apache.xerces.impl.xs.XSDeclarationPool;
0038:        import org.apache.xerces.impl.xs.XSElementDecl;
0039:        import org.apache.xerces.impl.xs.XSGrammarBucket;
0040:        import org.apache.xerces.impl.xs.XSGroupDecl;
0041:        import org.apache.xerces.impl.xs.XSMessageFormatter;
0042:        import org.apache.xerces.impl.xs.XSModelGroupImpl;
0043:        import org.apache.xerces.impl.xs.XSParticleDecl;
0044:        import org.apache.xerces.impl.xs.opti.ElementImpl;
0045:        import org.apache.xerces.impl.xs.opti.SchemaDOMParser;
0046:        import org.apache.xerces.impl.xs.opti.SchemaParsingConfig;
0047:        import org.apache.xerces.impl.xs.util.SimpleLocator;
0048:
0049:        import org.apache.xerces.util.DOMUtil;
0050:        import org.apache.xerces.parsers.SAXParser;
0051:        import org.apache.xerces.parsers.XML11Configuration;
0052:        import org.apache.xerces.util.DOMInputSource;
0053:        import org.apache.xerces.util.DefaultErrorHandler;
0054:        import org.apache.xerces.util.SAXInputSource;
0055:        import org.apache.xerces.util.SymbolTable;
0056:        import org.apache.xerces.util.XMLSymbols;
0057:        import org.apache.xerces.util.URI.MalformedURIException;
0058:        import org.apache.xerces.xni.QName;
0059:        import org.apache.xerces.xni.grammars.Grammar;
0060:        import org.apache.xerces.xni.grammars.XMLGrammarDescription;
0061:        import org.apache.xerces.xni.grammars.XMLGrammarPool;
0062:        import org.apache.xerces.xni.grammars.XMLSchemaDescription;
0063:        import org.apache.xerces.xni.parser.XMLComponentManager;
0064:        import org.apache.xerces.xni.parser.XMLConfigurationException;
0065:        import org.apache.xerces.xni.parser.XMLEntityResolver;
0066:        import org.apache.xerces.xni.parser.XMLErrorHandler;
0067:        import org.apache.xerces.xni.parser.XMLInputSource;
0068:        import org.apache.xerces.xs.XSObject;
0069:        import org.apache.xerces.xs.XSParticle;
0070:        import org.w3c.dom.Document;
0071:        import org.w3c.dom.Element;
0072:        import org.w3c.dom.Node;
0073:        import org.xml.sax.InputSource;
0074:        import org.xml.sax.SAXException;
0075:        import org.xml.sax.XMLReader;
0076:        import org.xml.sax.helpers.XMLReaderFactory;
0077:
0078:        /**
0079:         * The purpose of this class is to co-ordinate the construction of a
0080:         * grammar object corresponding to a schema.  To do this, it must be
0081:         * prepared to parse several schema documents (for instance if the
0082:         * schema document originally referred to contains <include> or
0083:         * <redefined> information items).  If any of the schemas imports a
0084:         * schema, other grammars may be constructed as a side-effect.
0085:         *
0086:         * @xerces.internal 
0087:         *
0088:         * @author Neil Graham, IBM
0089:         * @author Pavani Mukthipudi, Sun Microsystems
0090:         * 
0091:         * @version $Id: XSDHandler.java 449487 2006-09-24 21:11:28Z mrglavas $
0092:         */
0093:        public class XSDHandler {
0094:
0095:            /** Feature identifier: validation. */
0096:            protected static final String VALIDATION = Constants.SAX_FEATURE_PREFIX
0097:                    + Constants.VALIDATION_FEATURE;
0098:
0099:            /** feature identifier: XML Schema validation */
0100:            protected static final String XMLSCHEMA_VALIDATION = Constants.XERCES_FEATURE_PREFIX
0101:                    + Constants.SCHEMA_VALIDATION_FEATURE;
0102:
0103:            /** Feature identifier:  allow java encodings */
0104:            protected static final String ALLOW_JAVA_ENCODINGS = Constants.XERCES_FEATURE_PREFIX
0105:                    + Constants.ALLOW_JAVA_ENCODINGS_FEATURE;
0106:
0107:            /** Feature identifier:  continue after fatal error */
0108:            protected static final String CONTINUE_AFTER_FATAL_ERROR = Constants.XERCES_FEATURE_PREFIX
0109:                    + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE;
0110:
0111:            /** Feature identifier:  allow java encodings */
0112:            protected static final String STANDARD_URI_CONFORMANT_FEATURE = Constants.XERCES_FEATURE_PREFIX
0113:                    + Constants.STANDARD_URI_CONFORMANT_FEATURE;
0114:
0115:            /** Feature: disallow doctype*/
0116:            protected static final String DISALLOW_DOCTYPE = Constants.XERCES_FEATURE_PREFIX
0117:                    + Constants.DISALLOW_DOCTYPE_DECL_FEATURE;
0118:
0119:            /** Feature: generate synthetic annotations */
0120:            protected static final String GENERATE_SYNTHETIC_ANNOTATIONS = Constants.XERCES_FEATURE_PREFIX
0121:                    + Constants.GENERATE_SYNTHETIC_ANNOTATIONS_FEATURE;
0122:
0123:            /** Feature identifier: validate annotations. */
0124:            protected static final String VALIDATE_ANNOTATIONS = Constants.XERCES_FEATURE_PREFIX
0125:                    + Constants.VALIDATE_ANNOTATIONS_FEATURE;
0126:
0127:            /** Feature identifier: honour all schemaLocations */
0128:            protected static final String HONOUR_ALL_SCHEMALOCATIONS = Constants.XERCES_FEATURE_PREFIX
0129:                    + Constants.HONOUR_ALL_SCHEMALOCATIONS_FEATURE;
0130:
0131:            /** Feature identifier: namespace prefixes. */
0132:            private static final String NAMESPACE_PREFIXES = Constants.SAX_FEATURE_PREFIX
0133:                    + Constants.NAMESPACE_PREFIXES_FEATURE;
0134:
0135:            /** Feature identifier: string interning. */
0136:            protected static final String STRING_INTERNING = Constants.SAX_FEATURE_PREFIX
0137:                    + Constants.STRING_INTERNING_FEATURE;
0138:
0139:            /** Property identifier: error handler. */
0140:            protected static final String ERROR_HANDLER = Constants.XERCES_PROPERTY_PREFIX
0141:                    + Constants.ERROR_HANDLER_PROPERTY;
0142:
0143:            /** Property identifier: JAXP schema source. */
0144:            protected static final String JAXP_SCHEMA_SOURCE = Constants.JAXP_PROPERTY_PREFIX
0145:                    + Constants.SCHEMA_SOURCE;
0146:
0147:            /** Property identifier: entity resolver. */
0148:            public static final String ENTITY_RESOLVER = Constants.XERCES_PROPERTY_PREFIX
0149:                    + Constants.ENTITY_RESOLVER_PROPERTY;
0150:            /** Property identifier: entity manager. */
0151:            protected static final String ENTITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX
0152:                    + Constants.ENTITY_MANAGER_PROPERTY;
0153:
0154:            /** Property identifier: error reporter. */
0155:            public static final String ERROR_REPORTER = Constants.XERCES_PROPERTY_PREFIX
0156:                    + Constants.ERROR_REPORTER_PROPERTY;
0157:
0158:            /** Property identifier: grammar pool. */
0159:            public static final String XMLGRAMMAR_POOL = Constants.XERCES_PROPERTY_PREFIX
0160:                    + Constants.XMLGRAMMAR_POOL_PROPERTY;
0161:
0162:            /** Property identifier: symbol table. */
0163:            public static final String SYMBOL_TABLE = Constants.XERCES_PROPERTY_PREFIX
0164:                    + Constants.SYMBOL_TABLE_PROPERTY;
0165:
0166:            /** Property identifier: security manager. */
0167:            protected static final String SECURITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX
0168:                    + Constants.SECURITY_MANAGER_PROPERTY;
0169:
0170:            protected static final boolean DEBUG_NODE_POOL = false;
0171:
0172:            // Data
0173:
0174:            // different sorts of declarations; should make lookup and
0175:            // traverser calling more efficient/less bulky.
0176:            final static int ATTRIBUTE_TYPE = 1;
0177:            final static int ATTRIBUTEGROUP_TYPE = 2;
0178:            final static int ELEMENT_TYPE = 3;
0179:            final static int GROUP_TYPE = 4;
0180:            final static int IDENTITYCONSTRAINT_TYPE = 5;
0181:            final static int NOTATION_TYPE = 6;
0182:            final static int TYPEDECL_TYPE = 7;
0183:
0184:            // this string gets appended to redefined names; it's purpose is to be
0185:            // as unlikely as possible to cause collisions.
0186:            public final static String REDEF_IDENTIFIER = "_fn3dktizrknc9pi";
0187:
0188:            //
0189:            //protected data that can be accessable by any traverser
0190:            // stores <notation> decl
0191:            protected Hashtable fNotationRegistry = new Hashtable();
0192:
0193:            protected XSDeclarationPool fDeclPool = null;
0194:
0195:            // These tables correspond to the symbol spaces defined in the
0196:            // spec.
0197:            // They are keyed with a QName (that is, String("URI,localpart) and
0198:            // their values are nodes corresponding to the given name's decl.
0199:            // By asking the node for its ownerDocument and looking in
0200:            // XSDocumentInfoRegistry we can easily get the corresponding
0201:            // XSDocumentInfo object.
0202:            private Hashtable fUnparsedAttributeRegistry = new Hashtable();
0203:            private Hashtable fUnparsedAttributeGroupRegistry = new Hashtable();
0204:            private Hashtable fUnparsedElementRegistry = new Hashtable();
0205:            private Hashtable fUnparsedGroupRegistry = new Hashtable();
0206:            private Hashtable fUnparsedIdentityConstraintRegistry = new Hashtable();
0207:            private Hashtable fUnparsedNotationRegistry = new Hashtable();
0208:            private Hashtable fUnparsedTypeRegistry = new Hashtable();
0209:            // Compensation for the above hashtables to locate XSDocumentInfo, 
0210:            // Since we may take Schema Element directly, so can not get the
0211:            // corresponding XSDocumentInfo object just using above hashtables.
0212:            private Hashtable fUnparsedAttributeRegistrySub = new Hashtable();
0213:            private Hashtable fUnparsedAttributeGroupRegistrySub = new Hashtable();
0214:            private Hashtable fUnparsedElementRegistrySub = new Hashtable();
0215:            private Hashtable fUnparsedGroupRegistrySub = new Hashtable();
0216:            private Hashtable fUnparsedIdentityConstraintRegistrySub = new Hashtable();
0217:            private Hashtable fUnparsedNotationRegistrySub = new Hashtable();
0218:            private Hashtable fUnparsedTypeRegistrySub = new Hashtable();
0219:
0220:            // this is keyed with a documentNode (or the schemaRoot nodes
0221:            // contained in the XSDocumentInfo objects) and its value is the
0222:            // XSDocumentInfo object corresponding to that document.
0223:            // Basically, the function of this registry is to be a link
0224:            // between the nodes we fetch from calls to the fUnparsed*
0225:            // arrays and the XSDocumentInfos they live in.
0226:            private Hashtable fXSDocumentInfoRegistry = new Hashtable();
0227:
0228:            // this hashtable is keyed on by XSDocumentInfo objects.  Its values
0229:            // are Vectors containing the XSDocumentInfo objects <include>d,
0230:            // <import>ed or <redefine>d by the key XSDocumentInfo.
0231:            private Hashtable fDependencyMap = new Hashtable();
0232:
0233:            // this hashtable is keyed on by a target namespace.  Its values
0234:            // are Vectors containing namespaces imported by schema documents
0235:            // with the key target namespace.
0236:            // if an imprted schema has absent namespace, the value "null" is stored.
0237:            private Hashtable fImportMap = new Hashtable();
0238:            // all namespaces that imports other namespaces
0239:            // if the importing schema has absent namespace, empty string is stored.
0240:            // (because the key of a hashtable can't be null.)
0241:            private Vector fAllTNSs = new Vector();
0242:            // stores instance document mappings between namespaces and schema hints
0243:            private Hashtable fLocationPairs = null;
0244:            private static final Hashtable EMPTY_TABLE = new Hashtable();
0245:
0246:            // Records which nodes are hidden when the input is a DOMInputSource.
0247:            Hashtable fHiddenNodes = null;
0248:
0249:            // convenience methods
0250:            private String null2EmptyString(String ns) {
0251:                return ns == null ? XMLSymbols.EMPTY_STRING : ns;
0252:            }
0253:
0254:            private String emptyString2Null(String ns) {
0255:                return ns == XMLSymbols.EMPTY_STRING ? null : ns;
0256:            }
0257:
0258:            // use Schema Element to lookup the SystemId.
0259:            private String doc2SystemId(Element ele) {
0260:                String documentURI = null;
0261:                /**
0262:                 * REVISIT: Casting until DOM Level 3 interfaces are available. -- mrglavas
0263:                 */
0264:                if (ele.getOwnerDocument() instanceof  org.apache.xerces.impl.xs.opti.SchemaDOM) {
0265:                    documentURI = ((org.apache.xerces.impl.xs.opti.SchemaDOM) ele
0266:                            .getOwnerDocument()).getDocumentURI();
0267:                }
0268:                return documentURI != null ? documentURI
0269:                        : (String) fDoc2SystemId.get(ele);
0270:            }
0271:
0272:            // This vector stores strings which are combinations of the
0273:            // publicId and systemId of the inputSource corresponding to a
0274:            // schema document.  This combination is used so that the user's
0275:            // EntityResolver can provide a consistent way of identifying a
0276:            // schema document that is included in multiple other schemas.
0277:            private Hashtable fTraversed = new Hashtable();
0278:
0279:            // this hashtable contains a mapping from Schema Element to its systemId
0280:            // this is useful to resolve a uri relative to the referring document
0281:            private Hashtable fDoc2SystemId = new Hashtable();
0282:
0283:            // the primary XSDocumentInfo we were called to parse
0284:            private XSDocumentInfo fRoot = null;
0285:
0286:            // This hashtable's job is to act as a link between the Schema Element and its
0287:            // XSDocumentInfo object.
0288:            private Hashtable fDoc2XSDocumentMap = new Hashtable();
0289:
0290:            // map between <redefine> elements and the XSDocumentInfo
0291:            // objects that correspond to the documents being redefined.
0292:            private Hashtable fRedefine2XSDMap = new Hashtable();
0293:
0294:            // map between <redefine> elements and the namespace support
0295:            private Hashtable fRedefine2NSSupport = new Hashtable();
0296:
0297:            // these objects store a mapping between the names of redefining
0298:            // groups/attributeGroups and the groups/AttributeGroups which
0299:            // they redefine by restriction (implicitly).  It is up to the
0300:            // Group and AttributeGroup traversers to check these restrictions for
0301:            // validity.
0302:            private Hashtable fRedefinedRestrictedAttributeGroupRegistry = new Hashtable();
0303:            private Hashtable fRedefinedRestrictedGroupRegistry = new Hashtable();
0304:
0305:            // a variable storing whether the last schema document
0306:            // processed (by getSchema) was a duplicate.
0307:            private boolean fLastSchemaWasDuplicate;
0308:
0309:            // validate annotations feature
0310:            private boolean fValidateAnnotations = false;
0311:
0312:            //handle multiple import feature
0313:            private boolean fHonourAllSchemaLocations = false;
0314:
0315:            // the XMLErrorReporter
0316:            private XMLErrorReporter fErrorReporter;
0317:            private XMLEntityResolver fEntityResolver;
0318:
0319:            // the XSAttributeChecker
0320:            private XSAttributeChecker fAttributeChecker;
0321:
0322:            // the symbol table
0323:            private SymbolTable fSymbolTable;
0324:
0325:            // the GrammarResolver
0326:            private XSGrammarBucket fGrammarBucket;
0327:
0328:            // the Grammar description
0329:            private XSDDescription fSchemaGrammarDescription;
0330:
0331:            // the Grammar Pool
0332:            private XMLGrammarPool fGrammarPool;
0333:
0334:            //************ Traversers **********
0335:            XSDAttributeGroupTraverser fAttributeGroupTraverser;
0336:            XSDAttributeTraverser fAttributeTraverser;
0337:            XSDComplexTypeTraverser fComplexTypeTraverser;
0338:            XSDElementTraverser fElementTraverser;
0339:            XSDGroupTraverser fGroupTraverser;
0340:            XSDKeyrefTraverser fKeyrefTraverser;
0341:            XSDNotationTraverser fNotationTraverser;
0342:            XSDSimpleTypeTraverser fSimpleTypeTraverser;
0343:            XSDUniqueOrKeyTraverser fUniqueOrKeyTraverser;
0344:            XSDWildcardTraverser fWildCardTraverser;
0345:
0346:            SchemaDOMParser fSchemaParser;
0347:            SchemaContentHandler fXSContentHandler;
0348:            XML11Configuration fAnnotationValidator;
0349:            XSAnnotationGrammarPool fGrammarBucketAdapter;
0350:
0351:            // these data members are needed for the deferred traversal
0352:            // of local elements.
0353:
0354:            // the initial size of the array to store deferred local elements
0355:            private static final int INIT_STACK_SIZE = 30;
0356:            // the incremental size of the array to store deferred local elements
0357:            private static final int INC_STACK_SIZE = 10;
0358:            // current position of the array (# of deferred local elements)
0359:            private int fLocalElemStackPos = 0;
0360:
0361:            private XSParticleDecl[] fParticle = new XSParticleDecl[INIT_STACK_SIZE];
0362:            private Element[] fLocalElementDecl = new Element[INIT_STACK_SIZE];
0363:            private XSDocumentInfo[] fLocalElementDecl_schema = new XSDocumentInfo[INIT_STACK_SIZE]; //JACK
0364:            private int[] fAllContext = new int[INIT_STACK_SIZE];
0365:            private XSObject[] fParent = new XSObject[INIT_STACK_SIZE];
0366:            private String[][] fLocalElemNamespaceContext = new String[INIT_STACK_SIZE][1];
0367:
0368:            // these data members are needed for the deferred traversal
0369:            // of keyrefs.
0370:
0371:            // the initial size of the array to store deferred keyrefs
0372:            private static final int INIT_KEYREF_STACK = 2;
0373:            // the incremental size of the array to store deferred keyrefs
0374:            private static final int INC_KEYREF_STACK_AMOUNT = 2;
0375:            // current position of the array (# of deferred keyrefs)
0376:            private int fKeyrefStackPos = 0;
0377:
0378:            private Element[] fKeyrefs = new Element[INIT_KEYREF_STACK];
0379:            private XSDocumentInfo[] fKeyrefsMapXSDocumentInfo = new XSDocumentInfo[INIT_KEYREF_STACK];
0380:            private XSElementDecl[] fKeyrefElems = new XSElementDecl[INIT_KEYREF_STACK];
0381:            private String[][] fKeyrefNamespaceContext = new String[INIT_KEYREF_STACK][1];
0382:
0383:            // Constructors
0384:            public XSDHandler() {
0385:                fHiddenNodes = new Hashtable();
0386:                fSchemaParser = new SchemaDOMParser(new SchemaParsingConfig());
0387:            }
0388:
0389:            // it should be possible to use the same XSDHandler to parse
0390:            // multiple schema documents; this will allow one to be
0391:            // constructed.
0392:            public XSDHandler(XSGrammarBucket gBucket) {
0393:                this ();
0394:                fGrammarBucket = gBucket;
0395:
0396:                // Note: don't use SchemaConfiguration internally
0397:                //       we will get stack overflaw because
0398:                //       XMLSchemaValidator will be instantiating XSDHandler...
0399:                fSchemaGrammarDescription = new XSDDescription();
0400:            } // end constructor
0401:
0402:            /**
0403:             * This method initiates the parse of a schema.  It will likely be
0404:             * called from the Validator and it will make the
0405:             * resulting grammar available; it returns a reference to this object just
0406:             * in case.  A reset(XMLComponentManager) must be called before this methods is called.
0407:             * @param is
0408:             * @param desc
0409:             * @param locationPairs
0410:             * @return the SchemaGrammar
0411:             * @throws IOException
0412:             */
0413:            public SchemaGrammar parseSchema(XMLInputSource is,
0414:                    XSDDescription desc, Hashtable locationPairs)
0415:                    throws IOException {
0416:                fLocationPairs = locationPairs;
0417:                fSchemaParser.resetNodePool();
0418:                SchemaGrammar grammar = null;
0419:                String schemaNamespace = null;
0420:                short referType = desc.getContextType();
0421:                // if loading using JAXP schemaSource property, or using grammar caching loadGrammar
0422:                // the desc.targetNamespace is always null.
0423:                // Therefore we should not attempt to find out if
0424:                // the schema is already in the bucket, since in the case we have
0425:                // no namespace schema in the bucket, findGrammar will always return the
0426:                // no namespace schema.
0427:                if (referType != XSDDescription.CONTEXT_PREPARSE) {
0428:                    // first try to find it in the bucket/pool, return if one is found
0429:                    if (fHonourAllSchemaLocations
0430:                            && referType == XSDDescription.CONTEXT_IMPORT
0431:                            && isExistingGrammar(desc)) {
0432:                        grammar = fGrammarBucket.getGrammar(desc
0433:                                .getTargetNamespace());
0434:                    } else {
0435:                        grammar = findGrammar(desc);
0436:                    }
0437:                    if (grammar != null)
0438:                        return grammar;
0439:                    schemaNamespace = desc.getTargetNamespace();
0440:                    // handle empty string URI as null
0441:                    if (schemaNamespace != null) {
0442:                        schemaNamespace = fSymbolTable
0443:                                .addSymbol(schemaNamespace);
0444:                    }
0445:                }
0446:
0447:                // before parsing a schema, need to clear registries associated with
0448:                // parsing schemas
0449:                prepareForParse();
0450:
0451:                Document schemaRootDoc = null;
0452:                Element schemaRoot = null;
0453:                // first phase:  construct trees.
0454:                if (is instanceof  DOMInputSource) {
0455:                    //clean up the field fHiddenNodes, used for DOMInputSource
0456:                    fHiddenNodes.clear();
0457:                    Node domNode = ((DOMInputSource) is).getNode();
0458:
0459:                    if (domNode instanceof  Document) {
0460:                        schemaRootDoc = (Document) domNode;
0461:                        schemaRoot = DOMUtil.getRoot(schemaRootDoc);
0462:                    } else if (domNode instanceof  Element) {
0463:                        schemaRoot = (Element) domNode;
0464:                    } else {
0465:                        return null;
0466:                    }
0467:                } // DOMInputSource
0468:                else if (is instanceof  SAXInputSource) {
0469:                    XMLReader parser = ((SAXInputSource) is).getXMLReader();
0470:                    InputSource inputSource = ((SAXInputSource) is)
0471:                            .getInputSource();
0472:                    boolean namespacePrefixes = false;
0473:                    if (parser != null) {
0474:                        try {
0475:                            namespacePrefixes = parser
0476:                                    .getFeature(NAMESPACE_PREFIXES);
0477:                        } catch (SAXException se) {
0478:                        }
0479:                    } else {
0480:                        try {
0481:                            parser = XMLReaderFactory.createXMLReader();
0482:                        }
0483:                        // If something went wrong with the factory
0484:                        // just use our own SAX parser.
0485:                        catch (SAXException se) {
0486:                            parser = new SAXParser();
0487:                        }
0488:                        try {
0489:                            parser.setFeature(NAMESPACE_PREFIXES, true);
0490:                            namespacePrefixes = true;
0491:                        } catch (SAXException se) {
0492:                        }
0493:                    }
0494:                    // If XML names and Namespace URIs are already internalized we
0495:                    // can avoid running them through the SymbolTable.
0496:                    boolean stringsInternalized = false;
0497:                    try {
0498:                        stringsInternalized = parser
0499:                                .getFeature(STRING_INTERNING);
0500:                    } catch (SAXException exc) {
0501:                        // The feature isn't recognized or getting it is not supported.
0502:                        // In either case, assume that strings are not internalized.
0503:                    }
0504:                    if (fXSContentHandler == null) {
0505:                        fXSContentHandler = new SchemaContentHandler();
0506:                    }
0507:                    fXSContentHandler.reset(fSchemaParser, fSymbolTable,
0508:                            namespacePrefixes, stringsInternalized);
0509:                    parser.setContentHandler(fXSContentHandler);
0510:                    parser.setErrorHandler(fErrorReporter.getSAXErrorHandler());
0511:                    try {
0512:                        parser.parse(inputSource);
0513:                    } catch (SAXException se) {
0514:                        return null;
0515:                    }
0516:                    schemaRootDoc = fXSContentHandler.getDocument();
0517:                    if (schemaRootDoc == null) {
0518:                        // something went wrong right off the hop
0519:                        return null;
0520:                    }
0521:                    schemaRoot = DOMUtil.getRoot(schemaRootDoc);
0522:                } else {
0523:                    schemaRoot = getSchemaDocument(schemaNamespace, is,
0524:                            referType == XSDDescription.CONTEXT_PREPARSE,
0525:                            referType, null);
0526:
0527:                }//is instanceof XMLInputSource
0528:
0529:                if (schemaRoot == null) {
0530:                    // something went wrong right off the hop
0531:                    return null;
0532:                }
0533:
0534:                if (referType == XSDDescription.CONTEXT_PREPARSE) {
0535:                    Element schemaElem = schemaRoot;
0536:                    schemaNamespace = DOMUtil.getAttrValue(schemaElem,
0537:                            SchemaSymbols.ATT_TARGETNAMESPACE);
0538:                    if (schemaNamespace != null && schemaNamespace.length() > 0) {
0539:                        // Since now we've discovered a namespace, we need to update xsd key
0540:                        // and store this schema in traversed schemas bucket
0541:                        schemaNamespace = fSymbolTable
0542:                                .addSymbol(schemaNamespace);
0543:                        desc.setTargetNamespace(schemaNamespace);
0544:                    } else {
0545:                        schemaNamespace = null;
0546:                    }
0547:                    grammar = findGrammar(desc);
0548:                    if (grammar != null)
0549:                        return grammar;
0550:                    String schemaId = XMLEntityManager.expandSystemId(is
0551:                            .getSystemId(), is.getBaseSystemId(), false);
0552:                    XSDKey key = new XSDKey(schemaId, referType,
0553:                            schemaNamespace);
0554:                    fTraversed.put(key, schemaRoot);
0555:                    if (schemaId != null) {
0556:                        fDoc2SystemId.put(schemaRoot, schemaId);
0557:                    }
0558:                }
0559:
0560:                // before constructing trees and traversing a schema, need to reset
0561:                // all traversers and clear all registries
0562:                prepareForTraverse();
0563:
0564:                fRoot = constructTrees(schemaRoot, is.getSystemId(), desc);
0565:                if (fRoot == null) {
0566:                    return null;
0567:                }
0568:
0569:                // second phase:  fill global registries.
0570:                buildGlobalNameRegistries();
0571:
0572:                // third phase:  call traversers
0573:                ArrayList annotationInfo = fValidateAnnotations ? new ArrayList()
0574:                        : null;
0575:                traverseSchemas(annotationInfo);
0576:
0577:                // fourth phase: handle local element decls
0578:                traverseLocalElements();
0579:
0580:                // fifth phase:  handle Keyrefs
0581:                resolveKeyRefs();
0582:
0583:                // sixth phase:  validate attribute of non-schema namespaces
0584:                // REVISIT: skip this for now. we really don't want to do it.
0585:                //fAttributeChecker.checkNonSchemaAttributes(fGrammarBucket);
0586:
0587:                // seventh phase:  store imported grammars
0588:                // for all grammars with <import>s
0589:                for (int i = fAllTNSs.size() - 1; i >= 0; i--) {
0590:                    // get its target namespace
0591:                    String tns = (String) fAllTNSs.elementAt(i);
0592:                    // get all namespaces it imports
0593:                    Vector ins = (Vector) fImportMap.get(tns);
0594:                    // get the grammar
0595:                    SchemaGrammar sg = fGrammarBucket
0596:                            .getGrammar(emptyString2Null(tns));
0597:                    if (sg == null)
0598:                        continue;
0599:                    SchemaGrammar isg;
0600:                    // for imported namespace
0601:                    int count = 0;
0602:                    for (int j = 0; j < ins.size(); j++) {
0603:                        // get imported grammar
0604:                        isg = fGrammarBucket.getGrammar((String) ins
0605:                                .elementAt(j));
0606:                        // reuse the same vector
0607:                        if (isg != null)
0608:                            ins.setElementAt(isg, count++);
0609:                    }
0610:                    ins.setSize(count);
0611:                    // set the imported grammars
0612:                    sg.setImportedGrammars(ins);
0613:                }
0614:
0615:                /** validate annotations **/
0616:                if (fValidateAnnotations && annotationInfo.size() > 0) {
0617:                    validateAnnotations(annotationInfo);
0618:                }
0619:
0620:                // and return.
0621:                return fGrammarBucket.getGrammar(fRoot.fTargetNamespace);
0622:            } // end parseSchema
0623:
0624:            private void validateAnnotations(ArrayList annotationInfo) {
0625:                if (fAnnotationValidator == null) {
0626:                    createAnnotationValidator();
0627:                }
0628:                final int size = annotationInfo.size();
0629:                final XMLInputSource src = new XMLInputSource(null, null, null);
0630:                fGrammarBucketAdapter.refreshGrammars(fGrammarBucket);
0631:                for (int i = 0; i < size; i += 2) {
0632:                    src.setSystemId((String) annotationInfo.get(i));
0633:                    XSAnnotationInfo annotation = (XSAnnotationInfo) annotationInfo
0634:                            .get(i + 1);
0635:                    while (annotation != null) {
0636:                        src.setCharacterStream(new StringReader(
0637:                                annotation.fAnnotation));
0638:                        try {
0639:                            fAnnotationValidator.parse(src);
0640:                        } catch (IOException exc) {
0641:                        }
0642:                        annotation = annotation.next;
0643:                    }
0644:                }
0645:            }
0646:
0647:            private void createAnnotationValidator() {
0648:                fAnnotationValidator = new XML11Configuration();
0649:                fGrammarBucketAdapter = new XSAnnotationGrammarPool();
0650:                fAnnotationValidator.setFeature(VALIDATION, true);
0651:                fAnnotationValidator.setFeature(XMLSCHEMA_VALIDATION, true);
0652:                fAnnotationValidator.setProperty(XMLGRAMMAR_POOL,
0653:                        fGrammarBucketAdapter);
0654:                /** Set error handler. **/
0655:                XMLErrorHandler errorHandler = fErrorReporter.getErrorHandler();
0656:                fAnnotationValidator.setProperty(ERROR_HANDLER,
0657:                        (errorHandler != null) ? errorHandler
0658:                                : new DefaultErrorHandler());
0659:            }
0660:
0661:            /**
0662:             * Pull the grammar out of the bucket simply using
0663:             * its TNS as a key
0664:             */
0665:            SchemaGrammar getGrammar(String tns) {
0666:                return fGrammarBucket.getGrammar(tns);
0667:            }
0668:
0669:            /**
0670:             * First try to find a grammar in the bucket, if failed, consult the
0671:             * grammar pool. If a grammar is found in the pool, then add it (and all
0672:             * imported ones) into the bucket.
0673:             */
0674:            protected SchemaGrammar findGrammar(XSDDescription desc) {
0675:                SchemaGrammar sg = fGrammarBucket.getGrammar(desc
0676:                        .getTargetNamespace());
0677:                if (sg == null) {
0678:                    if (fGrammarPool != null) {
0679:                        sg = (SchemaGrammar) fGrammarPool.retrieveGrammar(desc);
0680:                        if (sg != null) {
0681:                            // put this grammar into the bucket, along with grammars
0682:                            // imported by it (directly or indirectly)
0683:                            if (!fGrammarBucket.putGrammar(sg, true)) {
0684:                                // REVISIT: a conflict between new grammar(s) and grammars
0685:                                // in the bucket. What to do? A warning? An exception?
0686:                                reportSchemaWarning("GrammarConflict", null,
0687:                                        null);
0688:                                sg = null;
0689:                            }
0690:                        }
0691:                    }
0692:                }
0693:                return sg;
0694:            }
0695:
0696:            // may wish to have setter methods for ErrorHandler,
0697:            // EntityResolver...
0698:
0699:            private static final String[][] NS_ERROR_CODES = {
0700:                    { "src-include.2.1", "src-include.2.1" },
0701:                    { "src-redefine.3.1", "src-redefine.3.1" },
0702:                    { "src-import.3.1", "src-import.3.2" }, null,
0703:                    { "TargetNamespace.1", "TargetNamespace.2" },
0704:                    { "TargetNamespace.1", "TargetNamespace.2" },
0705:                    { "TargetNamespace.1", "TargetNamespace.2" },
0706:                    { "TargetNamespace.1", "TargetNamespace.2" } };
0707:
0708:            private static final String[] ELE_ERROR_CODES = { "src-include.1",
0709:                    "src-redefine.2", "src-import.2", "schema_reference.4",
0710:                    "schema_reference.4", "schema_reference.4",
0711:                    "schema_reference.4", "schema_reference.4" };
0712:
0713:            // This method does several things:
0714:            // It constructs an instance of an XSDocumentInfo object using the
0715:            // schemaRoot node.  Then, for each <include>,
0716:            // <redefine>, and <import> children, it attempts to resolve the
0717:            // requested schema document, initiates a DOM parse, and calls
0718:            // itself recursively on that document's root.  It also records in
0719:            // the DependencyMap object what XSDocumentInfo objects its XSDocumentInfo
0720:            // depends on.
0721:            // It also makes sure the targetNamespace of the schema it was
0722:            // called to parse is correct.
0723:            protected XSDocumentInfo constructTrees(Element schemaRoot,
0724:                    String locationHint, XSDDescription desc) {
0725:                if (schemaRoot == null)
0726:                    return null;
0727:                String callerTNS = desc.getTargetNamespace();
0728:                short referType = desc.getContextType();
0729:
0730:                XSDocumentInfo currSchemaInfo = null;
0731:                try {
0732:                    // note that attributes are freed at end of traverseSchemas()
0733:                    currSchemaInfo = new XSDocumentInfo(schemaRoot,
0734:                            fAttributeChecker, fSymbolTable);
0735:                } catch (XMLSchemaException se) {
0736:                    reportSchemaError(ELE_ERROR_CODES[referType],
0737:                            new Object[] { locationHint }, schemaRoot);
0738:                    return null;
0739:                }
0740:                // targetNamespace="" is not valid, issue a warning, and ignore it
0741:                if (currSchemaInfo.fTargetNamespace != null
0742:                        && currSchemaInfo.fTargetNamespace.length() == 0) {
0743:                    reportSchemaWarning("EmptyTargetNamespace",
0744:                            new Object[] { locationHint }, schemaRoot);
0745:                    currSchemaInfo.fTargetNamespace = null;
0746:                }
0747:
0748:                if (callerTNS != null) {
0749:                    // the second index to the NS_ERROR_CODES array
0750:                    // if the caller/expected NS is not absent, we use the first column
0751:                    int secondIdx = 0;
0752:                    // for include and redefine
0753:                    if (referType == XSDDescription.CONTEXT_INCLUDE
0754:                            || referType == XSDDescription.CONTEXT_REDEFINE) {
0755:                        // if the referred document has no targetNamespace,
0756:                        // it's a chameleon schema
0757:                        if (currSchemaInfo.fTargetNamespace == null) {
0758:                            currSchemaInfo.fTargetNamespace = callerTNS;
0759:                            currSchemaInfo.fIsChameleonSchema = true;
0760:                        }
0761:                        // if the referred document has a target namespace differing
0762:                        // from the caller, it's an error
0763:                        else if (callerTNS != currSchemaInfo.fTargetNamespace) {
0764:                            reportSchemaError(
0765:                                    NS_ERROR_CODES[referType][secondIdx],
0766:                                    new Object[] { callerTNS,
0767:                                            currSchemaInfo.fTargetNamespace },
0768:                                    schemaRoot);
0769:                            return null;
0770:                        }
0771:                    }
0772:                    // for instance and import, the two NS's must be the same
0773:                    else if (referType != XSDDescription.CONTEXT_PREPARSE
0774:                            && callerTNS != currSchemaInfo.fTargetNamespace) {
0775:                        reportSchemaError(NS_ERROR_CODES[referType][secondIdx],
0776:                                new Object[] { callerTNS,
0777:                                        currSchemaInfo.fTargetNamespace },
0778:                                schemaRoot);
0779:                        return null;
0780:                    }
0781:                }
0782:                // now there is no caller/expected NS, it's an error for the referred
0783:                // document to have a target namespace, unless we are preparsing a schema
0784:                else if (currSchemaInfo.fTargetNamespace != null) {
0785:                    // set the target namespace of the description
0786:                    if (referType == XSDDescription.CONTEXT_PREPARSE) {
0787:                        desc
0788:                                .setTargetNamespace(currSchemaInfo.fTargetNamespace);
0789:                        callerTNS = currSchemaInfo.fTargetNamespace;
0790:                    } else {
0791:                        // the second index to the NS_ERROR_CODES array
0792:                        // if the caller/expected NS is absent, we use the second column
0793:                        int secondIdx = 1;
0794:                        reportSchemaError(NS_ERROR_CODES[referType][secondIdx],
0795:                                new Object[] { callerTNS,
0796:                                        currSchemaInfo.fTargetNamespace },
0797:                                schemaRoot);
0798:                        return null;
0799:                    }
0800:                }
0801:                // the other cases (callerTNS == currSchemaInfo.fTargetNamespce == null)
0802:                // are valid
0803:
0804:                // a schema document can always access it's own target namespace
0805:                currSchemaInfo.addAllowedNS(currSchemaInfo.fTargetNamespace);
0806:
0807:                SchemaGrammar sg = null;
0808:
0809:                if (referType == XSDDescription.CONTEXT_INCLUDE
0810:                        || referType == XSDDescription.CONTEXT_REDEFINE) {
0811:                    sg = fGrammarBucket
0812:                            .getGrammar(currSchemaInfo.fTargetNamespace);
0813:                } else if (fHonourAllSchemaLocations
0814:                        && referType == XSDDescription.CONTEXT_IMPORT) {
0815:                    sg = findGrammar(desc);
0816:                    if (sg == null) {
0817:                        sg = new SchemaGrammar(currSchemaInfo.fTargetNamespace,
0818:                                desc.makeClone(), fSymbolTable);
0819:                        fGrammarBucket.putGrammar(sg);
0820:                    }
0821:                } else {
0822:                    sg = new SchemaGrammar(currSchemaInfo.fTargetNamespace,
0823:                            desc.makeClone(), fSymbolTable);
0824:                    fGrammarBucket.putGrammar(sg);
0825:                }
0826:
0827:                // store the document and its location
0828:                // REVISIT: don't expose the DOM tree
0829:                sg.addDocument(null, (String) fDoc2SystemId
0830:                        .get(currSchemaInfo.fSchemaElement));
0831:
0832:                fDoc2XSDocumentMap.put(schemaRoot, currSchemaInfo);
0833:                Vector dependencies = new Vector();
0834:                Element rootNode = schemaRoot;
0835:
0836:                Element newSchemaRoot = null;
0837:                for (Element child = DOMUtil.getFirstChildElement(rootNode); child != null; child = DOMUtil
0838:                        .getNextSiblingElement(child)) {
0839:                    String schemaNamespace = null;
0840:                    String schemaHint = null;
0841:                    String localName = DOMUtil.getLocalName(child);
0842:
0843:                    short refType = -1;
0844:
0845:                    if (localName.equals(SchemaSymbols.ELT_ANNOTATION))
0846:                        continue;
0847:                    else if (localName.equals(SchemaSymbols.ELT_IMPORT)) {
0848:                        refType = XSDDescription.CONTEXT_IMPORT;
0849:                        // have to handle some validation here too!
0850:                        // call XSAttributeChecker to fill in attrs
0851:                        Object[] importAttrs = fAttributeChecker
0852:                                .checkAttributes(child, true, currSchemaInfo);
0853:                        schemaHint = (String) importAttrs[XSAttributeChecker.ATTIDX_SCHEMALOCATION];
0854:                        schemaNamespace = (String) importAttrs[XSAttributeChecker.ATTIDX_NAMESPACE];
0855:                        if (schemaNamespace != null)
0856:                            schemaNamespace = fSymbolTable
0857:                                    .addSymbol(schemaNamespace);
0858:                        // a document can't import another document with the same namespace
0859:                        if (schemaNamespace == currSchemaInfo.fTargetNamespace) {
0860:                            reportSchemaError(
0861:                                    schemaNamespace != null ? "src-import.1.1"
0862:                                            : "src-import.1.2",
0863:                                    new Object[] { schemaNamespace }, child);
0864:                        }
0865:
0866:                        // check contents and process optional annotations
0867:                        Element importChild = DOMUtil
0868:                                .getFirstChildElement(child);
0869:                        if (importChild != null) {
0870:                            String importComponentType = DOMUtil
0871:                                    .getLocalName(importChild);
0872:                            if (importComponentType
0873:                                    .equals(SchemaSymbols.ELT_ANNOTATION)) {
0874:                                // promoting annotations to parent component
0875:                                sg.addAnnotation(fElementTraverser
0876:                                        .traverseAnnotationDecl(importChild,
0877:                                                importAttrs, true,
0878:                                                currSchemaInfo));
0879:                            } else {
0880:                                reportSchemaError("s4s-elt-must-match.1",
0881:                                        new Object[] { localName,
0882:                                                "annotation?",
0883:                                                importComponentType }, child);
0884:                            }
0885:                            if (DOMUtil.getNextSiblingElement(importChild) != null) {
0886:                                reportSchemaError(
0887:                                        "s4s-elt-must-match.1",
0888:                                        new Object[] {
0889:                                                localName,
0890:                                                "annotation?",
0891:                                                DOMUtil
0892:                                                        .getLocalName(DOMUtil
0893:                                                                .getNextSiblingElement(importChild)) },
0894:                                        child);
0895:                            }
0896:                        } else {
0897:                            String text = DOMUtil.getSyntheticAnnotation(child);
0898:                            if (text != null) {
0899:                                sg.addAnnotation(fElementTraverser
0900:                                        .traverseSyntheticAnnotation(child,
0901:                                                text, importAttrs, true,
0902:                                                currSchemaInfo));
0903:                            }
0904:                        }
0905:                        fAttributeChecker.returnAttrArray(importAttrs,
0906:                                currSchemaInfo);
0907:
0908:                        // if this namespace has not been imported by this document,
0909:                        //  then import if multiple imports support is enabled.
0910:                        if (currSchemaInfo.isAllowedNS(schemaNamespace)) {
0911:                            if (!fHonourAllSchemaLocations)
0912:                                continue;
0913:                        } else {
0914:                            currSchemaInfo.addAllowedNS(schemaNamespace);
0915:                        }
0916:                        // also record the fact that one namespace imports another one
0917:                        // convert null to ""
0918:                        String tns = null2EmptyString(currSchemaInfo.fTargetNamespace);
0919:                        // get all namespaces imported by this one
0920:                        Vector ins = (Vector) fImportMap.get(tns);
0921:                        // if no namespace was imported, create new Vector
0922:                        if (ins == null) {
0923:                            // record that this one imports other(s)
0924:                            fAllTNSs.addElement(tns);
0925:                            ins = new Vector();
0926:                            fImportMap.put(tns, ins);
0927:                            ins.addElement(schemaNamespace);
0928:                        } else if (!ins.contains(schemaNamespace)) {
0929:                            ins.addElement(schemaNamespace);
0930:                        }
0931:
0932:                        fSchemaGrammarDescription.reset();
0933:                        fSchemaGrammarDescription
0934:                                .setContextType(XSDDescription.CONTEXT_IMPORT);
0935:                        fSchemaGrammarDescription
0936:                                .setBaseSystemId(doc2SystemId(schemaRoot));
0937:                        fSchemaGrammarDescription
0938:                                .setLocationHints(new String[] { schemaHint });
0939:                        fSchemaGrammarDescription
0940:                                .setTargetNamespace(schemaNamespace);
0941:
0942:                        // if a grammar with the same namespace and location exists (or being
0943:                        // built), ignore this one (don't traverse it).
0944:                        if ((!fHonourAllSchemaLocations && findGrammar(fSchemaGrammarDescription) != null)
0945:                                || isExistingGrammar(fSchemaGrammarDescription))
0946:                            continue;
0947:                        // If "findGrammar" returns a grammar, then this is not the
0948:                        // the first time we see a location for a given namespace.
0949:                        // Don't consult the location pair hashtable in this case,
0950:                        // otherwise the location will be ignored because it'll get
0951:                        // resolved to the same location as the first hint.
0952:                        newSchemaRoot = resolveSchema(
0953:                                fSchemaGrammarDescription, false, child,
0954:                                findGrammar(fSchemaGrammarDescription) == null);
0955:                    } else if ((localName.equals(SchemaSymbols.ELT_INCLUDE))
0956:                            || (localName.equals(SchemaSymbols.ELT_REDEFINE))) {
0957:                        // validation for redefine/include will be the same here; just
0958:                        // make sure TNS is right (don't care about redef contents
0959:                        // yet).
0960:                        Object[] includeAttrs = fAttributeChecker
0961:                                .checkAttributes(child, true, currSchemaInfo);
0962:                        schemaHint = (String) includeAttrs[XSAttributeChecker.ATTIDX_SCHEMALOCATION];
0963:                        // store the namespace decls of the redefine element
0964:                        if (localName.equals(SchemaSymbols.ELT_REDEFINE)) {
0965:                            fRedefine2NSSupport.put(child,
0966:                                    new SchemaNamespaceSupport(
0967:                                            currSchemaInfo.fNamespaceSupport));
0968:                        }
0969:
0970:                        // check annotations.  Must do this here to avoid having to
0971:                        // re-parse attributes later
0972:                        if (localName.equals(SchemaSymbols.ELT_INCLUDE)) {
0973:                            Element includeChild = DOMUtil
0974:                                    .getFirstChildElement(child);
0975:                            if (includeChild != null) {
0976:                                String includeComponentType = DOMUtil
0977:                                        .getLocalName(includeChild);
0978:                                if (includeComponentType
0979:                                        .equals(SchemaSymbols.ELT_ANNOTATION)) {
0980:                                    // promoting annotations to parent component
0981:                                    sg.addAnnotation(fElementTraverser
0982:                                            .traverseAnnotationDecl(
0983:                                                    includeChild, includeAttrs,
0984:                                                    true, currSchemaInfo));
0985:                                } else {
0986:                                    reportSchemaError("s4s-elt-must-match.1",
0987:                                            new Object[] { localName,
0988:                                                    "annotation?",
0989:                                                    includeComponentType },
0990:                                            child);
0991:                                }
0992:                                if (DOMUtil.getNextSiblingElement(includeChild) != null) {
0993:                                    reportSchemaError(
0994:                                            "s4s-elt-must-match.1",
0995:                                            new Object[] {
0996:                                                    localName,
0997:                                                    "annotation?",
0998:                                                    DOMUtil
0999:                                                            .getLocalName(DOMUtil
1000:                                                                    .getNextSiblingElement(includeChild)) },
1001:                                            child);
1002:                                }
1003:                            } else {
1004:                                String text = DOMUtil
1005:                                        .getSyntheticAnnotation(child);
1006:                                if (text != null) {
1007:                                    sg.addAnnotation(fElementTraverser
1008:                                            .traverseSyntheticAnnotation(child,
1009:                                                    text, includeAttrs, true,
1010:                                                    currSchemaInfo));
1011:                                }
1012:                            }
1013:                        } else {
1014:                            for (Element redefinedChild = DOMUtil
1015:                                    .getFirstChildElement(child); redefinedChild != null; redefinedChild = DOMUtil
1016:                                    .getNextSiblingElement(redefinedChild)) {
1017:                                String redefinedComponentType = DOMUtil
1018:                                        .getLocalName(redefinedChild);
1019:                                if (redefinedComponentType
1020:                                        .equals(SchemaSymbols.ELT_ANNOTATION)) {
1021:                                    // promoting annotations to parent component
1022:                                    sg.addAnnotation(fElementTraverser
1023:                                            .traverseAnnotationDecl(
1024:                                                    redefinedChild,
1025:                                                    includeAttrs, true,
1026:                                                    currSchemaInfo));
1027:                                    DOMUtil.setHidden(redefinedChild,
1028:                                            fHiddenNodes);
1029:                                } else {
1030:                                    String text = DOMUtil
1031:                                            .getSyntheticAnnotation(child);
1032:                                    if (text != null) {
1033:                                        sg.addAnnotation(fElementTraverser
1034:                                                .traverseSyntheticAnnotation(
1035:                                                        child, text,
1036:                                                        includeAttrs, true,
1037:                                                        currSchemaInfo));
1038:                                    }
1039:                                }
1040:                                // catch all other content errors later
1041:                            }
1042:                        }
1043:                        fAttributeChecker.returnAttrArray(includeAttrs,
1044:                                currSchemaInfo);
1045:                        // schemaLocation is required on <include> and <redefine>
1046:                        if (schemaHint == null) {
1047:                            reportSchemaError("s4s-att-must-appear",
1048:                                    new Object[] { "<include> or <redefine>",
1049:                                            "schemaLocation" }, child);
1050:                        }
1051:                        // pass the systemId of the current document as the base systemId
1052:                        boolean mustResolve = false;
1053:                        refType = XSDDescription.CONTEXT_INCLUDE;
1054:                        if (localName.equals(SchemaSymbols.ELT_REDEFINE)) {
1055:                            mustResolve = nonAnnotationContent(child);
1056:                            refType = XSDDescription.CONTEXT_REDEFINE;
1057:                        }
1058:                        fSchemaGrammarDescription.reset();
1059:                        fSchemaGrammarDescription.setContextType(refType);
1060:                        fSchemaGrammarDescription
1061:                                .setBaseSystemId(doc2SystemId(schemaRoot));
1062:                        fSchemaGrammarDescription
1063:                                .setLocationHints(new String[] { schemaHint });
1064:                        fSchemaGrammarDescription.setTargetNamespace(callerTNS);
1065:                        newSchemaRoot = resolveSchema(
1066:                                fSchemaGrammarDescription, mustResolve, child,
1067:                                true);
1068:                        schemaNamespace = currSchemaInfo.fTargetNamespace;
1069:                    } else {
1070:                        // no more possibility of schema references in well-formed
1071:                        // schema...
1072:                        break;
1073:                    }
1074:
1075:                    // If the schema is duplicate, we needn't call constructTrees() again.
1076:                    // To handle mutual <include>s
1077:                    XSDocumentInfo newSchemaInfo = null;
1078:                    if (fLastSchemaWasDuplicate) {
1079:                        newSchemaInfo = newSchemaRoot == null ? null
1080:                                : (XSDocumentInfo) fDoc2XSDocumentMap
1081:                                        .get(newSchemaRoot);
1082:                    } else {
1083:                        newSchemaInfo = constructTrees(newSchemaRoot,
1084:                                schemaHint, fSchemaGrammarDescription);
1085:                    }
1086:
1087:                    if (localName.equals(SchemaSymbols.ELT_REDEFINE)
1088:                            && newSchemaInfo != null) {
1089:                        // must record which schema we're redefining so that we can
1090:                        // rename the right things later!
1091:                        fRedefine2XSDMap.put(child, newSchemaInfo);
1092:                    }
1093:                    if (newSchemaRoot != null) {
1094:                        if (newSchemaInfo != null)
1095:                            dependencies.addElement(newSchemaInfo);
1096:                        newSchemaRoot = null;
1097:                    }
1098:                }
1099:
1100:                fDependencyMap.put(currSchemaInfo, dependencies);
1101:                return currSchemaInfo;
1102:            } // end constructTrees
1103:
1104:            private boolean isExistingGrammar(XSDDescription desc) {
1105:                SchemaGrammar sg = fGrammarBucket.getGrammar(desc
1106:                        .getTargetNamespace());
1107:                if (sg == null) {
1108:                    return findGrammar(desc) != null;
1109:                } else {
1110:                    try {
1111:                        return sg.getDocumentLocations().contains(
1112:                                XMLEntityManager.expandSystemId(desc
1113:                                        .getLiteralSystemId(), desc
1114:                                        .getBaseSystemId(), false));
1115:                    } catch (MalformedURIException e) {
1116:                        return false;
1117:                    }
1118:                }
1119:            }
1120:
1121:            // This method builds registries for all globally-referenceable
1122:            // names.  A registry will be built for each symbol space defined
1123:            // by the spec.  It is also this method's job to rename redefined
1124:            // components, and to record which components redefine others (so
1125:            // that implicit redefinitions of groups and attributeGroups can be handled).
1126:            protected void buildGlobalNameRegistries() {
1127:
1128:                // Starting with fRoot, we examine each child of the schema
1129:                // element.  Skipping all imports and includes, we record the names
1130:                // of all other global components (and children of <redefine>).  We
1131:                // also put <redefine> names in a registry that we look through in
1132:                // case something needs renaming.  Once we're done with a schema we
1133:                // set its Document node to hidden so that we don't try to traverse
1134:                // it again; then we look to its Dependency map entry.  We keep a
1135:                // stack of schemas that we haven't yet finished processing; this
1136:                // is a depth-first traversal.
1137:
1138:                Stack schemasToProcess = new Stack();
1139:                schemasToProcess.push(fRoot);
1140:
1141:                while (!schemasToProcess.empty()) {
1142:                    XSDocumentInfo currSchemaDoc = (XSDocumentInfo) schemasToProcess
1143:                            .pop();
1144:                    Element currDoc = currSchemaDoc.fSchemaElement;
1145:                    if (DOMUtil.isHidden(currDoc, fHiddenNodes)) {
1146:                        // must have processed this already!
1147:                        continue;
1148:                    }
1149:
1150:                    Element currRoot = currDoc;
1151:                    // process this schema's global decls
1152:                    boolean dependenciesCanOccur = true;
1153:                    for (Element globalComp = DOMUtil
1154:                            .getFirstChildElement(currRoot); globalComp != null; globalComp = DOMUtil
1155:                            .getNextSiblingElement(globalComp)) {
1156:                        // this loop makes sure the <schema> element ordering is
1157:                        // also valid.
1158:                        if (DOMUtil.getLocalName(globalComp).equals(
1159:                                SchemaSymbols.ELT_ANNOTATION)) {
1160:                            //skip it; traverse it later
1161:                            continue;
1162:                        } else if (DOMUtil.getLocalName(globalComp).equals(
1163:                                SchemaSymbols.ELT_INCLUDE)
1164:                                || DOMUtil.getLocalName(globalComp).equals(
1165:                                        SchemaSymbols.ELT_IMPORT)) {
1166:                            if (!dependenciesCanOccur) {
1167:                                reportSchemaError("s4s-elt-invalid-content.3",
1168:                                        new Object[] { DOMUtil
1169:                                                .getLocalName(globalComp) },
1170:                                        globalComp);
1171:                            }
1172:                            DOMUtil.setHidden(globalComp, fHiddenNodes);
1173:                        } else if (DOMUtil.getLocalName(globalComp).equals(
1174:                                SchemaSymbols.ELT_REDEFINE)) {
1175:                            if (!dependenciesCanOccur) {
1176:                                reportSchemaError("s4s-elt-invalid-content.3",
1177:                                        new Object[] { DOMUtil
1178:                                                .getLocalName(globalComp) },
1179:                                        globalComp);
1180:                            }
1181:                            for (Element redefineComp = DOMUtil
1182:                                    .getFirstChildElement(globalComp); redefineComp != null; redefineComp = DOMUtil
1183:                                    .getNextSiblingElement(redefineComp)) {
1184:                                String lName = DOMUtil.getAttrValue(
1185:                                        redefineComp, SchemaSymbols.ATT_NAME);
1186:                                if (lName.length() == 0) // an error we'll catch later
1187:                                    continue;
1188:                                String qName = currSchemaDoc.fTargetNamespace == null ? ","
1189:                                        + lName
1190:                                        : currSchemaDoc.fTargetNamespace + ","
1191:                                                + lName;
1192:                                String componentType = DOMUtil
1193:                                        .getLocalName(redefineComp);
1194:                                if (componentType
1195:                                        .equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
1196:                                    checkForDuplicateNames(qName,
1197:                                            fUnparsedAttributeGroupRegistry,
1198:                                            fUnparsedAttributeGroupRegistrySub,
1199:                                            redefineComp, currSchemaDoc);
1200:                                    // the check will have changed our name;
1201:                                    String targetLName = DOMUtil.getAttrValue(
1202:                                            redefineComp,
1203:                                            SchemaSymbols.ATT_NAME)
1204:                                            + REDEF_IDENTIFIER;
1205:                                    // and all we need to do is error-check+rename our kkids:
1206:                                    renameRedefiningComponents(currSchemaDoc,
1207:                                            redefineComp,
1208:                                            SchemaSymbols.ELT_ATTRIBUTEGROUP,
1209:                                            lName, targetLName);
1210:                                } else if ((componentType
1211:                                        .equals(SchemaSymbols.ELT_COMPLEXTYPE))
1212:                                        || (componentType
1213:                                                .equals(SchemaSymbols.ELT_SIMPLETYPE))) {
1214:                                    checkForDuplicateNames(qName,
1215:                                            fUnparsedTypeRegistry,
1216:                                            fUnparsedTypeRegistrySub,
1217:                                            redefineComp, currSchemaDoc);
1218:                                    // the check will have changed our name;
1219:                                    String targetLName = DOMUtil.getAttrValue(
1220:                                            redefineComp,
1221:                                            SchemaSymbols.ATT_NAME)
1222:                                            + REDEF_IDENTIFIER;
1223:                                    // and all we need to do is error-check+rename our kkids:
1224:                                    if (componentType
1225:                                            .equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
1226:                                        renameRedefiningComponents(
1227:                                                currSchemaDoc, redefineComp,
1228:                                                SchemaSymbols.ELT_COMPLEXTYPE,
1229:                                                lName, targetLName);
1230:                                    } else { // must be simpleType
1231:                                        renameRedefiningComponents(
1232:                                                currSchemaDoc, redefineComp,
1233:                                                SchemaSymbols.ELT_SIMPLETYPE,
1234:                                                lName, targetLName);
1235:                                    }
1236:                                } else if (componentType
1237:                                        .equals(SchemaSymbols.ELT_GROUP)) {
1238:                                    checkForDuplicateNames(qName,
1239:                                            fUnparsedGroupRegistry,
1240:                                            fUnparsedGroupRegistrySub,
1241:                                            redefineComp, currSchemaDoc);
1242:                                    // the check will have changed our name;
1243:                                    String targetLName = DOMUtil.getAttrValue(
1244:                                            redefineComp,
1245:                                            SchemaSymbols.ATT_NAME)
1246:                                            + REDEF_IDENTIFIER;
1247:                                    // and all we need to do is error-check+rename our kids:
1248:                                    renameRedefiningComponents(currSchemaDoc,
1249:                                            redefineComp,
1250:                                            SchemaSymbols.ELT_GROUP, lName,
1251:                                            targetLName);
1252:                                }
1253:                            } // end march through <redefine> children
1254:                            // and now set as traversed
1255:                            //DOMUtil.setHidden(globalComp);
1256:                        } else {
1257:                            dependenciesCanOccur = false;
1258:                            String lName = DOMUtil.getAttrValue(globalComp,
1259:                                    SchemaSymbols.ATT_NAME);
1260:                            if (lName.length() == 0) // an error we'll catch later
1261:                                continue;
1262:                            String qName = currSchemaDoc.fTargetNamespace == null ? ","
1263:                                    + lName
1264:                                    : currSchemaDoc.fTargetNamespace + ","
1265:                                            + lName;
1266:                            String componentType = DOMUtil
1267:                                    .getLocalName(globalComp);
1268:                            if (componentType
1269:                                    .equals(SchemaSymbols.ELT_ATTRIBUTE)) {
1270:                                checkForDuplicateNames(qName,
1271:                                        fUnparsedAttributeRegistry,
1272:                                        fUnparsedAttributeRegistrySub,
1273:                                        globalComp, currSchemaDoc);
1274:                            } else if (componentType
1275:                                    .equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
1276:                                checkForDuplicateNames(qName,
1277:                                        fUnparsedAttributeGroupRegistry,
1278:                                        fUnparsedAttributeGroupRegistrySub,
1279:                                        globalComp, currSchemaDoc);
1280:                            } else if ((componentType
1281:                                    .equals(SchemaSymbols.ELT_COMPLEXTYPE))
1282:                                    || (componentType
1283:                                            .equals(SchemaSymbols.ELT_SIMPLETYPE))) {
1284:                                checkForDuplicateNames(qName,
1285:                                        fUnparsedTypeRegistry,
1286:                                        fUnparsedTypeRegistrySub, globalComp,
1287:                                        currSchemaDoc);
1288:                            } else if (componentType
1289:                                    .equals(SchemaSymbols.ELT_ELEMENT)) {
1290:                                checkForDuplicateNames(qName,
1291:                                        fUnparsedElementRegistry,
1292:                                        fUnparsedElementRegistrySub,
1293:                                        globalComp, currSchemaDoc);
1294:                            } else if (componentType
1295:                                    .equals(SchemaSymbols.ELT_GROUP)) {
1296:                                checkForDuplicateNames(qName,
1297:                                        fUnparsedGroupRegistry,
1298:                                        fUnparsedGroupRegistrySub, globalComp,
1299:                                        currSchemaDoc);
1300:                            } else if (componentType
1301:                                    .equals(SchemaSymbols.ELT_NOTATION)) {
1302:                                checkForDuplicateNames(qName,
1303:                                        fUnparsedNotationRegistry,
1304:                                        fUnparsedNotationRegistrySub,
1305:                                        globalComp, currSchemaDoc);
1306:                            }
1307:                        }
1308:                    } // end for
1309:
1310:                    // now we're done with this one!
1311:                    DOMUtil.setHidden(currDoc, fHiddenNodes);
1312:                    // now add the schemas this guy depends on
1313:                    Vector currSchemaDepends = (Vector) fDependencyMap
1314:                            .get(currSchemaDoc);
1315:                    for (int i = 0; i < currSchemaDepends.size(); i++) {
1316:                        schemasToProcess.push(currSchemaDepends.elementAt(i));
1317:                    }
1318:                } // while
1319:
1320:            } // end buildGlobalNameRegistries
1321:
1322:            // Beginning at the first schema processing was requested for
1323:            // (fRoot), this method
1324:            // examines each child (global schema information item) of each
1325:            // schema document (and of each <redefine> element)
1326:            // corresponding to an XSDocumentInfo object.  If the
1327:            // readOnly field on that node has not been set, it calls an
1328:            // appropriate traverser to traverse it.  Once all global decls in
1329:            // an XSDocumentInfo object have been traversed, it marks that object
1330:            // as traversed (or hidden) in order to avoid infinite loops.  It completes
1331:            // when it has visited all XSDocumentInfo objects in the
1332:            // DependencyMap and marked them as traversed.
1333:            protected void traverseSchemas(ArrayList annotationInfo) {
1334:                // the process here is very similar to that in
1335:                // buildGlobalRegistries, except we can't set our schemas as
1336:                // hidden for a second time; so make them all visible again
1337:                // first!
1338:                setSchemasVisible(fRoot);
1339:                Stack schemasToProcess = new Stack();
1340:                schemasToProcess.push(fRoot);
1341:                while (!schemasToProcess.empty()) {
1342:                    XSDocumentInfo currSchemaDoc = (XSDocumentInfo) schemasToProcess
1343:                            .pop();
1344:                    Element currDoc = currSchemaDoc.fSchemaElement;
1345:
1346:                    SchemaGrammar currSG = fGrammarBucket
1347:                            .getGrammar(currSchemaDoc.fTargetNamespace);
1348:
1349:                    if (DOMUtil.isHidden(currDoc, fHiddenNodes)) {
1350:                        // must have processed this already!
1351:                        continue;
1352:                    }
1353:                    Element currRoot = currDoc;
1354:                    boolean sawAnnotation = false;
1355:                    // traverse this schema's global decls
1356:                    for (Element globalComp = DOMUtil
1357:                            .getFirstVisibleChildElement(currRoot, fHiddenNodes); globalComp != null; globalComp = DOMUtil
1358:                            .getNextVisibleSiblingElement(globalComp,
1359:                                    fHiddenNodes)) {
1360:                        DOMUtil.setHidden(globalComp, fHiddenNodes);
1361:                        String componentType = DOMUtil.getLocalName(globalComp);
1362:                        // includes and imports will not show up here!
1363:                        if (DOMUtil.getLocalName(globalComp).equals(
1364:                                SchemaSymbols.ELT_REDEFINE)) {
1365:                            // use the namespace decls for the redefine, instead of for the parent <schema>
1366:                            currSchemaDoc
1367:                                    .backupNSSupport((SchemaNamespaceSupport) fRedefine2NSSupport
1368:                                            .get(globalComp));
1369:                            for (Element redefinedComp = DOMUtil
1370:                                    .getFirstVisibleChildElement(globalComp,
1371:                                            fHiddenNodes); redefinedComp != null; redefinedComp = DOMUtil
1372:                                    .getNextVisibleSiblingElement(
1373:                                            redefinedComp, fHiddenNodes)) {
1374:                                String redefinedComponentType = DOMUtil
1375:                                        .getLocalName(redefinedComp);
1376:                                DOMUtil.setHidden(redefinedComp, fHiddenNodes);
1377:                                if (redefinedComponentType
1378:                                        .equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
1379:                                    fAttributeGroupTraverser.traverseGlobal(
1380:                                            redefinedComp, currSchemaDoc,
1381:                                            currSG);
1382:                                } else if (redefinedComponentType
1383:                                        .equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
1384:                                    fComplexTypeTraverser.traverseGlobal(
1385:                                            redefinedComp, currSchemaDoc,
1386:                                            currSG);
1387:                                } else if (redefinedComponentType
1388:                                        .equals(SchemaSymbols.ELT_GROUP)) {
1389:                                    fGroupTraverser.traverseGlobal(
1390:                                            redefinedComp, currSchemaDoc,
1391:                                            currSG);
1392:                                } else if (redefinedComponentType
1393:                                        .equals(SchemaSymbols.ELT_SIMPLETYPE)) {
1394:                                    fSimpleTypeTraverser.traverseGlobal(
1395:                                            redefinedComp, currSchemaDoc,
1396:                                            currSG);
1397:                                }
1398:                                // annotations will have been processed already; this is now
1399:                                // unnecessary
1400:                                //else if (redefinedComponentType.equals(SchemaSymbols.ELT_ANNOTATION)) {
1401:                                //    fElementTraverser.traverseAnnotationDecl(redefinedComp, null, true, currSchemaDoc);
1402:                                //}
1403:                                else {
1404:                                    reportSchemaError(
1405:                                            "s4s-elt-must-match.1",
1406:                                            new Object[] {
1407:                                                    DOMUtil
1408:                                                            .getLocalName(globalComp),
1409:                                                    "(annotation | (simpleType | complexType | group | attributeGroup))*",
1410:                                                    redefinedComponentType },
1411:                                            redefinedComp);
1412:                                }
1413:                            } // end march through <redefine> children
1414:                            currSchemaDoc.restoreNSSupport();
1415:                        } else if (componentType
1416:                                .equals(SchemaSymbols.ELT_ATTRIBUTE)) {
1417:                            fAttributeTraverser.traverseGlobal(globalComp,
1418:                                    currSchemaDoc, currSG);
1419:                        } else if (componentType
1420:                                .equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
1421:                            fAttributeGroupTraverser.traverseGlobal(globalComp,
1422:                                    currSchemaDoc, currSG);
1423:                        } else if (componentType
1424:                                .equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
1425:                            fComplexTypeTraverser.traverseGlobal(globalComp,
1426:                                    currSchemaDoc, currSG);
1427:                        } else if (componentType
1428:                                .equals(SchemaSymbols.ELT_ELEMENT)) {
1429:                            fElementTraverser.traverseGlobal(globalComp,
1430:                                    currSchemaDoc, currSG);
1431:                        } else if (componentType
1432:                                .equals(SchemaSymbols.ELT_GROUP)) {
1433:                            fGroupTraverser.traverseGlobal(globalComp,
1434:                                    currSchemaDoc, currSG);
1435:                        } else if (componentType
1436:                                .equals(SchemaSymbols.ELT_NOTATION)) {
1437:                            fNotationTraverser.traverse(globalComp,
1438:                                    currSchemaDoc, currSG);
1439:                        } else if (componentType
1440:                                .equals(SchemaSymbols.ELT_SIMPLETYPE)) {
1441:                            fSimpleTypeTraverser.traverseGlobal(globalComp,
1442:                                    currSchemaDoc, currSG);
1443:                        } else if (componentType
1444:                                .equals(SchemaSymbols.ELT_ANNOTATION)) {
1445:                            currSG.addAnnotation(fElementTraverser
1446:                                    .traverseAnnotationDecl(globalComp,
1447:                                            currSchemaDoc.getSchemaAttrs(),
1448:                                            true, currSchemaDoc));
1449:                            sawAnnotation = true;
1450:                        } else {
1451:                            reportSchemaError("s4s-elt-invalid-content.1",
1452:                                    new Object[] { SchemaSymbols.ELT_SCHEMA,
1453:                                            DOMUtil.getLocalName(globalComp) },
1454:                                    globalComp);
1455:                        }
1456:                    } // end for
1457:
1458:                    if (!sawAnnotation) {
1459:                        String text = DOMUtil.getSyntheticAnnotation(currRoot);
1460:                        if (text != null) {
1461:                            currSG.addAnnotation(fElementTraverser
1462:                                    .traverseSyntheticAnnotation(currRoot,
1463:                                            text, currSchemaDoc
1464:                                                    .getSchemaAttrs(), true,
1465:                                            currSchemaDoc));
1466:                        }
1467:                    }
1468:
1469:                    /** Collect annotation information for validation. **/
1470:                    if (annotationInfo != null) {
1471:                        XSAnnotationInfo info = currSchemaDoc.getAnnotations();
1472:                        /** Only add annotations to the list if there were any in this document. **/
1473:                        if (info != null) {
1474:                            annotationInfo.add(doc2SystemId(currDoc));
1475:                            annotationInfo.add(info);
1476:                        }
1477:                    }
1478:                    // now we're done with this one!
1479:                    currSchemaDoc.returnSchemaAttrs();
1480:                    DOMUtil.setHidden(currDoc, fHiddenNodes);
1481:
1482:                    // now add the schemas this guy depends on
1483:                    Vector currSchemaDepends = (Vector) fDependencyMap
1484:                            .get(currSchemaDoc);
1485:                    for (int i = 0; i < currSchemaDepends.size(); i++) {
1486:                        schemasToProcess.push(currSchemaDepends.elementAt(i));
1487:                    }
1488:                } // while
1489:            } // end traverseSchemas
1490:
1491:            // store whether we have reported an error about that no grammar
1492:            // is found for the given namespace uri
1493:            private Vector fReportedTNS = null;
1494:
1495:            // check whether we need to report an error against the given uri.
1496:            // if we have reported an error, then we don't need to report again;
1497:            // otherwise we reported the error, and remember this fact.
1498:            private final boolean needReportTNSError(String uri) {
1499:                if (fReportedTNS == null)
1500:                    fReportedTNS = new Vector();
1501:                else if (fReportedTNS.contains(uri))
1502:                    return false;
1503:                fReportedTNS.addElement(uri);
1504:                return true;
1505:            }
1506:
1507:            private static final String[] COMP_TYPE = {
1508:                    null, // index 0
1509:                    "attribute declaration", "attribute group",
1510:                    "element declaration", "group", "identity constraint",
1511:                    "notation", "type definition", };
1512:
1513:            private static final String[] CIRCULAR_CODES = { "Internal-Error",
1514:                    "Internal-Error", "src-attribute_group.3",
1515:                    "e-props-correct.6", "mg-props-correct.2",
1516:                    "Internal-Error", "Internal-Error", "st-props-correct.2", //or ct-props-correct.3
1517:            };
1518:
1519:            // since it is forbidden for traversers to talk to each other
1520:            // directly (except wen a traverser encounters a local declaration),
1521:            // this provides a generic means for a traverser to call
1522:            // for the traversal of some declaration.  An XSDocumentInfo is
1523:            // required because the XSDocumentInfo that the traverser is traversing
1524:            // may bear no relation to the one the handler is operating on.
1525:            // This method will:
1526:            // 1.  See if a global definition matching declToTraverse exists;
1527:            // 2. if so, determine if there is a path from currSchema to the
1528:            // schema document where declToTraverse lives (i.e., do a lookup
1529:            // in DependencyMap);
1530:            // 3. depending on declType (which will be relevant to step 1 as
1531:            // well), call the appropriate traverser with the appropriate
1532:            // XSDocumentInfo object.
1533:            // This method returns whatever the traverser it called returned;
1534:            // this will be an Object of some kind
1535:            // that lives in the Grammar.
1536:            protected Object getGlobalDecl(XSDocumentInfo currSchema,
1537:                    int declType, QName declToTraverse, Element elmNode) {
1538:
1539:                if (DEBUG_NODE_POOL) {
1540:                    System.out.println("TRAVERSE_GL: "
1541:                            + declToTraverse.toString());
1542:                }
1543:                // from the schema spec, all built-in types are present in all schemas,
1544:                // so if the requested component is a type, and could be found in the
1545:                // default schema grammar, we should return that type.
1546:                // otherwise (since we would support user-defined schema grammar) we'll
1547:                // use the normal way to get the decl
1548:                if (declToTraverse.uri != null
1549:                        && declToTraverse.uri == SchemaSymbols.URI_SCHEMAFORSCHEMA) {
1550:                    if (declType == TYPEDECL_TYPE) {
1551:                        Object retObj = SchemaGrammar.SG_SchemaNS
1552:                                .getGlobalTypeDecl(declToTraverse.localpart);
1553:                        if (retObj != null)
1554:                            return retObj;
1555:                    }
1556:                }
1557:
1558:                // now check whether this document can access the requsted namespace
1559:                if (!currSchema.isAllowedNS(declToTraverse.uri)) {
1560:                    // cannot get to this schema from the one containing the requesting decl
1561:                    if (currSchema.needReportTNSError(declToTraverse.uri)) {
1562:                        String code = declToTraverse.uri == null ? "src-resolve.4.1"
1563:                                : "src-resolve.4.2";
1564:                        reportSchemaError(code, new Object[] {
1565:                                fDoc2SystemId.get(currSchema.fSchemaElement),
1566:                                declToTraverse.uri, declToTraverse.rawname },
1567:                                elmNode);
1568:                    }
1569:                    return null;
1570:                }
1571:
1572:                // check whether there is grammar for the requested namespace
1573:                SchemaGrammar sGrammar = fGrammarBucket
1574:                        .getGrammar(declToTraverse.uri);
1575:                if (sGrammar == null) {
1576:                    if (needReportTNSError(declToTraverse.uri))
1577:                        reportSchemaError("src-resolve", new Object[] {
1578:                                declToTraverse.rawname, COMP_TYPE[declType] },
1579:                                elmNode);
1580:                    return null;
1581:                }
1582:
1583:                // if there is such grammar, check whether the requested component is in the grammar
1584:                Object retObj = null;
1585:                switch (declType) {
1586:                case ATTRIBUTE_TYPE:
1587:                    retObj = sGrammar
1588:                            .getGlobalAttributeDecl(declToTraverse.localpart);
1589:                    break;
1590:                case ATTRIBUTEGROUP_TYPE:
1591:                    retObj = sGrammar
1592:                            .getGlobalAttributeGroupDecl(declToTraverse.localpart);
1593:                    break;
1594:                case ELEMENT_TYPE:
1595:                    retObj = sGrammar
1596:                            .getGlobalElementDecl(declToTraverse.localpart);
1597:                    break;
1598:                case GROUP_TYPE:
1599:                    retObj = sGrammar
1600:                            .getGlobalGroupDecl(declToTraverse.localpart);
1601:                    break;
1602:                case IDENTITYCONSTRAINT_TYPE:
1603:                    retObj = sGrammar
1604:                            .getIDConstraintDecl(declToTraverse.localpart);
1605:                    break;
1606:                case NOTATION_TYPE:
1607:                    retObj = sGrammar
1608:                            .getGlobalNotationDecl(declToTraverse.localpart);
1609:                    break;
1610:                case TYPEDECL_TYPE:
1611:                    retObj = sGrammar
1612:                            .getGlobalTypeDecl(declToTraverse.localpart);
1613:                    break;
1614:                }
1615:
1616:                // if the component is parsed, return it
1617:                if (retObj != null)
1618:                    return retObj;
1619:
1620:                XSDocumentInfo schemaWithDecl = null;
1621:                Element decl = null;
1622:                XSDocumentInfo declDoc = null;
1623:
1624:                // the component is not parsed, try to find a DOM element for it
1625:                String declKey = declToTraverse.uri == null ? ","
1626:                        + declToTraverse.localpart : declToTraverse.uri + ","
1627:                        + declToTraverse.localpart;
1628:                switch (declType) {
1629:                case ATTRIBUTE_TYPE:
1630:                    decl = (Element) fUnparsedAttributeRegistry.get(declKey);
1631:                    declDoc = (XSDocumentInfo) fUnparsedAttributeRegistrySub
1632:                            .get(declKey);
1633:                    break;
1634:                case ATTRIBUTEGROUP_TYPE:
1635:                    decl = (Element) fUnparsedAttributeGroupRegistry
1636:                            .get(declKey);
1637:                    declDoc = (XSDocumentInfo) fUnparsedAttributeGroupRegistrySub
1638:                            .get(declKey);
1639:                    break;
1640:                case ELEMENT_TYPE:
1641:                    decl = (Element) fUnparsedElementRegistry.get(declKey);
1642:                    declDoc = (XSDocumentInfo) fUnparsedElementRegistrySub
1643:                            .get(declKey);
1644:                    break;
1645:                case GROUP_TYPE:
1646:                    decl = (Element) fUnparsedGroupRegistry.get(declKey);
1647:                    declDoc = (XSDocumentInfo) fUnparsedGroupRegistrySub
1648:                            .get(declKey);
1649:                    break;
1650:                case IDENTITYCONSTRAINT_TYPE:
1651:                    decl = (Element) fUnparsedIdentityConstraintRegistry
1652:                            .get(declKey);
1653:                    declDoc = (XSDocumentInfo) fUnparsedIdentityConstraintRegistrySub
1654:                            .get(declKey);
1655:                    break;
1656:                case NOTATION_TYPE:
1657:                    decl = (Element) fUnparsedNotationRegistry.get(declKey);
1658:                    declDoc = (XSDocumentInfo) fUnparsedNotationRegistrySub
1659:                            .get(declKey);
1660:                    break;
1661:                case TYPEDECL_TYPE:
1662:                    decl = (Element) fUnparsedTypeRegistry.get(declKey);
1663:                    declDoc = (XSDocumentInfo) fUnparsedTypeRegistrySub
1664:                            .get(declKey);
1665:                    break;
1666:                default:
1667:                    reportSchemaError(
1668:                            "Internal-Error",
1669:                            new Object[] { "XSDHandler asked to locate component of type "
1670:                                    + declType
1671:                                    + "; it does not recognize this type!" },
1672:                            elmNode);
1673:                }
1674:
1675:                // no DOM element found, so the component can't be located
1676:                if (decl == null) {
1677:                    reportSchemaError("src-resolve", new Object[] {
1678:                            declToTraverse.rawname, COMP_TYPE[declType] },
1679:                            elmNode);
1680:                    return null;
1681:                }
1682:
1683:                // get the schema doc containing the component to be parsed
1684:                // it should always return non-null value, but since null-checking
1685:                // comes for free, let's be safe and check again
1686:                schemaWithDecl = findXSDocumentForDecl(currSchema, decl,
1687:                        declDoc);
1688:                if (schemaWithDecl == null) {
1689:                    // cannot get to this schema from the one containing the requesting decl
1690:                    String code = declToTraverse.uri == null ? "src-resolve.4.1"
1691:                            : "src-resolve.4.2";
1692:                    reportSchemaError(code, new Object[] {
1693:                            fDoc2SystemId.get(currSchema.fSchemaElement),
1694:                            declToTraverse.uri, declToTraverse.rawname },
1695:                            elmNode);
1696:                    return null;
1697:                }
1698:                // a component is hidden, meaning either it's traversed, or being traversed.
1699:                // but we didn't find it in the grammar, so it's the latter case, and
1700:                // a circular reference. error!
1701:                if (DOMUtil.isHidden(decl, fHiddenNodes)) {
1702:                    String code = CIRCULAR_CODES[declType];
1703:                    if (declType == TYPEDECL_TYPE) {
1704:                        if (SchemaSymbols.ELT_COMPLEXTYPE.equals(DOMUtil
1705:                                .getLocalName(decl)))
1706:                            code = "ct-props-correct.3";
1707:                    }
1708:                    // decl must not be null if we're here...
1709:                    reportSchemaError(code,
1710:                            new Object[] { declToTraverse.prefix + ":"
1711:                                    + declToTraverse.localpart }, elmNode);
1712:                    return null;
1713:                }
1714:
1715:                DOMUtil.setHidden(decl, fHiddenNodes);
1716:                SchemaNamespaceSupport nsSupport = null;
1717:                // if the parent is <redefine> use the namespace delcs for it.
1718:                Element parent = DOMUtil.getParent(decl);
1719:                if (DOMUtil.getLocalName(parent).equals(
1720:                        SchemaSymbols.ELT_REDEFINE))
1721:                    nsSupport = (SchemaNamespaceSupport) fRedefine2NSSupport
1722:                            .get(parent);
1723:                // back up the current SchemaNamespaceSupport, because we need to provide
1724:                // a fresh one to the traverseGlobal methods.
1725:                schemaWithDecl.backupNSSupport(nsSupport);
1726:
1727:                // traverse the referenced global component
1728:                switch (declType) {
1729:                case ATTRIBUTE_TYPE:
1730:                    retObj = fAttributeTraverser.traverseGlobal(decl,
1731:                            schemaWithDecl, sGrammar);
1732:                    break;
1733:                case ATTRIBUTEGROUP_TYPE:
1734:                    retObj = fAttributeGroupTraverser.traverseGlobal(decl,
1735:                            schemaWithDecl, sGrammar);
1736:                    break;
1737:                case ELEMENT_TYPE:
1738:                    retObj = fElementTraverser.traverseGlobal(decl,
1739:                            schemaWithDecl, sGrammar);
1740:                    break;
1741:                case GROUP_TYPE:
1742:                    retObj = fGroupTraverser.traverseGlobal(decl,
1743:                            schemaWithDecl, sGrammar);
1744:                    break;
1745:                case IDENTITYCONSTRAINT_TYPE:
1746:                    // identity constraints should have been parsed already...
1747:                    // we should never get here
1748:                    retObj = null;
1749:                    break;
1750:                case NOTATION_TYPE:
1751:                    retObj = fNotationTraverser.traverse(decl, schemaWithDecl,
1752:                            sGrammar);
1753:                    break;
1754:                case TYPEDECL_TYPE:
1755:                    if (DOMUtil.getLocalName(decl).equals(
1756:                            SchemaSymbols.ELT_COMPLEXTYPE))
1757:                        retObj = fComplexTypeTraverser.traverseGlobal(decl,
1758:                                schemaWithDecl, sGrammar);
1759:                    else
1760:                        retObj = fSimpleTypeTraverser.traverseGlobal(decl,
1761:                                schemaWithDecl, sGrammar);
1762:                }
1763:
1764:                // restore the previous SchemaNamespaceSupport, so that the caller can get
1765:                // proper namespace binding.
1766:                schemaWithDecl.restoreNSSupport();
1767:
1768:                return retObj;
1769:            } // getGlobalDecl(XSDocumentInfo, int, QName):  Object
1770:
1771:            // This method determines whether there is a group
1772:            // (attributeGroup) which the given one has redefined by
1773:            // restriction.  If so, it returns it; else it returns null.
1774:            // @param type:  whether what's been redefined is an
1775:            // attributeGroup or a group;
1776:            // @param name:  the QName of the component doing the redefining.
1777:            // @param currSchema:  schema doc in which the redefining component lives.
1778:            // @return:  Object representing decl redefined if present, null
1779:            // otherwise.
1780:            Object getGrpOrAttrGrpRedefinedByRestriction(int type, QName name,
1781:                    XSDocumentInfo currSchema, Element elmNode) {
1782:                String realName = name.uri != null ? name.uri + ","
1783:                        + name.localpart : "," + name.localpart;
1784:                String nameToFind = null;
1785:                switch (type) {
1786:                case ATTRIBUTEGROUP_TYPE:
1787:                    nameToFind = (String) fRedefinedRestrictedAttributeGroupRegistry
1788:                            .get(realName);
1789:                    break;
1790:                case GROUP_TYPE:
1791:                    nameToFind = (String) fRedefinedRestrictedGroupRegistry
1792:                            .get(realName);
1793:                    break;
1794:                default:
1795:                    return null;
1796:                }
1797:                if (nameToFind == null)
1798:                    return null;
1799:                int commaPos = nameToFind.indexOf(",");
1800:                QName qNameToFind = new QName(XMLSymbols.EMPTY_STRING,
1801:                        nameToFind.substring(commaPos + 1), nameToFind
1802:                                .substring(commaPos), (commaPos == 0) ? null
1803:                                : nameToFind.substring(0, commaPos));
1804:                Object retObj = getGlobalDecl(currSchema, type, qNameToFind,
1805:                        elmNode);
1806:                if (retObj == null) {
1807:                    switch (type) {
1808:                    case ATTRIBUTEGROUP_TYPE:
1809:                        reportSchemaError("src-redefine.7.2.1",
1810:                                new Object[] { name.localpart }, elmNode);
1811:                        break;
1812:                    case GROUP_TYPE:
1813:                        reportSchemaError("src-redefine.6.2.1",
1814:                                new Object[] { name.localpart }, elmNode);
1815:                        break;
1816:                    }
1817:                    return null;
1818:                }
1819:                return retObj;
1820:            } // getGrpOrAttrGrpRedefinedByRestriction(int, QName, XSDocumentInfo):  Object
1821:
1822:            // Since ID constraints can occur in local elements, unless we
1823:            // wish to completely traverse all our DOM trees looking for ID
1824:            // constraints while we're building our global name registries,
1825:            // which seems terribly inefficient, we need to resolve keyrefs
1826:            // after all parsing is complete.  This we can simply do by running through
1827:            // fIdentityConstraintRegistry and calling traverseKeyRef on all
1828:            // of the KeyRef nodes.  This unfortunately removes this knowledge
1829:            // from the elementTraverser class (which must ignore keyrefs),
1830:            // but there seems to be no efficient way around this...
1831:            protected void resolveKeyRefs() {
1832:                for (int i = 0; i < fKeyrefStackPos; i++) {
1833:                    XSDocumentInfo keyrefSchemaDoc = fKeyrefsMapXSDocumentInfo[i];
1834:                    keyrefSchemaDoc.fNamespaceSupport.makeGlobal();
1835:                    keyrefSchemaDoc.fNamespaceSupport
1836:                            .setEffectiveContext(fKeyrefNamespaceContext[i]);
1837:                    SchemaGrammar keyrefGrammar = fGrammarBucket
1838:                            .getGrammar(keyrefSchemaDoc.fTargetNamespace);
1839:                    // need to set <keyref> to hidden before traversing it,
1840:                    // because it has global scope
1841:                    DOMUtil.setHidden(fKeyrefs[i], fHiddenNodes);
1842:                    fKeyrefTraverser.traverse(fKeyrefs[i], fKeyrefElems[i],
1843:                            keyrefSchemaDoc, keyrefGrammar);
1844:                }
1845:            } // end resolveKeyRefs
1846:
1847:            // an accessor method.  Just makes sure callers
1848:            // who want the Identity constraint registry vaguely know what they're about.
1849:            protected Hashtable getIDRegistry() {
1850:                return fUnparsedIdentityConstraintRegistry;
1851:            }
1852:
1853:            // an accessor method.  
1854:            protected Hashtable getIDRegistry_sub() {
1855:                return fUnparsedIdentityConstraintRegistrySub;
1856:            }
1857:
1858:            // This method squirrels away <keyref> declarations--along with the element
1859:            // decls and namespace bindings they might find handy.
1860:            protected void storeKeyRef(Element keyrefToStore,
1861:                    XSDocumentInfo schemaDoc, XSElementDecl currElemDecl) {
1862:                String keyrefName = DOMUtil.getAttrValue(keyrefToStore,
1863:                        SchemaSymbols.ATT_NAME);
1864:                if (keyrefName.length() != 0) {
1865:                    String keyrefQName = schemaDoc.fTargetNamespace == null ? ","
1866:                            + keyrefName
1867:                            : schemaDoc.fTargetNamespace + "," + keyrefName;
1868:                    checkForDuplicateNames(keyrefQName,
1869:                            fUnparsedIdentityConstraintRegistry,
1870:                            fUnparsedIdentityConstraintRegistrySub,
1871:                            keyrefToStore, schemaDoc);
1872:                }
1873:                // now set up all the registries we'll need...
1874:
1875:                // check array sizes
1876:                if (fKeyrefStackPos == fKeyrefs.length) {
1877:                    Element[] elemArray = new Element[fKeyrefStackPos
1878:                            + INC_KEYREF_STACK_AMOUNT];
1879:                    System
1880:                            .arraycopy(fKeyrefs, 0, elemArray, 0,
1881:                                    fKeyrefStackPos);
1882:                    fKeyrefs = elemArray;
1883:                    XSElementDecl[] declArray = new XSElementDecl[fKeyrefStackPos
1884:                            + INC_KEYREF_STACK_AMOUNT];
1885:                    System.arraycopy(fKeyrefElems, 0, declArray, 0,
1886:                            fKeyrefStackPos);
1887:                    fKeyrefElems = declArray;
1888:                    String[][] stringArray = new String[fKeyrefStackPos
1889:                            + INC_KEYREF_STACK_AMOUNT][];
1890:                    System.arraycopy(fKeyrefNamespaceContext, 0, stringArray,
1891:                            0, fKeyrefStackPos);
1892:                    fKeyrefNamespaceContext = stringArray;
1893:
1894:                    XSDocumentInfo[] xsDocumentInfo = new XSDocumentInfo[fKeyrefStackPos
1895:                            + INC_KEYREF_STACK_AMOUNT];
1896:                    System.arraycopy(fKeyrefsMapXSDocumentInfo, 0,
1897:                            xsDocumentInfo, 0, fKeyrefStackPos);
1898:                    fKeyrefsMapXSDocumentInfo = xsDocumentInfo;
1899:
1900:                }
1901:                fKeyrefs[fKeyrefStackPos] = keyrefToStore;
1902:                fKeyrefElems[fKeyrefStackPos] = currElemDecl;
1903:                fKeyrefNamespaceContext[fKeyrefStackPos] = schemaDoc.fNamespaceSupport
1904:                        .getEffectiveLocalContext();
1905:
1906:                fKeyrefsMapXSDocumentInfo[fKeyrefStackPos++] = schemaDoc;
1907:            } // storeKeyref (Element, XSDocumentInfo, XSElementDecl): void
1908:
1909:            /**
1910:             * resolveSchema method is responsible for resolving location of the schema (using XMLEntityResolver),
1911:             * and if it was succefully resolved getting the schema Document.
1912:             * @param desc
1913:             * @param mustResolve
1914:             * @param referElement
1915:             * @return A schema Element or null.
1916:             */
1917:            private Element resolveSchema(XSDDescription desc,
1918:                    boolean mustResolve, Element referElement, boolean usePairs) {
1919:                XMLInputSource schemaSource = null;
1920:                try {
1921:                    Hashtable pairs = usePairs ? fLocationPairs : EMPTY_TABLE;
1922:                    schemaSource = XMLSchemaLoader.resolveDocument(desc, pairs,
1923:                            fEntityResolver);
1924:                } catch (IOException ex) {
1925:                    if (mustResolve) {
1926:                        reportSchemaError("schema_reference.4",
1927:                                new Object[] { desc.getLocationHints()[0] },
1928:                                referElement);
1929:                    } else {
1930:                        reportSchemaWarning("schema_reference.4",
1931:                                new Object[] { desc.getLocationHints()[0] },
1932:                                referElement);
1933:                    }
1934:                }
1935:                if (schemaSource instanceof  DOMInputSource) {
1936:                    fHiddenNodes.clear();
1937:                    Node node = ((DOMInputSource) schemaSource).getNode();
1938:
1939:                    if (node instanceof  Document) {
1940:                        return DOMUtil.getRoot((Document) node);
1941:                    } else if (node instanceof  Element) {
1942:                        return (Element) node;
1943:                    } else {
1944:                        return null;
1945:                    }
1946:                } // DOMInputSource
1947:                else if (schemaSource instanceof  SAXInputSource) {
1948:                    XMLReader parser = ((SAXInputSource) schemaSource)
1949:                            .getXMLReader();
1950:                    InputSource inputSource = ((SAXInputSource) schemaSource)
1951:                            .getInputSource();
1952:                    boolean namespacePrefixes = false;
1953:                    if (parser != null) {
1954:                        try {
1955:                            namespacePrefixes = parser
1956:                                    .getFeature(NAMESPACE_PREFIXES);
1957:                        } catch (SAXException se) {
1958:                        }
1959:                    } else {
1960:                        try {
1961:                            parser = XMLReaderFactory.createXMLReader();
1962:                        }
1963:                        // If something went wrong with the factory
1964:                        // just use our own SAX parser.
1965:                        catch (SAXException se) {
1966:                            parser = new SAXParser();
1967:                        }
1968:                        try {
1969:                            parser.setFeature(NAMESPACE_PREFIXES, true);
1970:                            namespacePrefixes = true;
1971:                        } catch (SAXException se) {
1972:                        }
1973:                    }
1974:                    // If XML names and Namespace URIs are already internalized we
1975:                    // can avoid running them through the SymbolTable.
1976:                    boolean stringsInternalized = false;
1977:                    try {
1978:                        stringsInternalized = parser
1979:                                .getFeature(STRING_INTERNING);
1980:                    } catch (SAXException exc) {
1981:                        // The feature isn't recognized or getting it is not supported.
1982:                        // In either case, assume that strings are not internalized.
1983:                    }
1984:                    if (fXSContentHandler == null) {
1985:                        fXSContentHandler = new SchemaContentHandler();
1986:                    }
1987:                    fXSContentHandler.reset(fSchemaParser, fSymbolTable,
1988:                            namespacePrefixes, stringsInternalized);
1989:                    parser.setContentHandler(fXSContentHandler);
1990:                    parser.setErrorHandler(fErrorReporter.getSAXErrorHandler());
1991:                    try {
1992:                        parser.parse(inputSource);
1993:                    } catch (SAXException se) {
1994:                        return null;
1995:                    } catch (IOException ioe) {
1996:                        return null;
1997:                    }
1998:                    Document root = fXSContentHandler.getDocument();
1999:                    if (root == null) {
2000:                        // something went wrong right off the hop
2001:                        return null;
2002:                    }
2003:                    return DOMUtil.getRoot(root);
2004:                }
2005:                return getSchemaDocument(desc.getTargetNamespace(),
2006:                        schemaSource, mustResolve, desc.getContextType(),
2007:                        referElement);
2008:            } // getSchema(String, String, String, boolean, short):  Document
2009:
2010:            /**
2011:             * getSchemaDocument method uses XMLInputSource to parse a schema document.
2012:             * @param schemaNamespace
2013:             * @param schemaSource
2014:             * @param mustResolve
2015:             * @param referType
2016:             * @param referElement
2017:             * @return A schema Element.
2018:             */
2019:            private Element getSchemaDocument(String schemaNamespace,
2020:                    XMLInputSource schemaSource, boolean mustResolve,
2021:                    short referType, Element referElement) {
2022:
2023:                boolean hasInput = true;
2024:                // contents of this method will depend on the system we adopt for entity resolution--i.e., XMLEntityHandler, EntityHandler, etc.
2025:                Element schemaElement = null;
2026:                try {
2027:                    // when the system id and byte stream and character stream
2028:                    // of the input source are all null, it's
2029:                    // impossible to find the schema document. so we skip in
2030:                    // this case. otherwise we'll receive some NPE or
2031:                    // file not found errors. but schemaHint=="" is perfectly
2032:                    // legal for import.
2033:                    if (schemaSource != null
2034:                            && (schemaSource.getSystemId() != null
2035:                                    || schemaSource.getByteStream() != null || schemaSource
2036:                                    .getCharacterStream() != null)) {
2037:
2038:                        // When the system id of the input source is used, first try to
2039:                        // expand it, and check whether the same document has been
2040:                        // parsed before. If so, return the document corresponding to
2041:                        // that system id.
2042:                        XSDKey key = null;
2043:                        String schemaId = null;
2044:                        if (referType != XSDDescription.CONTEXT_PREPARSE) {
2045:                            schemaId = XMLEntityManager.expandSystemId(
2046:                                    schemaSource.getSystemId(), schemaSource
2047:                                            .getBaseSystemId(), false);
2048:                            key = new XSDKey(schemaId, referType,
2049:                                    schemaNamespace);
2050:                            if ((schemaElement = (Element) fTraversed.get(key)) != null) {
2051:                                fLastSchemaWasDuplicate = true;
2052:                                return schemaElement;
2053:                            }
2054:                        }
2055:
2056:                        fSchemaParser.parse(schemaSource);
2057:                        schemaElement = fSchemaParser.getDocument2() == null ? null
2058:                                : DOMUtil.getRoot(fSchemaParser.getDocument2());
2059:
2060:                        // now we need to store the mapping information from system id
2061:                        // to the document. also from the document to the system id.
2062:                        if (key != null)
2063:                            fTraversed.put(key, schemaElement);
2064:                        if (schemaId != null)
2065:                            fDoc2SystemId.put(schemaElement, schemaId);
2066:                        fLastSchemaWasDuplicate = false;
2067:                        return schemaElement;
2068:                    } else {
2069:                        hasInput = false;
2070:                    }
2071:                } catch (IOException ex) {
2072:                }
2073:
2074:                // either an error occured (exception), or empty input source was
2075:                // returned, we need to report an error or a warning
2076:                if (mustResolve) {
2077:                    if (hasInput) {
2078:                        reportSchemaError("schema_reference.4",
2079:                                new Object[] { schemaSource.getSystemId() },
2080:                                referElement);
2081:                    } else {
2082:                        reportSchemaError("schema_reference.4",
2083:                                new Object[] { schemaSource == null ? ""
2084:                                        : schemaSource.getSystemId() },
2085:                                referElement);
2086:                    }
2087:                } else if (hasInput) {
2088:                    reportSchemaWarning("schema_reference.4",
2089:                            new Object[] { schemaSource.getSystemId() },
2090:                            referElement);
2091:                }
2092:
2093:                fLastSchemaWasDuplicate = false;
2094:                return null;
2095:            } // getSchema(String, XMLInputSource, boolean, boolean): Document
2096:
2097:            // initialize all the traversers.
2098:            // this should only need to be called once during the construction
2099:            // of this object; it creates the traversers that will be used to
2100:
2101:            // construct schemaGrammars.
2102:            private void createTraversers() {
2103:                fAttributeChecker = new XSAttributeChecker(this );
2104:                fAttributeGroupTraverser = new XSDAttributeGroupTraverser(this ,
2105:                        fAttributeChecker);
2106:                fAttributeTraverser = new XSDAttributeTraverser(this ,
2107:                        fAttributeChecker);
2108:                fComplexTypeTraverser = new XSDComplexTypeTraverser(this ,
2109:                        fAttributeChecker);
2110:                fElementTraverser = new XSDElementTraverser(this ,
2111:                        fAttributeChecker);
2112:                fGroupTraverser = new XSDGroupTraverser(this , fAttributeChecker);
2113:                fKeyrefTraverser = new XSDKeyrefTraverser(this ,
2114:                        fAttributeChecker);
2115:                fNotationTraverser = new XSDNotationTraverser(this ,
2116:                        fAttributeChecker);
2117:                fSimpleTypeTraverser = new XSDSimpleTypeTraverser(this ,
2118:                        fAttributeChecker);
2119:                fUniqueOrKeyTraverser = new XSDUniqueOrKeyTraverser(this ,
2120:                        fAttributeChecker);
2121:                fWildCardTraverser = new XSDWildcardTraverser(this ,
2122:                        fAttributeChecker);
2123:            } // createTraversers()
2124:
2125:            // before parsing a schema, need to clear registries associated with
2126:            // parsing schemas
2127:            void prepareForParse() {
2128:                fTraversed.clear();
2129:                fDoc2SystemId.clear();
2130:                fHiddenNodes.clear();
2131:                fLastSchemaWasDuplicate = false;
2132:            }
2133:
2134:            // before traversing a schema's parse tree, need to reset all traversers and
2135:            // clear all registries
2136:            void prepareForTraverse() {
2137:                fUnparsedAttributeRegistry.clear();
2138:                fUnparsedAttributeGroupRegistry.clear();
2139:                fUnparsedElementRegistry.clear();
2140:                fUnparsedGroupRegistry.clear();
2141:                fUnparsedIdentityConstraintRegistry.clear();
2142:                fUnparsedNotationRegistry.clear();
2143:                fUnparsedTypeRegistry.clear();
2144:
2145:                fUnparsedAttributeRegistrySub.clear();
2146:                fUnparsedAttributeGroupRegistrySub.clear();
2147:                fUnparsedElementRegistrySub.clear();
2148:                fUnparsedGroupRegistrySub.clear();
2149:                fUnparsedIdentityConstraintRegistrySub.clear();
2150:                fUnparsedNotationRegistrySub.clear();
2151:                fUnparsedTypeRegistrySub.clear();
2152:
2153:                fXSDocumentInfoRegistry.clear();
2154:                fDependencyMap.clear();
2155:                fDoc2XSDocumentMap.clear();
2156:                fRedefine2XSDMap.clear();
2157:                fRedefine2NSSupport.clear();
2158:                fAllTNSs.removeAllElements();
2159:                fImportMap.clear();
2160:                fRoot = null;
2161:
2162:                // clear local element stack
2163:                for (int i = 0; i < fLocalElemStackPos; i++) {
2164:                    fParticle[i] = null;
2165:                    fLocalElementDecl[i] = null;
2166:                    fLocalElementDecl_schema[i] = null;
2167:                    fLocalElemNamespaceContext[i] = null;
2168:                }
2169:                fLocalElemStackPos = 0;
2170:
2171:                // and do same for keyrefs.
2172:                for (int i = 0; i < fKeyrefStackPos; i++) {
2173:                    fKeyrefs[i] = null;
2174:                    fKeyrefElems[i] = null;
2175:                    fKeyrefNamespaceContext[i] = null;
2176:                    fKeyrefsMapXSDocumentInfo[i] = null;
2177:                }
2178:                fKeyrefStackPos = 0;
2179:
2180:                // create traversers if necessary
2181:                if (fAttributeChecker == null) {
2182:                    createTraversers();
2183:                }
2184:
2185:                // reset traversers
2186:                fAttributeChecker.reset(fSymbolTable);
2187:                fAttributeGroupTraverser.reset(fSymbolTable,
2188:                        fValidateAnnotations);
2189:                fAttributeTraverser.reset(fSymbolTable, fValidateAnnotations);
2190:                fComplexTypeTraverser.reset(fSymbolTable, fValidateAnnotations);
2191:                fElementTraverser.reset(fSymbolTable, fValidateAnnotations);
2192:                fGroupTraverser.reset(fSymbolTable, fValidateAnnotations);
2193:                fKeyrefTraverser.reset(fSymbolTable, fValidateAnnotations);
2194:                fNotationTraverser.reset(fSymbolTable, fValidateAnnotations);
2195:                fSimpleTypeTraverser.reset(fSymbolTable, fValidateAnnotations);
2196:                fUniqueOrKeyTraverser.reset(fSymbolTable, fValidateAnnotations);
2197:                fWildCardTraverser.reset(fSymbolTable, fValidateAnnotations);
2198:
2199:                fRedefinedRestrictedAttributeGroupRegistry.clear();
2200:                fRedefinedRestrictedGroupRegistry.clear();
2201:            }
2202:
2203:            public void setDeclPool(XSDeclarationPool declPool) {
2204:                fDeclPool = declPool;
2205:            }
2206:
2207:            public void reset(XMLComponentManager componentManager) {
2208:
2209:                // set symbol table
2210:                fSymbolTable = (SymbolTable) componentManager
2211:                        .getProperty(SYMBOL_TABLE);
2212:
2213:                //set entity resolver
2214:                fEntityResolver = (XMLEntityResolver) componentManager
2215:                        .getProperty(ENTITY_MANAGER);
2216:                XMLEntityResolver er = (XMLEntityResolver) componentManager
2217:                        .getProperty(ENTITY_RESOLVER);
2218:                if (er != null)
2219:                    fSchemaParser.setEntityResolver(er);
2220:
2221:                // set error reporter
2222:                fErrorReporter = (XMLErrorReporter) componentManager
2223:                        .getProperty(ERROR_REPORTER);
2224:                try {
2225:                    XMLErrorHandler currErrorHandler = fErrorReporter
2226:                            .getErrorHandler();
2227:                    // Setting a parser property can be much more expensive
2228:                    // than checking its value.  Don't set the ERROR_HANDLER
2229:                    // property unless it's actually changed.
2230:                    if (currErrorHandler != fSchemaParser
2231:                            .getProperty(ERROR_HANDLER)) {
2232:                        fSchemaParser.setProperty(ERROR_HANDLER,
2233:                                (currErrorHandler != null) ? currErrorHandler
2234:                                        : new DefaultErrorHandler());
2235:                        if (fAnnotationValidator != null) {
2236:                            fAnnotationValidator
2237:                                    .setProperty(
2238:                                            ERROR_HANDLER,
2239:                                            (currErrorHandler != null) ? currErrorHandler
2240:                                                    : new DefaultErrorHandler());
2241:                        }
2242:                    }
2243:                } catch (XMLConfigurationException e) {
2244:                }
2245:
2246:                try {
2247:                    fValidateAnnotations = componentManager
2248:                            .getFeature(VALIDATE_ANNOTATIONS);
2249:                } catch (XMLConfigurationException e) {
2250:                    fValidateAnnotations = false;
2251:                }
2252:
2253:                try {
2254:                    fHonourAllSchemaLocations = componentManager
2255:                            .getFeature(HONOUR_ALL_SCHEMALOCATIONS);
2256:                } catch (XMLConfigurationException e) {
2257:                    fHonourAllSchemaLocations = false;
2258:                }
2259:
2260:                try {
2261:                    fSchemaParser.setFeature(CONTINUE_AFTER_FATAL_ERROR,
2262:                            fErrorReporter
2263:                                    .getFeature(CONTINUE_AFTER_FATAL_ERROR));
2264:                } catch (XMLConfigurationException e) {
2265:                }
2266:
2267:                try {
2268:                    fSchemaParser.setFeature(ALLOW_JAVA_ENCODINGS,
2269:                            componentManager.getFeature(ALLOW_JAVA_ENCODINGS));
2270:                } catch (XMLConfigurationException e) {
2271:                }
2272:                try {
2273:                    fSchemaParser
2274:                            .setFeature(
2275:                                    STANDARD_URI_CONFORMANT_FEATURE,
2276:                                    componentManager
2277:                                            .getFeature(STANDARD_URI_CONFORMANT_FEATURE));
2278:                } catch (XMLConfigurationException e) {
2279:                }
2280:
2281:                try {
2282:                    fGrammarPool = (XMLGrammarPool) componentManager
2283:                            .getProperty(XMLGRAMMAR_POOL);
2284:                } catch (XMLConfigurationException e) {
2285:                    fGrammarPool = null;
2286:                }
2287:                // security features
2288:                try {
2289:                    fSchemaParser.setFeature(DISALLOW_DOCTYPE, componentManager
2290:                            .getFeature(DISALLOW_DOCTYPE));
2291:                } catch (XMLConfigurationException e) {
2292:                }
2293:                try {
2294:                    Object security = componentManager
2295:                            .getProperty(SECURITY_MANAGER);
2296:                    if (security != null) {
2297:                        fSchemaParser.setProperty(SECURITY_MANAGER, security);
2298:                    }
2299:                } catch (XMLConfigurationException e) {
2300:                }
2301:
2302:            } // reset(XMLComponentManager)
2303:
2304:            /**
2305:             * Traverse all the deferred local elements. This method should be called
2306:             * by traverseSchemas after we've done with all the global declarations.
2307:             */
2308:            void traverseLocalElements() {
2309:                fElementTraverser.fDeferTraversingLocalElements = false;
2310:
2311:                for (int i = 0; i < fLocalElemStackPos; i++) {
2312:                    Element currElem = fLocalElementDecl[i];
2313:                    //XSDocumentInfo currSchema = (XSDocumentInfo)fDoc2XSDocumentMap.get(DOMUtil.getDocument(currElem));
2314:                    //XSDocumentInfo currSchema = (XSDocumentInfo)fDoc2XSDocumentMap.get(DOMUtil.getRoot(DOMUtil.getDocument(currElem)));
2315:                    XSDocumentInfo currSchema = fLocalElementDecl_schema[i];
2316:                    SchemaGrammar currGrammar = fGrammarBucket
2317:                            .getGrammar(currSchema.fTargetNamespace);
2318:                    fElementTraverser.traverseLocal(fParticle[i], currElem,
2319:                            currSchema, currGrammar, fAllContext[i],
2320:                            fParent[i], fLocalElemNamespaceContext[i]);
2321:                    // If it's an empty particle, remove it from the containing component.
2322:                    if (fParticle[i].fType == XSParticleDecl.PARTICLE_EMPTY) {
2323:                        XSModelGroupImpl group = null;
2324:                        if (fParent[i] instanceof  XSComplexTypeDecl) {
2325:                            XSParticle p = ((XSComplexTypeDecl) fParent[i])
2326:                                    .getParticle();
2327:                            if (p != null)
2328:                                group = (XSModelGroupImpl) p.getTerm();
2329:                        } else {
2330:                            group = ((XSGroupDecl) fParent[i]).fModelGroup;
2331:                        }
2332:                        if (group != null)
2333:                            removeParticle(group, fParticle[i]);
2334:                    }
2335:                }
2336:            }
2337:
2338:            private boolean removeParticle(XSModelGroupImpl group,
2339:                    XSParticleDecl particle) {
2340:                XSParticleDecl member;
2341:                for (int i = 0; i < group.fParticleCount; i++) {
2342:                    member = group.fParticles[i];
2343:                    if (member == particle) {
2344:                        for (int j = i; j < group.fParticleCount - 1; j++)
2345:                            group.fParticles[j] = group.fParticles[j + 1];
2346:                        group.fParticleCount--;
2347:                        return true;
2348:                    }
2349:                    if (member.fType == XSParticleDecl.PARTICLE_MODELGROUP) {
2350:                        if (removeParticle((XSModelGroupImpl) member.fValue,
2351:                                particle))
2352:                            return true;
2353:                    }
2354:                }
2355:                return false;
2356:            }
2357:
2358:            // the purpose of this method is to keep up-to-date structures
2359:            // we'll need for the feferred traversal of local elements.
2360:            void fillInLocalElemInfo(Element elmDecl, XSDocumentInfo schemaDoc,
2361:                    int allContextFlags, XSObject parent,
2362:                    XSParticleDecl particle) {
2363:
2364:                // if the stack is full, increase the size
2365:                if (fParticle.length == fLocalElemStackPos) {
2366:                    // increase size
2367:                    XSParticleDecl[] newStackP = new XSParticleDecl[fLocalElemStackPos
2368:                            + INC_STACK_SIZE];
2369:                    System.arraycopy(fParticle, 0, newStackP, 0,
2370:                            fLocalElemStackPos);
2371:                    fParticle = newStackP;
2372:                    Element[] newStackE = new Element[fLocalElemStackPos
2373:                            + INC_STACK_SIZE];
2374:                    System.arraycopy(fLocalElementDecl, 0, newStackE, 0,
2375:                            fLocalElemStackPos);
2376:                    fLocalElementDecl = newStackE;
2377:                    XSDocumentInfo[] newStackE_schema = new XSDocumentInfo[fLocalElemStackPos
2378:                            + INC_STACK_SIZE];
2379:                    System.arraycopy(fLocalElementDecl_schema, 0,
2380:                            newStackE_schema, 0, fLocalElemStackPos);
2381:                    fLocalElementDecl_schema = newStackE_schema;
2382:                    int[] newStackI = new int[fLocalElemStackPos
2383:                            + INC_STACK_SIZE];
2384:                    System.arraycopy(fAllContext, 0, newStackI, 0,
2385:                            fLocalElemStackPos);
2386:                    fAllContext = newStackI;
2387:                    XSObject[] newStackC = new XSObject[fLocalElemStackPos
2388:                            + INC_STACK_SIZE];
2389:                    System.arraycopy(fParent, 0, newStackC, 0,
2390:                            fLocalElemStackPos);
2391:                    fParent = newStackC;
2392:                    String[][] newStackN = new String[fLocalElemStackPos
2393:                            + INC_STACK_SIZE][];
2394:                    System.arraycopy(fLocalElemNamespaceContext, 0, newStackN,
2395:                            0, fLocalElemStackPos);
2396:                    fLocalElemNamespaceContext = newStackN;
2397:                }
2398:
2399:                fParticle[fLocalElemStackPos] = particle;
2400:                fLocalElementDecl[fLocalElemStackPos] = elmDecl;
2401:                fLocalElementDecl_schema[fLocalElemStackPos] = schemaDoc;
2402:                fAllContext[fLocalElemStackPos] = allContextFlags;
2403:                fParent[fLocalElemStackPos] = parent;
2404:                fLocalElemNamespaceContext[fLocalElemStackPos++] = schemaDoc.fNamespaceSupport
2405:                        .getEffectiveLocalContext();
2406:            } // end fillInLocalElemInfo(...)
2407:
2408:            /** This method makes sure that
2409:             * if this component is being redefined that it lives in the
2410:             * right schema.  It then renames the component correctly.  If it
2411:             * detects a collision--a duplicate definition--then it complains.
2412:             * Note that redefines must be handled carefully:  if there
2413:             * is a collision, it may be because we're redefining something we know about
2414:             * or because we've found the thing we're redefining.
2415:             */
2416:            void checkForDuplicateNames(String qName, Hashtable registry,
2417:                    Hashtable registry_sub, Element currComp,
2418:                    XSDocumentInfo currSchema) {
2419:                Object objElem = null;
2420:                // REVISIT:  when we add derivation checking, we'll have to make
2421:                // sure that ID constraint collisions don't necessarily result in error messages.
2422:                if ((objElem = registry.get(qName)) == null) {
2423:                    // just add it in!
2424:                    registry.put(qName, currComp);
2425:                    registry_sub.put(qName, currSchema);
2426:
2427:                } else {
2428:                    Element collidingElem = (Element) objElem;
2429:                    XSDocumentInfo collidingElemSchema = (XSDocumentInfo) registry_sub
2430:                            .get(qName);
2431:                    if (collidingElem == currComp)
2432:                        return;
2433:                    Element elemParent = null;
2434:                    XSDocumentInfo redefinedSchema = null;
2435:                    // case where we've collided with a redefining element
2436:                    // (the parent of the colliding element is a redefine)
2437:                    boolean collidedWithRedefine = true;
2438:                    if ((DOMUtil.getLocalName((elemParent = DOMUtil
2439:                            .getParent(collidingElem)))
2440:                            .equals(SchemaSymbols.ELT_REDEFINE))) {
2441:                        redefinedSchema = (XSDocumentInfo) (fRedefine2XSDMap
2442:                                .get(elemParent));
2443:                        // case where we're a redefining element.
2444:                    } else if ((DOMUtil.getLocalName(DOMUtil
2445:                            .getParent(currComp))
2446:                            .equals(SchemaSymbols.ELT_REDEFINE))) {
2447:                        redefinedSchema = collidingElemSchema;
2448:                        collidedWithRedefine = false;
2449:                    }
2450:                    if (redefinedSchema != null) { //redefinition involved somehow
2451:                        // If both components belong to the same document then
2452:                        // report an error and return.
2453:                        if (collidingElemSchema == currSchema) {
2454:                            reportSchemaError("sch-props-correct.2",
2455:                                    new Object[] { qName }, currComp);
2456:                            return;
2457:                        }
2458:
2459:                        String newName = qName
2460:                                .substring(qName.lastIndexOf(',') + 1)
2461:                                + REDEF_IDENTIFIER;
2462:                        if (redefinedSchema == currSchema) { // object comp. okay here
2463:                            // now have to do some renaming...
2464:                            currComp.setAttribute(SchemaSymbols.ATT_NAME,
2465:                                    newName);
2466:                            if (currSchema.fTargetNamespace == null) {
2467:                                registry.put("," + newName, currComp);
2468:                                registry_sub.put("," + newName, currSchema);
2469:                            } else {
2470:                                registry.put(currSchema.fTargetNamespace + ","
2471:                                        + newName, currComp);
2472:                                registry_sub.put(currSchema.fTargetNamespace
2473:                                        + "," + newName, currSchema);
2474:                            }
2475:                            // and take care of nested redefines by calling recursively:
2476:                            if (currSchema.fTargetNamespace == null)
2477:                                checkForDuplicateNames("," + newName, registry,
2478:                                        registry_sub, currComp, currSchema);
2479:                            else
2480:                                checkForDuplicateNames(
2481:                                        currSchema.fTargetNamespace + ","
2482:                                                + newName, registry,
2483:                                        registry_sub, currComp, currSchema);
2484:                        } else { // we may be redefining the wrong schema
2485:                            if (collidedWithRedefine) {
2486:                                if (currSchema.fTargetNamespace == null)
2487:                                    checkForDuplicateNames("," + newName,
2488:                                            registry, registry_sub, currComp,
2489:                                            currSchema);
2490:                                else
2491:                                    checkForDuplicateNames(
2492:                                            currSchema.fTargetNamespace + ","
2493:                                                    + newName, registry,
2494:                                            registry_sub, currComp, currSchema);
2495:                            } else {
2496:                                // error that redefined element in wrong schema
2497:                                reportSchemaError("sch-props-correct.2",
2498:                                        new Object[] { qName }, currComp);
2499:                            }
2500:                        }
2501:                    } else {
2502:                        // we've just got a flat-out collision
2503:                        reportSchemaError("sch-props-correct.2",
2504:                                new Object[] { qName }, currComp);
2505:                    }
2506:                }
2507:            } // checkForDuplicateNames(String, Hashtable, Element, XSDocumentInfo):void
2508:
2509:            // the purpose of this method is to take the component of the
2510:            // specified type and rename references to itself so that they
2511:            // refer to the object being redefined.  It takes special care of
2512:            // <group>s and <attributeGroup>s to ensure that information
2513:            // relating to implicit restrictions is preserved for those
2514:            // traversers.
2515:            private void renameRedefiningComponents(XSDocumentInfo currSchema,
2516:                    Element child, String componentType, String oldName,
2517:                    String newName) {
2518:                if (componentType.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
2519:                    Element grandKid = DOMUtil.getFirstChildElement(child);
2520:                    if (grandKid == null) {
2521:                        reportSchemaError("src-redefine.5.a.a", null, child);
2522:                    } else {
2523:                        String grandKidName = DOMUtil.getLocalName(grandKid);
2524:                        if (grandKidName.equals(SchemaSymbols.ELT_ANNOTATION)) {
2525:                            grandKid = DOMUtil.getNextSiblingElement(grandKid);
2526:                        }
2527:                        if (grandKid == null) {
2528:                            reportSchemaError("src-redefine.5.a.a", null, child);
2529:                        } else {
2530:                            grandKidName = DOMUtil.getLocalName(grandKid);
2531:                            if (!grandKidName
2532:                                    .equals(SchemaSymbols.ELT_RESTRICTION)) {
2533:                                reportSchemaError("src-redefine.5.a.b",
2534:                                        new Object[] { grandKidName }, child);
2535:                            } else {
2536:                                Object[] attrs = fAttributeChecker
2537:                                        .checkAttributes(grandKid, false,
2538:                                                currSchema);
2539:                                QName derivedBase = (QName) attrs[XSAttributeChecker.ATTIDX_BASE];
2540:                                if (derivedBase == null
2541:                                        || derivedBase.uri != currSchema.fTargetNamespace
2542:                                        || !derivedBase.localpart
2543:                                                .equals(oldName)) {
2544:                                    reportSchemaError(
2545:                                            "src-redefine.5.a.c",
2546:                                            new Object[] {
2547:                                                    grandKidName,
2548:                                                    (currSchema.fTargetNamespace == null ? ""
2549:                                                            : currSchema.fTargetNamespace)
2550:                                                            + "," + oldName },
2551:                                            child);
2552:                                } else {
2553:                                    // now we have to do the renaming...
2554:                                    if (derivedBase.prefix != null
2555:                                            && derivedBase.prefix.length() > 0)
2556:                                        grandKid.setAttribute(
2557:                                                SchemaSymbols.ATT_BASE,
2558:                                                derivedBase.prefix + ":"
2559:                                                        + newName);
2560:                                    else
2561:                                        grandKid
2562:                                                .setAttribute(
2563:                                                        SchemaSymbols.ATT_BASE,
2564:                                                        newName);
2565:                                    //                            return true;
2566:                                }
2567:                                fAttributeChecker.returnAttrArray(attrs,
2568:                                        currSchema);
2569:                            }
2570:                        }
2571:                    }
2572:                } else if (componentType.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
2573:                    Element grandKid = DOMUtil.getFirstChildElement(child);
2574:                    if (grandKid == null) {
2575:                        reportSchemaError("src-redefine.5.b.a", null, child);
2576:                    } else {
2577:                        if (DOMUtil.getLocalName(grandKid).equals(
2578:                                SchemaSymbols.ELT_ANNOTATION)) {
2579:                            grandKid = DOMUtil.getNextSiblingElement(grandKid);
2580:                        }
2581:                        if (grandKid == null) {
2582:                            reportSchemaError("src-redefine.5.b.a", null, child);
2583:                        } else {
2584:                            // have to go one more level down; let another pass worry whether complexType is valid.
2585:                            Element greatGrandKid = DOMUtil
2586:                                    .getFirstChildElement(grandKid);
2587:                            if (greatGrandKid == null) {
2588:                                reportSchemaError("src-redefine.5.b.b", null,
2589:                                        grandKid);
2590:                            } else {
2591:                                String greatGrandKidName = DOMUtil
2592:                                        .getLocalName(greatGrandKid);
2593:                                if (greatGrandKidName
2594:                                        .equals(SchemaSymbols.ELT_ANNOTATION)) {
2595:                                    greatGrandKid = DOMUtil
2596:                                            .getNextSiblingElement(greatGrandKid);
2597:                                }
2598:                                if (greatGrandKid == null) {
2599:                                    reportSchemaError("src-redefine.5.b.b",
2600:                                            null, grandKid);
2601:                                } else {
2602:                                    greatGrandKidName = DOMUtil
2603:                                            .getLocalName(greatGrandKid);
2604:                                    if (!greatGrandKidName
2605:                                            .equals(SchemaSymbols.ELT_RESTRICTION)
2606:                                            && !greatGrandKidName
2607:                                                    .equals(SchemaSymbols.ELT_EXTENSION)) {
2608:                                        reportSchemaError(
2609:                                                "src-redefine.5.b.c",
2610:                                                new Object[] { greatGrandKidName },
2611:                                                greatGrandKid);
2612:                                    } else {
2613:                                        Object[] attrs = fAttributeChecker
2614:                                                .checkAttributes(greatGrandKid,
2615:                                                        false, currSchema);
2616:                                        QName derivedBase = (QName) attrs[XSAttributeChecker.ATTIDX_BASE];
2617:                                        if (derivedBase == null
2618:                                                || derivedBase.uri != currSchema.fTargetNamespace
2619:                                                || !derivedBase.localpart
2620:                                                        .equals(oldName)) {
2621:                                            reportSchemaError(
2622:                                                    "src-redefine.5.b.d",
2623:                                                    new Object[] {
2624:                                                            greatGrandKidName,
2625:                                                            (currSchema.fTargetNamespace == null ? ""
2626:                                                                    : currSchema.fTargetNamespace)
2627:                                                                    + ","
2628:                                                                    + oldName },
2629:                                                    greatGrandKid);
2630:                                        } else {
2631:                                            // now we have to do the renaming...
2632:                                            if (derivedBase.prefix != null
2633:                                                    && derivedBase.prefix
2634:                                                            .length() > 0)
2635:                                                greatGrandKid
2636:                                                        .setAttribute(
2637:                                                                SchemaSymbols.ATT_BASE,
2638:                                                                derivedBase.prefix
2639:                                                                        + ":"
2640:                                                                        + newName);
2641:                                            else
2642:                                                greatGrandKid.setAttribute(
2643:                                                        SchemaSymbols.ATT_BASE,
2644:                                                        newName);
2645:                                            //                                    return true;
2646:                                        }
2647:                                    }
2648:                                }
2649:                            }
2650:                        }
2651:                    }
2652:                } else if (componentType
2653:                        .equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
2654:                    String processedBaseName = (currSchema.fTargetNamespace == null) ? ","
2655:                            + oldName
2656:                            : currSchema.fTargetNamespace + "," + oldName;
2657:                    int attGroupRefsCount = changeRedefineGroup(
2658:                            processedBaseName, componentType, newName, child,
2659:                            currSchema);
2660:                    if (attGroupRefsCount > 1) {
2661:                        reportSchemaError(
2662:                                "src-redefine.7.1",
2663:                                new Object[] { new Integer(attGroupRefsCount) },
2664:                                child);
2665:                    } else if (attGroupRefsCount == 1) {
2666:                        //                return true;
2667:                    } else if (currSchema.fTargetNamespace == null)
2668:                        fRedefinedRestrictedAttributeGroupRegistry.put(
2669:                                processedBaseName, "," + newName);
2670:                    else
2671:                        fRedefinedRestrictedAttributeGroupRegistry.put(
2672:                                processedBaseName, currSchema.fTargetNamespace
2673:                                        + "," + newName);
2674:                } else if (componentType.equals(SchemaSymbols.ELT_GROUP)) {
2675:                    String processedBaseName = (currSchema.fTargetNamespace == null) ? ","
2676:                            + oldName
2677:                            : currSchema.fTargetNamespace + "," + oldName;
2678:                    int groupRefsCount = changeRedefineGroup(processedBaseName,
2679:                            componentType, newName, child, currSchema);
2680:                    if (groupRefsCount > 1) {
2681:                        reportSchemaError("src-redefine.6.1.1",
2682:                                new Object[] { new Integer(groupRefsCount) },
2683:                                child);
2684:                    } else if (groupRefsCount == 1) {
2685:                        //                return true;
2686:                    } else {
2687:                        if (currSchema.fTargetNamespace == null)
2688:                            fRedefinedRestrictedGroupRegistry.put(
2689:                                    processedBaseName, "," + newName);
2690:                        else
2691:                            fRedefinedRestrictedGroupRegistry
2692:                                    .put(processedBaseName,
2693:                                            currSchema.fTargetNamespace + ","
2694:                                                    + newName);
2695:                    }
2696:                } else {
2697:                    reportSchemaError(
2698:                            "Internal-Error",
2699:                            new Object[] { "could not handle this particular <redefine>; please submit your schemas and instance document in a bug report!" },
2700:                            child);
2701:                }
2702:                // if we get here then we must have reported an error and failed somewhere...
2703:                //        return false;
2704:            } // renameRedefiningComponents(XSDocumentInfo, Element, String, String, String):void
2705:
2706:            // this method takes a name of the form a:b, determines the URI mapped
2707:            // to by a in the current SchemaNamespaceSupport object, and returns this
2708:            // information in the form (nsURI,b) suitable for lookups in the global
2709:            // decl Hashtables.
2710:            // REVISIT: should have it return QName, instead of String. this would
2711:            //          save lots of string concatenation time. we can use
2712:            //          QName#equals() to compare two QNames, and use QName directly
2713:            //          as a key to the SymbolHash.
2714:            //          And when the DV's are ready to return compiled values from
2715:            //          validate() method, we should just call QNameDV.validate()
2716:            //          in this method.
2717:            private String findQName(String name, XSDocumentInfo schemaDoc) {
2718:                SchemaNamespaceSupport currNSMap = schemaDoc.fNamespaceSupport;
2719:                int colonPtr = name.indexOf(':');
2720:                String prefix = XMLSymbols.EMPTY_STRING;
2721:                if (colonPtr > 0)
2722:                    prefix = name.substring(0, colonPtr);
2723:                String uri = currNSMap.getURI(fSymbolTable.addSymbol(prefix));
2724:                String localpart = (colonPtr == 0) ? name : name
2725:                        .substring(colonPtr + 1);
2726:                if (prefix == XMLSymbols.EMPTY_STRING && uri == null
2727:                        && schemaDoc.fIsChameleonSchema)
2728:                    uri = schemaDoc.fTargetNamespace;
2729:                if (uri == null)
2730:                    return "," + localpart;
2731:                return uri + "," + localpart;
2732:            } // findQName(String, XSDocumentInfo):  String
2733:
2734:            // This function looks among the children of curr for an element of type elementSought.
2735:            // If it finds one, it evaluates whether its ref attribute contains a reference
2736:            // to originalQName.  If it does, it returns 1 + the value returned by
2737:            // calls to itself on all other children.  In all other cases it returns 0 plus
2738:            // the sum of the values returned by calls to itself on curr's children.
2739:            // It also resets the value of ref so that it will refer to the renamed type from the schema
2740:            // being redefined.
2741:            private int changeRedefineGroup(String originalQName,
2742:                    String elementSought, String newName, Element curr,
2743:                    XSDocumentInfo schemaDoc) {
2744:                int result = 0;
2745:                for (Element child = DOMUtil.getFirstChildElement(curr); child != null; child = DOMUtil
2746:                        .getNextSiblingElement(child)) {
2747:                    String name = DOMUtil.getLocalName(child);
2748:                    if (!name.equals(elementSought))
2749:                        result += changeRedefineGroup(originalQName,
2750:                                elementSought, newName, child, schemaDoc);
2751:                    else {
2752:                        String ref = child.getAttribute(SchemaSymbols.ATT_REF);
2753:                        if (ref.length() != 0) {
2754:                            String processedRef = findQName(ref, schemaDoc);
2755:                            if (originalQName.equals(processedRef)) {
2756:                                String prefix = XMLSymbols.EMPTY_STRING;
2757:                                int colonptr = ref.indexOf(":");
2758:                                if (colonptr > 0) {
2759:                                    prefix = ref.substring(0, colonptr);
2760:                                    child.setAttribute(SchemaSymbols.ATT_REF,
2761:                                            prefix + ":" + newName);
2762:                                } else
2763:                                    child.setAttribute(SchemaSymbols.ATT_REF,
2764:                                            newName);
2765:                                result++;
2766:                                if (elementSought
2767:                                        .equals(SchemaSymbols.ELT_GROUP)) {
2768:                                    String minOccurs = child
2769:                                            .getAttribute(SchemaSymbols.ATT_MINOCCURS);
2770:                                    String maxOccurs = child
2771:                                            .getAttribute(SchemaSymbols.ATT_MAXOCCURS);
2772:                                    if (!((maxOccurs.length() == 0 || maxOccurs
2773:                                            .equals("1")) && (minOccurs
2774:                                            .length() == 0 || minOccurs
2775:                                            .equals("1")))) {
2776:                                        reportSchemaError("src-redefine.6.1.2",
2777:                                                new Object[] { ref }, child);
2778:                                    }
2779:                                }
2780:                            }
2781:                        } // if ref was null some other stage of processing will flag the error
2782:                    }
2783:                }
2784:                return result;
2785:            } // changeRedefineGroup
2786:
2787:            // this method returns the XSDocumentInfo object that contains the
2788:            // component corresponding to decl.  If components from this
2789:            // document cannot be referred to from those of currSchema, this
2790:            // method returns null; it's up to the caller to throw an error.
2791:            // @param:  currSchema:  the XSDocumentInfo object containing the
2792:            // decl ref'ing us.
2793:            // @param:  decl:  the declaration being ref'd.
2794:            // this method is superficial now. ---Jack
2795:            private XSDocumentInfo findXSDocumentForDecl(
2796:                    XSDocumentInfo currSchema, Element decl,
2797:                    XSDocumentInfo decl_Doc) {
2798:
2799:                if (DEBUG_NODE_POOL) {
2800:                    System.out.println("DOCUMENT NS:"
2801:                            + currSchema.fTargetNamespace + " hashcode:"
2802:                            + ((Object) currSchema.fSchemaElement).hashCode());
2803:                }
2804:                Object temp = decl_Doc;
2805:                if (temp == null) {
2806:                    // something went badly wrong; we don't know this doc?
2807:                    return null;
2808:                }
2809:                XSDocumentInfo declDocInfo = (XSDocumentInfo) temp;
2810:                return declDocInfo;
2811:                /*********
2812:                 Logic here is unnecessary after schema WG's recent decision to allow
2813:                 schema components from one document to refer to components of any other,
2814:                 so long as there's some include/import/redefine path amongst them.
2815:                 If they rver reverse this decision the code's right here though...  - neilg
2816:                 // now look in fDependencyMap to see if this is reachable
2817:                  if(((Vector)fDependencyMap.get(currSchema)).contains(declDocInfo)) {
2818:                  return declDocInfo;
2819:                  }
2820:                  // obviously the requesting doc didn't include, redefine or
2821:                   // import the one containing decl...
2822:                    return null;
2823:                 **********/
2824:            } // findXSDocumentForDecl(XSDocumentInfo, Element):  XSDocumentInfo
2825:
2826:            // returns whether more than <annotation>s occur in children of elem
2827:            private boolean nonAnnotationContent(Element elem) {
2828:                for (Element child = DOMUtil.getFirstChildElement(elem); child != null; child = DOMUtil
2829:                        .getNextSiblingElement(child)) {
2830:                    if (!(DOMUtil.getLocalName(child)
2831:                            .equals(SchemaSymbols.ELT_ANNOTATION)))
2832:                        return true;
2833:                }
2834:                return false;
2835:            } // nonAnnotationContent(Element):  boolean
2836:
2837:            private void setSchemasVisible(XSDocumentInfo startSchema) {
2838:                if (DOMUtil.isHidden(startSchema.fSchemaElement, fHiddenNodes)) {
2839:                    // make it visible
2840:                    DOMUtil
2841:                            .setVisible(startSchema.fSchemaElement,
2842:                                    fHiddenNodes);
2843:                    Vector dependingSchemas = (Vector) fDependencyMap
2844:                            .get(startSchema);
2845:                    for (int i = 0; i < dependingSchemas.size(); i++) {
2846:                        setSchemasVisible((XSDocumentInfo) dependingSchemas
2847:                                .elementAt(i));
2848:                    }
2849:                }
2850:                // if it's visible already than so must be its children
2851:            } // setSchemasVisible(XSDocumentInfo): void
2852:
2853:            private SimpleLocator xl = new SimpleLocator();
2854:
2855:            /**
2856:             * Extract location information from an Element node, and create a
2857:             * new SimpleLocator object from such information. Returning null means
2858:             * no information can be retrieved from the element.
2859:             */
2860:            public SimpleLocator element2Locator(Element e) {
2861:                if (!(e instanceof  ElementImpl))
2862:                    return null;
2863:
2864:                SimpleLocator l = new SimpleLocator();
2865:                return element2Locator(e, l) ? l : null;
2866:            }
2867:
2868:            /**
2869:             * Extract location information from an Element node, store such
2870:             * information in the passed-in SimpleLocator object, then return
2871:             * true. Returning false means can't extract or store such information.
2872:             */
2873:            public boolean element2Locator(Element e, SimpleLocator l) {
2874:                if (l == null)
2875:                    return false;
2876:                if (e instanceof  ElementImpl) {
2877:                    ElementImpl ele = (ElementImpl) e;
2878:                    // get system id from document object
2879:                    Document doc = ele.getOwnerDocument();
2880:                    String sid = (String) fDoc2SystemId.get(DOMUtil
2881:                            .getRoot(doc));
2882:                    // line/column numbers are stored in the element node
2883:                    int line = ele.getLineNumber();
2884:                    int column = ele.getColumnNumber();
2885:                    l.setValues(sid, sid, line, column, ele
2886:                            .getCharacterOffset());
2887:                    return true;
2888:                }
2889:                return false;
2890:            }
2891:
2892:            void reportSchemaError(String key, Object[] args, Element ele) {
2893:                if (element2Locator(ele, xl)) {
2894:                    fErrorReporter.reportError(xl,
2895:                            XSMessageFormatter.SCHEMA_DOMAIN, key, args,
2896:                            XMLErrorReporter.SEVERITY_ERROR);
2897:                } else {
2898:                    fErrorReporter.reportError(
2899:                            XSMessageFormatter.SCHEMA_DOMAIN, key, args,
2900:                            XMLErrorReporter.SEVERITY_ERROR);
2901:                }
2902:            }
2903:
2904:            void reportSchemaWarning(String key, Object[] args, Element ele) {
2905:                if (element2Locator(ele, xl)) {
2906:                    fErrorReporter.reportError(xl,
2907:                            XSMessageFormatter.SCHEMA_DOMAIN, key, args,
2908:                            XMLErrorReporter.SEVERITY_WARNING);
2909:                } else {
2910:                    fErrorReporter.reportError(
2911:                            XSMessageFormatter.SCHEMA_DOMAIN, key, args,
2912:                            XMLErrorReporter.SEVERITY_WARNING);
2913:                }
2914:            }
2915:
2916:            /**
2917:             * Grammar pool used for validating annotations. This will return all of the
2918:             * grammars from the grammar bucket. It will also return an object for the
2919:             * schema for schemas which will contain at least the relevant declarations
2920:             * for annotations.
2921:             */
2922:            private static class XSAnnotationGrammarPool implements 
2923:                    XMLGrammarPool {
2924:
2925:                private XSGrammarBucket fGrammarBucket;
2926:                private Grammar[] fInitialGrammarSet;
2927:
2928:                public Grammar[] retrieveInitialGrammarSet(String grammarType) {
2929:                    if (grammarType == XMLGrammarDescription.XML_SCHEMA) {
2930:                        if (fInitialGrammarSet == null) {
2931:                            if (fGrammarBucket == null) {
2932:                                fInitialGrammarSet = new Grammar[] { SchemaGrammar.SG_Schema4Annotations };
2933:                            } else {
2934:                                SchemaGrammar[] schemaGrammars = fGrammarBucket
2935:                                        .getGrammars();
2936:                                /** 
2937:                                 * If the grammar bucket already contains the schema for schemas
2938:                                 * then we already have the definitions for the parts relevant
2939:                                 * to annotations.
2940:                                 */
2941:                                for (int i = 0; i < schemaGrammars.length; ++i) {
2942:                                    if (SchemaSymbols.URI_SCHEMAFORSCHEMA
2943:                                            .equals(schemaGrammars[i]
2944:                                                    .getTargetNamespace())) {
2945:                                        fInitialGrammarSet = schemaGrammars;
2946:                                        return fInitialGrammarSet;
2947:                                    }
2948:                                }
2949:                                Grammar[] grammars = new Grammar[schemaGrammars.length + 1];
2950:                                System.arraycopy(schemaGrammars, 0, grammars,
2951:                                        0, schemaGrammars.length);
2952:                                grammars[grammars.length - 1] = SchemaGrammar.SG_Schema4Annotations;
2953:                                fInitialGrammarSet = grammars;
2954:                            }
2955:                        }
2956:                        return fInitialGrammarSet;
2957:                    }
2958:                    return new Grammar[0];
2959:                }
2960:
2961:                public void cacheGrammars(String grammarType, Grammar[] grammars) {
2962:
2963:                }
2964:
2965:                public Grammar retrieveGrammar(XMLGrammarDescription desc) {
2966:                    if (desc.getGrammarType() == XMLGrammarDescription.XML_SCHEMA) {
2967:                        final String tns = ((XMLSchemaDescription) desc)
2968:                                .getTargetNamespace();
2969:                        if (fGrammarBucket != null) {
2970:                            Grammar grammar = fGrammarBucket.getGrammar(tns);
2971:                            if (grammar != null) {
2972:                                return grammar;
2973:                            }
2974:                        }
2975:                        if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(tns)) {
2976:                            return SchemaGrammar.SG_Schema4Annotations;
2977:                        }
2978:                    }
2979:                    return null;
2980:                }
2981:
2982:                public void refreshGrammars(XSGrammarBucket gBucket) {
2983:                    fGrammarBucket = gBucket;
2984:                    fInitialGrammarSet = null;
2985:                }
2986:
2987:                public void lockPool() {
2988:                }
2989:
2990:                public void unlockPool() {
2991:                }
2992:
2993:                public void clear() {
2994:                }
2995:            }
2996:
2997:            /**
2998:             * used to identify a reference to a schema document
2999:             * if the same document is referenced twice with the same key, then
3000:             * we only need to parse it once.
3001:             *
3002:             * When 2 XSDKey's are compared, the following table can be used to
3003:             * determine whether they are equal:
3004:             *      inc     red     imp     pre     ins
3005:             * inc  N/L      ?      N/L     N/L     N/L
3006:             * red   ?      N/L      ?       ?       ?
3007:             * imp  N/L      ?      N/P     N/P     N/P
3008:             * pre  N/L      ?      N/P     N/P     N/P
3009:             * ins  N/L      ?      N/P     N/P     N/P
3010:             *
3011:             * Where: N/L: duplicate when they have the same namespace and location.
3012:             *         ? : not clear from the spec.
3013:             *             REVISIT: to simplify the process, also considering
3014:             *             it's very rare, we treat them as not duplicate.
3015:             *        N/P: not possible. imp/pre/ins are referenced by namespace.
3016:             *             when the first time we encounter a schema document for a
3017:             *             namespace, we create a grammar and store it in the grammar
3018:             *             bucket. when we see another reference to the same namespace,
3019:             *             we first check whether a grammar with the same namespace is
3020:             *             already in the bucket, which is true in this case, so we
3021:             *             won't create another XSDKey.
3022:             *
3023:             * Conclusion from the table: two XSDKey's are duplicate only when all of
3024:             * the following are true:
3025:             * 1. They are both "redefine", or neither is "redefine";
3026:             * 2. They have the same namespace;
3027:             * 3. They have the same non-null location.
3028:             *
3029:             * About 3: if neither has a non-null location, then it's the case where
3030:             * 2 input streams are provided, but no system ID is provided. We can't tell
3031:             * whether the 2 streams have the same content, so we treat them as not
3032:             * duplicate.
3033:             */
3034:            private static class XSDKey {
3035:                String systemId;
3036:                short referType;
3037:                // for inclue/redefine, this is the enclosing namespace
3038:                // for import/preparse/instance, this is the target namespace
3039:                String referNS;
3040:
3041:                XSDKey(String systemId, short referType, String referNS) {
3042:                    this .systemId = systemId;
3043:                    this .referType = referType;
3044:                    this .referNS = referNS;
3045:                }
3046:
3047:                public int hashCode() {
3048:                    // according to the description at the beginning of this class,
3049:                    // we use the hashcode of the namespace as the hashcoe of this key.
3050:                    return referNS == null ? 0 : referNS.hashCode();
3051:                }
3052:
3053:                public boolean equals(Object obj) {
3054:                    if (!(obj instanceof  XSDKey)) {
3055:                        return false;
3056:                    }
3057:                    XSDKey key = (XSDKey) obj;
3058:
3059:                    // condition 1: both are redefine
3060:                    /** if (referType == XSDDescription.CONTEXT_REDEFINE ||
3061:                            key.referType == XSDDescription.CONTEXT_REDEFINE) {
3062:                        if (referType != key.referType)
3063:                            return false;
3064:                    }**/
3065:
3066:                    // condition 2: same namespace
3067:                    if (referNS != key.referNS)
3068:                        return false;
3069:
3070:                    // condition 3: same non-null location
3071:                    if (systemId == null || !systemId.equals(key.systemId)) {
3072:                        return false;
3073:                    }
3074:
3075:                    return true;
3076:                }
3077:            }
3078:
3079:            /**
3080:             * @param state
3081:             */
3082:            public void setGenerateSyntheticAnnotations(boolean state) {
3083:                fSchemaParser.setFeature(GENERATE_SYNTHETIC_ANNOTATIONS, state);
3084:            }
3085:
3086:        } // XSDHandler
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.