xsdhandler.java
来自「JAVA的一些源码 JAVA2 STANDARD EDITION DEVELO」· Java 代码 · 共 1,320 行 · 第 1/5 页
JAVA
1,320 行
} /** * First try to find a grammar in the bucket, if failed, consult the * grammar pool. If a grammar is found in the pool, then add it (and all * imported ones) into the bucket. */ protected SchemaGrammar findGrammar(XSDDescription desc) { SchemaGrammar sg = fGrammarBucket.getGrammar(desc.getTargetNamespace()); if (sg == null) { if (fGrammarPool != null) { sg = (SchemaGrammar)fGrammarPool.retrieveGrammar(desc); if (sg != null) { // put this grammar into the bucket, along with grammars // imported by it (directly or indirectly) if (!fGrammarBucket.putGrammar(sg, true)) { // REVISIT: a conflict between new grammar(s) and grammars // in the bucket. What to do? A warning? An exception? reportSchemaWarning("GrammarConflict", null, null); sg = null; } } } } return sg; } // may wish to have setter methods for ErrorHandler, // EntityResolver... private static final String[][] NS_ERROR_CODES = { {"src-include.2.1", "src-include.2.1"}, {"src-redefine.3.1", "src-redefine.3.1"}, {"src-import.3.1", "src-import.3.2"}, null, {"TargetNamespace.1", "TargetNamespace.2"}, {"TargetNamespace.1", "TargetNamespace.2"}, {"TargetNamespace.1", "TargetNamespace.2"}, {"TargetNamespace.1", "TargetNamespace.2"} }; private static final String[] ELE_ERROR_CODES = { "src-include.1", "src-redefine.2", "src-import.2", "schema_reference.4", "schema_reference.4", "schema_reference.4", "schema_reference.4", "schema_reference.4" }; // This method does several things: // It constructs an instance of an XSDocumentInfo object using the // schemaRoot node. Then, for each <include>, // <redefine>, and <import> children, it attempts to resolve the // requested schema document, initiates a DOM parse, and calls // itself recursively on that document's root. It also records in // the DependencyMap object what XSDocumentInfo objects its XSDocumentInfo // depends on. // It also makes sure the targetNamespace of the schema it was // called to parse is correct. protected XSDocumentInfo constructTrees(Document schemaRoot, String locationHint, XSDDescription desc) { if (schemaRoot == null) return null; String callerTNS = desc.getTargetNamespace(); short referType = desc.getContextType(); XSDocumentInfo currSchemaInfo = null; try { // note that attributes are freed at end of traverseSchemas() currSchemaInfo = new XSDocumentInfo(schemaRoot, fAttributeChecker, fSymbolTable); } catch (XMLSchemaException se) { reportSchemaError(ELE_ERROR_CODES[referType], new Object[]{locationHint}, DOMUtil.getRoot(schemaRoot)); return null; } // targetNamespace="" is not valid, issue a warning, and ignore it if (currSchemaInfo.fTargetNamespace != null && currSchemaInfo.fTargetNamespace.length() == 0) { reportSchemaWarning("EmptyTargetNamespace", new Object[]{locationHint}, DOMUtil.getRoot(schemaRoot)); currSchemaInfo.fTargetNamespace = null; } if (callerTNS != null) { // the second index to the NS_ERROR_CODES array // if the caller/expected NS is not absent, we use the first column int secondIdx = 0; // for include and redefine if (referType == XSDDescription.CONTEXT_INCLUDE || referType == XSDDescription.CONTEXT_REDEFINE) { // if the referred document has no targetNamespace, // it's a chameleon schema if (currSchemaInfo.fTargetNamespace == null) { currSchemaInfo.fTargetNamespace = callerTNS; currSchemaInfo.fIsChameleonSchema = true; } // if the referred document has a target namespace differing // from the caller, it's an error else if (callerTNS != currSchemaInfo.fTargetNamespace) { reportSchemaError(NS_ERROR_CODES[referType][secondIdx], new Object [] {callerTNS, currSchemaInfo.fTargetNamespace}, DOMUtil.getRoot(schemaRoot)); return null; } } // for instance and import, the two NS's must be the same else if (referType != XSDDescription.CONTEXT_PREPARSE && callerTNS != currSchemaInfo.fTargetNamespace) { reportSchemaError(NS_ERROR_CODES[referType][secondIdx], new Object [] {callerTNS, currSchemaInfo.fTargetNamespace}, DOMUtil.getRoot(schemaRoot)); return null; } } // now there is no caller/expected NS, it's an error for the referred // document to have a target namespace, unless we are preparsing a schema else if (currSchemaInfo.fTargetNamespace != null) { // set the target namespace of the description if (referType == XSDDescription.CONTEXT_PREPARSE) { desc.setTargetNamespace(currSchemaInfo.fTargetNamespace); callerTNS = currSchemaInfo.fTargetNamespace; } else { // the second index to the NS_ERROR_CODES array // if the caller/expected NS is absent, we use the second column int secondIdx = 1; reportSchemaError(NS_ERROR_CODES[referType][secondIdx], new Object [] {callerTNS, currSchemaInfo.fTargetNamespace}, DOMUtil.getRoot(schemaRoot)); return null; } } // the other cases (callerTNS == currSchemaInfo.fTargetNamespce == null) // are valid // a schema document can always access it's own target namespace currSchemaInfo.addAllowedNS(currSchemaInfo.fTargetNamespace); SchemaGrammar sg = null; if (referType == XSDDescription.CONTEXT_INCLUDE || referType == XSDDescription.CONTEXT_REDEFINE) { sg = fGrammarBucket.getGrammar(currSchemaInfo.fTargetNamespace); } else { sg = new SchemaGrammar(currSchemaInfo.fTargetNamespace, desc.makeClone(), fSymbolTable); fGrammarBucket.putGrammar(sg); } // store the document and its location // REVISIT: don't expose the DOM tree //sg.addDocument(currSchemaInfo.fSchemaDoc, (String)fDoc2SystemId.get(currSchemaInfo)); sg.addDocument(null, (String)fDoc2SystemId.get(currSchemaInfo.fSchemaDoc)); fDoc2XSDocumentMap.put(schemaRoot, currSchemaInfo); Vector dependencies = new Vector(); Element rootNode = DOMUtil.getRoot(schemaRoot); Document newSchemaRoot = null; for (Element child = DOMUtil.getFirstChildElement(rootNode); child != null; child = DOMUtil.getNextSiblingElement(child)) { String schemaNamespace=null; String schemaHint=null; String localName = DOMUtil.getLocalName(child); short refType = -1; if (localName.equals(SchemaSymbols.ELT_ANNOTATION)) continue; else if (localName.equals(SchemaSymbols.ELT_IMPORT)) { refType = XSDDescription.CONTEXT_IMPORT; // have to handle some validation here too! // call XSAttributeChecker to fill in attrs Object[] importAttrs = fAttributeChecker.checkAttributes(child, true, currSchemaInfo); schemaHint = (String)importAttrs[XSAttributeChecker.ATTIDX_SCHEMALOCATION]; schemaNamespace = (String)importAttrs[XSAttributeChecker.ATTIDX_NAMESPACE]; if (schemaNamespace != null) schemaNamespace = fSymbolTable.addSymbol(schemaNamespace); // a document can't import another document with the same namespace if (schemaNamespace == currSchemaInfo.fTargetNamespace) { reportSchemaError("src-import.1.1", new Object [] {schemaNamespace}, child); } // check contents and process optional annotations Element importChild = DOMUtil.getFirstChildElement(child); if(importChild != null ) { String importComponentType = DOMUtil.getLocalName(importChild); if (importComponentType.equals(SchemaSymbols.ELT_ANNOTATION)) { // promoting annotations to parent component sg.addAnnotation( fElementTraverser.traverseAnnotationDecl(importChild, importAttrs, true, currSchemaInfo)); } else { reportSchemaError("s4s-elt-must-match.1", new Object [] {localName, "annotation?", importComponentType}, child); } if(DOMUtil.getNextSiblingElement(importChild) != null) { reportSchemaError("s4s-elt-must-match.1", new Object [] {localName, "annotation?", DOMUtil.getLocalName(DOMUtil.getNextSiblingElement(importChild))}, child); } } fAttributeChecker.returnAttrArray(importAttrs, currSchemaInfo); // if this namespace has been imported by this document, // ignore the <import> statement if (currSchemaInfo.isAllowedNS(schemaNamespace)) continue; // a schema document can access it's imported namespaces currSchemaInfo.addAllowedNS(schemaNamespace); // also record the fact that one namespace imports another one // convert null to "" String tns = null2EmptyString(currSchemaInfo.fTargetNamespace); // get all namespaces imported by this one Vector ins = (Vector)fImportMap.get(tns); // if no namespace was imported, create new Vector if (ins == null) { // record that this one imports other(s) fAllTNSs.addElement(tns); ins = new Vector(); fImportMap.put(tns, ins); ins.addElement(schemaNamespace); } else if (!ins.contains(schemaNamespace)){ ins.addElement(schemaNamespace); } fSchemaGrammarDescription.reset(); fSchemaGrammarDescription.setContextType(XSDDescription.CONTEXT_IMPORT); fSchemaGrammarDescription.setBaseSystemId((String)fDoc2SystemId.get(schemaRoot)); fSchemaGrammarDescription.setLocationHints(new String[]{schemaHint}); fSchemaGrammarDescription.setTargetNamespace(schemaNamespace); // if a grammar with the same namespace exists (or being // built), ignore this one (don't traverse it). if (findGrammar(fSchemaGrammarDescription) != null) continue; newSchemaRoot = resolveSchema(fSchemaGrammarDescription, false, child); } else if ((localName.equals(SchemaSymbols.ELT_INCLUDE)) || (localName.equals(SchemaSymbols.ELT_REDEFINE))) { // validation for redefine/include will be the same here; just // make sure TNS is right (don't care about redef contents // yet). Object[] includeAttrs = fAttributeChecker.checkAttributes(child, true, currSchemaInfo); schemaHint = (String)includeAttrs[XSAttributeChecker.ATTIDX_SCHEMALOCATION]; // store the namespace decls of the redefine element if (localName.equals(SchemaSymbols.ELT_REDEFINE)) { fRedefine2NSSupport.put(child, new SchemaNamespaceSupport(currSchemaInfo.fNamespaceSupport)); } // check annotations. Must do this here to avoid having to // re-parse attributes later if(localName.equals(SchemaSymbols.ELT_INCLUDE)) { Element includeChild = DOMUtil.getFirstChildElement(child); if(includeChild != null ) { String includeComponentType = DOMUtil.getLocalName(includeChild); if (includeComponentType.equals(SchemaSymbols.ELT_ANNOTATION)) { // promoting annotations to parent component sg.addAnnotation( fElementTraverser.traverseAnnotationDecl(includeChild, includeAttrs, true, currSchemaInfo)); } else { reportSchemaError("s4s-elt-must-match.1", new Object [] {localName, "annotation?", includeComponentType}, child); } if(DOMUtil.getNextSiblingElement(includeChild) != null) { reportSchemaError("s4s-elt-must-match.1", new Object [] {localName, "annotation?", DOMUtil.getLocalName(DOMUtil.getNextSiblingElement(includeChild))}, child); } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?