📄 xsdhandler.java
字号:
// something went wrong right off the hop return null; } schemaRoot = DOMUtil.getRoot(schemaRootDoc); } else { schemaRoot = getSchemaDocument(schemaNamespace, is, referType == XSDDescription.CONTEXT_PREPARSE, referType, null); }//is instanceof XMLInputSource if(schemaRoot == null){ // something went wrong right off the hop return null; } if ( referType == XSDDescription.CONTEXT_PREPARSE) { Element schemaElem = 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 = XMLEntityManager.expandSystemId(is.getSystemId(), is.getBaseSystemId(), false); 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, is.getSystemId(), desc); if (fRoot == null) { return null; } // second phase: fill global registries. buildGlobalNameRegistries(); // third phase: call traversers ArrayList annotationInfo = fValidateAnnotations ? new ArrayList() : null; traverseSchemas(annotationInfo); // 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); } /** validate annotations **/ if (fValidateAnnotations && annotationInfo.size() > 0) { validateAnnotations(annotationInfo); } // and return. return fGrammarBucket.getGrammar(fRoot.fTargetNamespace); } // end parseSchema private void validateAnnotations(ArrayList annotationInfo) { if (fAnnotationValidator == null) { createAnnotationValidator(); } final int size = annotationInfo.size(); final XMLInputSource src = new XMLInputSource(null, null, null); fGrammarBucketAdapter.refreshGrammars(fGrammarBucket); for (int i = 0; i < size; i += 2) { src.setSystemId((String) annotationInfo.get(i)); XSAnnotationInfo annotation = (XSAnnotationInfo) annotationInfo.get(i+1); while (annotation != null) { src.setCharacterStream(new StringReader(annotation.fAnnotation)); try { fAnnotationValidator.parse(src); } catch (IOException exc) {} annotation = annotation.next; } } } private void createAnnotationValidator() { fAnnotationValidator = new XML11Configuration(); fGrammarBucketAdapter = new XSAnnotationGrammarPool(); fAnnotationValidator.setFeature(VALIDATION, true); fAnnotationValidator.setFeature(XMLSCHEMA_VALIDATION, true); fAnnotationValidator.setProperty(XMLGRAMMAR_POOL, fGrammarBucketAdapter); /** Set error handler. **/ XMLErrorHandler errorHandler = fErrorReporter.getErrorHandler(); fAnnotationValidator.setProperty(ERROR_HANDLER, (errorHandler != null) ? errorHandler : new DefaultErrorHandler()); } /** * Pull the grammar out of the bucket simply using * its TNS as a key */ SchemaGrammar getGrammar(String tns) { return fGrammarBucket.getGrammar(tns); } /** * 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(Element 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}, 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}, 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}, 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}, 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],
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -