xsdhandler.java
来自「JAVA的一些源码 JAVA2 STANDARD EDITION DEVELO」· Java 代码 · 共 1,320 行 · 第 1/5 页
JAVA
1,320 行
private String emptyString2Null(String ns) { return ns == XMLSymbols.EMPTY_STRING ? null : ns; } // This vector stores strings which are combinations of the // publicId and systemId of the inputSource corresponding to a // schema document. This combination is used so that the user's // EntityResolver can provide a consistent way of identifying a // schema document that is included in multiple other schemas. private Hashtable fTraversed = new Hashtable(); // this hashtable contains a mapping from Document to its systemId // this is useful to resolve a uri relative to the referring document private Hashtable fDoc2SystemId = new Hashtable(); // the primary XSDocumentInfo we were called to parse private XSDocumentInfo fRoot = null; // This hashtable's job is to act as a link between the document // node at the root of the parsed schema's tree and its // XSDocumentInfo object. private Hashtable fDoc2XSDocumentMap = new Hashtable(); // map between <redefine> elements and the XSDocumentInfo // objects that correspond to the documents being redefined. private Hashtable fRedefine2XSDMap = new Hashtable(); // map between <redefine> elements and the namespace support private Hashtable fRedefine2NSSupport = new Hashtable(); // these objects store a mapping between the names of redefining // groups/attributeGroups and the groups/AttributeGroups which // they redefine by restriction (implicitly). It is up to the // Group and AttributeGroup traversers to check these restrictions for // validity. private Hashtable fRedefinedRestrictedAttributeGroupRegistry = new Hashtable(); private Hashtable fRedefinedRestrictedGroupRegistry = new Hashtable(); // a variable storing whether the last schema document // processed (by getSchema) was a duplicate. private boolean fLastSchemaWasDuplicate; // the XMLErrorReporter private XMLErrorReporter fErrorReporter; private XMLEntityResolver fEntityResolver; // the XSAttributeChecker private XSAttributeChecker fAttributeChecker; // the symbol table private SymbolTable fSymbolTable; // the GrammarResolver private XSGrammarBucket fGrammarBucket; // the Grammar description private XSDDescription fSchemaGrammarDescription; // the Grammar Pool private XMLGrammarPool fGrammarPool; //************ Traversers ********** XSDAttributeGroupTraverser fAttributeGroupTraverser; XSDAttributeTraverser fAttributeTraverser; XSDComplexTypeTraverser fComplexTypeTraverser; XSDElementTraverser fElementTraverser; XSDGroupTraverser fGroupTraverser; XSDKeyrefTraverser fKeyrefTraverser; XSDNotationTraverser fNotationTraverser; XSDSimpleTypeTraverser fSimpleTypeTraverser; XSDUniqueOrKeyTraverser fUniqueOrKeyTraverser; XSDWildcardTraverser fWildCardTraverser; //DOMParser fSchemaParser; SchemaParsingConfig fSchemaParser; // these data members are needed for the deferred traversal // of local elements. // the initial size of the array to store deferred local elements private static final int INIT_STACK_SIZE = 30; // the incremental size of the array to store deferred local elements private static final int INC_STACK_SIZE = 10; // current position of the array (# of deferred local elements) private int fLocalElemStackPos = 0; private XSParticleDecl[] fParticle = new XSParticleDecl[INIT_STACK_SIZE]; private Element[] fLocalElementDecl = new Element[INIT_STACK_SIZE]; private int[] fAllContext = new int[INIT_STACK_SIZE]; private XSObject[] fParent = new XSObject[INIT_STACK_SIZE]; private String [][] fLocalElemNamespaceContext = new String [INIT_STACK_SIZE][1]; // these data members are needed for the deferred traversal // of keyrefs. // the initial size of the array to store deferred keyrefs private static final int INIT_KEYREF_STACK = 2; // the incremental size of the array to store deferred keyrefs private static final int INC_KEYREF_STACK_AMOUNT = 2; // current position of the array (# of deferred keyrefs) private int fKeyrefStackPos = 0; private Element [] fKeyrefs = new Element[INIT_KEYREF_STACK]; private XSElementDecl [] fKeyrefElems = new XSElementDecl [INIT_KEYREF_STACK]; private String [][] fKeyrefNamespaceContext = new String[INIT_KEYREF_STACK][1]; // Constructors public XSDHandler(){ fSchemaParser = new SchemaParsingConfig(); } // it should be possible to use the same XSDHandler to parse // multiple schema documents; this will allow one to be // constructed. public XSDHandler (XSGrammarBucket gBucket) { this(); fGrammarBucket = gBucket; // Note: don't use SchemaConfiguration internally // we will get stack overflaw because // XMLSchemaValidator will be instantiating XSDHandler... fSchemaGrammarDescription = new XSDDescription(); } // end constructor /** * This method initiates the parse of a schema. It will likely be * called from the Validator and it will make the * resulting grammar available; it returns a reference to this object just * in case. A reset(XMLComponentManager) must be called before this methods is called. * @param is * @param desc * @param locationPairs * @return * @throws IOException */ public SchemaGrammar parseSchema(Source source, XSDDescription desc, Hashtable locationPairs) throws IOException { fLocationPairs = locationPairs; if (fSchemaParser != null) { fSchemaParser.resetNodePool(); } SchemaGrammar grammar = null; String schemaNamespace = null; short referType = desc.getContextType(); // if loading using JAXP schemaSource property, or using grammar caching loadGrammar // the desc.targetNamespace is always null. // Therefore we should not attempt to find out if // the schema is already in the bucket, since in the case we have // no namespace schema in the bucket, findGrammar will always return the // no namespace schema. if (referType != XSDDescription.CONTEXT_PREPARSE){ // first try to find it in the bucket/pool, return if one is found grammar = findGrammar(desc); if (grammar != null) return grammar; schemaNamespace = desc.getTargetNamespace(); // handle empty string URI as null if (schemaNamespace != null) { schemaNamespace = fSymbolTable.addSymbol(schemaNamespace); } } // before parsing a schema, need to clear registries associated with // parsing schemas prepareForParse(); // first phase: construct trees. Document schemaRoot = getSchema(schemaNamespace, source, referType == XSDDescription.CONTEXT_PREPARSE, referType, null); if (schemaRoot == null) { // something went wrong right off the hop return null; } if ( referType == XSDDescription.CONTEXT_PREPARSE) { Element schemaElem = DOMUtil.getRoot(schemaRoot); schemaNamespace = DOMUtil.getAttrValue(schemaElem, SchemaSymbols.ATT_TARGETNAMESPACE); if(schemaNamespace != null && schemaNamespace.length() > 0) { // Since now we've discovered a namespace, we need to update xsd key // and store this schema in traversed schemas bucket schemaNamespace = fSymbolTable.addSymbol(schemaNamespace); desc.setTargetNamespace(schemaNamespace); } else { schemaNamespace = null; } grammar = findGrammar(desc); if (grammar != null) return grammar; String schemaId = source.getSystemId(); XSDKey key = new XSDKey(schemaId, referType, schemaNamespace); fTraversed.put(key, schemaRoot ); if (schemaId != null) { fDoc2SystemId.put(schemaRoot, schemaId ); } } // before constructing trees and traversing a schema, need to reset // all traversers and clear all registries prepareForTraverse(); fRoot = constructTrees(schemaRoot, source.getSystemId(), desc); if (fRoot == null) { return null; } // second phase: fill global registries. buildGlobalNameRegistries(); // third phase: call traversers traverseSchemas(); // fourth phase: handle local element decls traverseLocalElements(); // fifth phase: handle Keyrefs resolveKeyRefs(); // sixth phase: validate attribute of non-schema namespaces // REVISIT: skip this for now. we really don't want to do it. //fAttributeChecker.checkNonSchemaAttributes(fGrammarBucket); // seventh phase: store imported grammars // for all grammars with <import>s for (int i = fAllTNSs.size() - 1; i >= 0; i--) { // get its target namespace String tns = (String)fAllTNSs.elementAt(i); // get all namespaces it imports Vector ins = (Vector)fImportMap.get(tns); // get the grammar SchemaGrammar sg = fGrammarBucket.getGrammar(emptyString2Null(tns)); if (sg == null) continue; SchemaGrammar isg; // for imported namespace int count = 0; for (int j = 0; j < ins.size(); j++) { // get imported grammar isg = fGrammarBucket.getGrammar((String)ins.elementAt(j)); // reuse the same vector if (isg != null) ins.setElementAt(isg, count++); } ins.setSize(count); // set the imported grammars sg.setImportedGrammars(ins); } // and return. return fGrammarBucket.getGrammar(fRoot.fTargetNamespace); } // end parseSchema /** * Pull the grammar out of the bucket simply using * its TNS as a key */ SchemaGrammar getGrammar(String tns) { return fGrammarBucket.getGrammar(tns);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?