1 /*
2 * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
3 */
4 /*
5 * Licensed to the Apache Software Foundation (ASF) under one or more
6 * contributor license agreements. See the NOTICE file distributed with
7 * this work for additional information regarding copyright ownership.
8 * The ASF licenses this file to You under the Apache License, Version 2.0
9 * (the "License"); you may not use this file except in compliance with
10 * the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21 package com.sun.org.apache.xerces.internal.impl.xs.traversers;
22
43 import com.sun.org.apache.xerces.internal.impl.xs.XSNotationDecl;
44 import com.sun.org.apache.xerces.internal.impl.xs.XSParticleDecl;
45 import com.sun.org.apache.xerces.internal.impl.xs.identity.IdentityConstraint;
46 import com.sun.org.apache.xerces.internal.impl.xs.opti.ElementImpl;
47 import com.sun.org.apache.xerces.internal.impl.xs.opti.SchemaDOMParser;
48 import com.sun.org.apache.xerces.internal.impl.xs.opti.SchemaParsingConfig;
49 import com.sun.org.apache.xerces.internal.impl.xs.util.SimpleLocator;
50 import com.sun.org.apache.xerces.internal.impl.xs.util.XSInputSource;
51 import com.sun.org.apache.xerces.internal.parsers.SAXParser;
52 import com.sun.org.apache.xerces.internal.parsers.XML11Configuration;
53 import com.sun.org.apache.xerces.internal.util.DOMInputSource;
54 import com.sun.org.apache.xerces.internal.util.DOMUtil;
55 import com.sun.org.apache.xerces.internal.util.DefaultErrorHandler;
56 import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper;
57 import com.sun.org.apache.xerces.internal.util.SAXInputSource;
58 import com.sun.org.apache.xerces.internal.util.StAXInputSource;
59 import com.sun.org.apache.xerces.internal.util.StAXLocationWrapper;
60 import com.sun.org.apache.xerces.internal.util.SymbolHash;
61 import com.sun.org.apache.xerces.internal.util.SymbolTable;
62 import com.sun.org.apache.xerces.internal.util.URI.MalformedURIException;
63 import com.sun.org.apache.xerces.internal.util.XMLSymbols;
64 import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
65 import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
66 import com.sun.org.apache.xerces.internal.xni.QName;
67 import com.sun.org.apache.xerces.internal.xni.XNIException;
68 import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
69 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
70 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
71 import com.sun.org.apache.xerces.internal.xni.grammars.XMLSchemaDescription;
72 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
73 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
74 import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
75 import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
76 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
77 import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
78 import com.sun.org.apache.xerces.internal.xs.StringList;
79 import com.sun.org.apache.xerces.internal.xs.XSAttributeDeclaration;
80 import com.sun.org.apache.xerces.internal.xs.XSAttributeGroupDefinition;
81 import com.sun.org.apache.xerces.internal.xs.XSAttributeUse;
82 import com.sun.org.apache.xerces.internal.xs.XSConstants;
112 import org.w3c.dom.Node;
113 import org.xml.sax.InputSource;
114 import org.xml.sax.SAXException;
115 import org.xml.sax.SAXNotRecognizedException;
116 import org.xml.sax.SAXParseException;
117 import org.xml.sax.XMLReader;
118
119 /**
120 * The purpose of this class is to co-ordinate the construction of a
121 * grammar object corresponding to a schema. To do this, it must be
122 * prepared to parse several schema documents (for instance if the
123 * schema document originally referred to contains <include> or
124 * <redefined> information items). If any of the schemas imports a
125 * schema, other grammars may be constructed as a side-effect.
126 *
127 * @xerces.internal
128 *
129 * @author Neil Graham, IBM
130 * @author Pavani Mukthipudi, Sun Microsystems
131 *
132 * @LastModified: Nov 2017
133 */
134 @SuppressWarnings("deprecation") //org.xml.sax.helpers.XMLReaderFactory
135 public class XSDHandler {
136
137 /** Feature identifier: validation. */
138 protected static final String VALIDATION =
139 Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE;
140
141 /** feature identifier: XML Schema validation */
142 protected static final String XMLSCHEMA_VALIDATION =
143 Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE;
144
145 /** Feature identifier: allow java encodings */
146 protected static final String ALLOW_JAVA_ENCODINGS =
147 Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE;
148
149 /** Feature identifier: continue after fatal error */
150 protected static final String CONTINUE_AFTER_FATAL_ERROR =
151 Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE;
152
574 schemaRoot = getSchemaDocument(schemaNamespace, (SAXInputSource) is,
575 referType == XSDDescription.CONTEXT_PREPARSE,
576 referType, null);
577 } // SAXInputSource
578 else if (is instanceof StAXInputSource) {
579 schemaRoot = getSchemaDocument(schemaNamespace, (StAXInputSource) is,
580 referType == XSDDescription.CONTEXT_PREPARSE,
581 referType, null);
582 } // StAXInputSource
583 else if (is instanceof XSInputSource) {
584 schemaRoot = getSchemaDocument((XSInputSource) is, desc);
585 } // XSInputSource
586 else {
587 schemaRoot = getSchemaDocument(schemaNamespace, is,
588 referType == XSDDescription.CONTEXT_PREPARSE,
589 referType, null);
590
591 } //is instanceof XMLInputSource
592
593 if (schemaRoot == null) {
594 // something went wrong right off the hop
595 if (is instanceof XSInputSource) {
596 return fGrammarBucket.getGrammar(desc.getTargetNamespace());
597 }
598 return grammar;
599 }
600
601 if (referType == XSDDescription.CONTEXT_PREPARSE) {
602 Element schemaElem = schemaRoot;
603 schemaNamespace = DOMUtil.getAttrValue(schemaElem, SchemaSymbols.ATT_TARGETNAMESPACE);
604 if(schemaNamespace != null && schemaNamespace.length() > 0) {
605 // Since now we've discovered a namespace, we need to update xsd key
606 // and store this schema in traversed schemas bucket
607 schemaNamespace = fSymbolTable.addSymbol(schemaNamespace);
608 desc.setTargetNamespace(schemaNamespace);
609 }
610 else {
611 schemaNamespace = null;
612 }
613 grammar = findGrammar(desc, fNamespaceGrowth);
614 String schemaId = XMLEntityManager.expandSystemId(is.getSystemId(), is.getBaseSystemId(), false);
615 if (grammar != null) {
616 // When namespace growth is enabled and a null location is provided we cannot tell
617 // whether we've loaded this schema document before so we must assume that we haven't.
1282 else if (DOMUtil.getLocalName(globalComp).equals(SchemaSymbols.ELT_INCLUDE) ||
1283 DOMUtil.getLocalName(globalComp).equals(SchemaSymbols.ELT_IMPORT)) {
1284 if (!dependenciesCanOccur) {
1285 reportSchemaError("s4s-elt-invalid-content.3", new Object [] {DOMUtil.getLocalName(globalComp)}, globalComp);
1286 }
1287 DOMUtil.setHidden(globalComp, fHiddenNodes);
1288 }
1289 else if (DOMUtil.getLocalName(globalComp).equals(SchemaSymbols.ELT_REDEFINE)) {
1290 if (!dependenciesCanOccur) {
1291 reportSchemaError("s4s-elt-invalid-content.3", new Object [] {DOMUtil.getLocalName(globalComp)}, globalComp);
1292 }
1293 for (Element redefineComp = DOMUtil.getFirstChildElement(globalComp);
1294 redefineComp != null;
1295 redefineComp = DOMUtil.getNextSiblingElement(redefineComp)) {
1296 String lName = DOMUtil.getAttrValue(redefineComp, SchemaSymbols.ATT_NAME);
1297 if (lName.length() == 0) // an error we'll catch later
1298 continue;
1299 String qName = currSchemaDoc.fTargetNamespace == null ?
1300 ","+lName:
1301 currSchemaDoc.fTargetNamespace +","+lName;
1302 String componentType = DOMUtil.getLocalName(redefineComp);
1303 if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
1304 checkForDuplicateNames(qName, ATTRIBUTEGROUP_TYPE, fUnparsedAttributeGroupRegistry, fUnparsedAttributeGroupRegistrySub, redefineComp, currSchemaDoc);
1305 // the check will have changed our name;
1306 String targetLName = DOMUtil.getAttrValue(redefineComp, SchemaSymbols.ATT_NAME)+REDEF_IDENTIFIER;
1307 // and all we need to do is error-check+rename our kkids:
1308 renameRedefiningComponents(currSchemaDoc, redefineComp, SchemaSymbols.ELT_ATTRIBUTEGROUP,
1309 lName, targetLName);
1310 }
1311 else if ((componentType.equals(SchemaSymbols.ELT_COMPLEXTYPE)) ||
1312 (componentType.equals(SchemaSymbols.ELT_SIMPLETYPE))) {
1313 checkForDuplicateNames(qName, TYPEDECL_TYPE, fUnparsedTypeRegistry, fUnparsedTypeRegistrySub, redefineComp, currSchemaDoc);
1314 // the check will have changed our name;
1315 String targetLName = DOMUtil.getAttrValue(redefineComp, SchemaSymbols.ATT_NAME) + REDEF_IDENTIFIER;
1316 // and all we need to do is error-check+rename our kkids:
1317 if (componentType.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
1318 renameRedefiningComponents(currSchemaDoc, redefineComp, SchemaSymbols.ELT_COMPLEXTYPE,
1319 lName, targetLName);
1320 }
1321 else { // must be simpleType
1326 else if (componentType.equals(SchemaSymbols.ELT_GROUP)) {
1327 checkForDuplicateNames(qName, GROUP_TYPE, fUnparsedGroupRegistry, fUnparsedGroupRegistrySub, redefineComp, currSchemaDoc);
1328 // the check will have changed our name;
1329 String targetLName = DOMUtil.getAttrValue(redefineComp, SchemaSymbols.ATT_NAME)+REDEF_IDENTIFIER;
1330 // and all we need to do is error-check+rename our kids:
1331 renameRedefiningComponents(currSchemaDoc, redefineComp, SchemaSymbols.ELT_GROUP,
1332 lName, targetLName);
1333 }
1334 } // end march through <redefine> children
1335 // and now set as traversed
1336 //DOMUtil.setHidden(globalComp);
1337 }
1338 else {
1339 dependenciesCanOccur = false;
1340 String lName = DOMUtil.getAttrValue(globalComp, SchemaSymbols.ATT_NAME);
1341 if (lName.length() == 0) // an error we'll catch later
1342 continue;
1343 String qName = currSchemaDoc.fTargetNamespace == null?
1344 ","+lName:
1345 currSchemaDoc.fTargetNamespace +","+lName;
1346 String componentType = DOMUtil.getLocalName(globalComp);
1347
1348 if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
1349 checkForDuplicateNames(qName, ATTRIBUTE_TYPE, fUnparsedAttributeRegistry, fUnparsedAttributeRegistrySub, globalComp, currSchemaDoc);
1350 }
1351 else if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
1352 checkForDuplicateNames(qName, ATTRIBUTEGROUP_TYPE, fUnparsedAttributeGroupRegistry, fUnparsedAttributeGroupRegistrySub, globalComp, currSchemaDoc);
1353 }
1354 else if ((componentType.equals(SchemaSymbols.ELT_COMPLEXTYPE)) ||
1355 (componentType.equals(SchemaSymbols.ELT_SIMPLETYPE))) {
1356 checkForDuplicateNames(qName, TYPEDECL_TYPE, fUnparsedTypeRegistry, fUnparsedTypeRegistrySub, globalComp, currSchemaDoc);
1357 }
1358 else if (componentType.equals(SchemaSymbols.ELT_ELEMENT)) {
1359 checkForDuplicateNames(qName, ELEMENT_TYPE, fUnparsedElementRegistry, fUnparsedElementRegistrySub, globalComp, currSchemaDoc);
1360 }
1361 else if (componentType.equals(SchemaSymbols.ELT_GROUP)) {
1362 checkForDuplicateNames(qName, GROUP_TYPE, fUnparsedGroupRegistry, fUnparsedGroupRegistrySub, globalComp, currSchemaDoc);
1363 }
1364 else if (componentType.equals(SchemaSymbols.ELT_NOTATION)) {
1365 checkForDuplicateNames(qName, NOTATION_TYPE, fUnparsedNotationRegistry, fUnparsedNotationRegistrySub, globalComp, currSchemaDoc);
2449 fStAXSchemaParser.parse(streamReader);
2450 if (consumeRemainingContent) {
2451 while (streamReader.hasNext()) {
2452 streamReader.next();
2453 }
2454 }
2455 }
2456 else {
2457 fStAXSchemaParser.parse(eventReader);
2458 if (consumeRemainingContent) {
2459 while (eventReader.hasNext()) {
2460 eventReader.nextEvent();
2461 }
2462 }
2463 }
2464 Document schemaDocument = fStAXSchemaParser.getDocument();
2465 schemaElement = schemaDocument != null ? DOMUtil.getRoot(schemaDocument) : null;
2466 return getSchemaDocument0(key, schemaId, schemaElement);
2467 }
2468 catch (XMLStreamException e) {
2469 StAXLocationWrapper slw = new StAXLocationWrapper();
2470 slw.setLocation(e.getLocation());
2471 throw new XMLParseException(slw, e.getMessage(), e);
2472 }
2473 catch (IOException e) {
2474 exception = e;
2475 }
2476 return getSchemaDocument1(mustResolve, true, schemaSource, referElement, exception);
2477 } // getSchemaDocument(String, StAXInputSource, boolean, short, Element): Element
2478
2479 /**
2480 * Code shared between the various getSchemaDocument() methods which
2481 * stores mapping information for the document.
2482 */
2483 private Element getSchemaDocument0(XSDKey key, String schemaId, Element schemaElement) {
2484 // now we need to store the mapping information from system id
2485 // to the document. also from the document to the system id.
2486 if (key != null) {
2487 fTraversed.put(key, schemaElement);
2488 }
2489 if (schemaId != null) {
2490 fDoc2SystemId.put(schemaElement, schemaId);
2491 }
2492 fLastSchemaWasDuplicate = false;
2724 // update import list of the new grammar
2725 updateImportListFor(newGrammar);
2726 return newGrammar;
2727 }
2728
2729 private void addNewGrammarLocations(SchemaGrammar srcGrammar, SchemaGrammar dstGrammar) {
2730 final StringList locations = srcGrammar.getDocumentLocations();
2731 final int locSize = locations.size();
2732 final StringList locations2 = dstGrammar.getDocumentLocations();
2733
2734 for (int i=0; i<locSize; i++) {
2735 String loc = locations.item(i);
2736 if (!locations2.contains(loc)) {
2737 dstGrammar.addDocument(null, loc);
2738 }
2739 }
2740 }
2741
2742 @SuppressWarnings("unchecked")
2743 private void addNewImportedGrammars(SchemaGrammar srcGrammar, SchemaGrammar dstGrammar) {
2744 final ArrayList<SchemaGrammar> igs1 = (ArrayList<SchemaGrammar>)srcGrammar.getImportedGrammars();
2745 if (igs1 != null) {
2746 ArrayList<SchemaGrammar> igs2 = (ArrayList<SchemaGrammar>)dstGrammar.getImportedGrammars();
2747
2748 if (igs2 == null) {
2749 igs2 = (ArrayList<SchemaGrammar>)igs1.clone();
2750 dstGrammar.setImportedGrammars(igs2);
2751 }
2752 else {
2753 updateImportList(igs1, igs2);
2754 }
2755 }
2756 }
2757
2758 private void updateImportList(List<SchemaGrammar> importedSrc, List<SchemaGrammar> importedDst)
2759 {
2760 final int size = importedSrc.size();
2761
2762 for (int i=0; i<size; i++) {
2763 final SchemaGrammar sg = importedSrc.get(i);
2764 if (!containedImportedGrammar(importedDst, sg)) {
2765 importedDst.add(sg);
2766 }
2767 }
2768 }
2769
2770 private void addNewGrammarComponents(SchemaGrammar srcGrammar, SchemaGrammar dstGrammar) {
2771 dstGrammar.resetComponents();
2772 addGlobalElementDecls(srcGrammar, dstGrammar);
2773 addGlobalAttributeDecls(srcGrammar, dstGrammar);
3145 break;
3146 case XSConstants.MODEL_GROUP :
3147 expandRelatedModelGroupComponents((XSModelGroup) term, componentList, namespace, dependencies);
3148 break;
3149 default:
3150 break;
3151 }
3152 }
3153
3154 private void expandRelatedModelGroupComponents(XSModelGroup modelGroup, List<XSObject> componentList,
3155 String namespace, Map<String, List<String>> dependencies) {
3156 XSObjectList particles = modelGroup.getParticles();
3157 final int length = (particles == null) ? 0 : particles.getLength();
3158 for (int i=0; i<length; i++) {
3159 expandRelatedParticleComponents((XSParticle)particles.item(i), componentList, namespace, dependencies);
3160 }
3161 }
3162
3163 private void addRelatedType(XSTypeDefinition type, List<XSObject> componentList, String namespace, Map<String, List<String>> dependencies) {
3164 if (!type.getAnonymous()) {
3165 if (!type.getNamespace().equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)) { //REVISIT - do we use == instead
3166 if (!componentList.contains(type)) {
3167 final List<String> importedNamespaces = findDependentNamespaces(namespace, dependencies);
3168 addNamespaceDependency(namespace, type.getNamespace(), importedNamespaces);
3169 componentList.add(type);
3170 }
3171 }
3172 }
3173 else {
3174 expandRelatedTypeComponents(type, componentList, namespace, dependencies);
3175 }
3176 }
3177
3178 private void addRelatedElement(XSElementDeclaration decl, List<XSObject> componentList, String namespace, Map<String, List<String>> dependencies) {
3179 if (decl.getScope() == XSConstants.SCOPE_GLOBAL) {
3180 if (!componentList.contains(decl)) {
3181 List<String> importedNamespaces = findDependentNamespaces(namespace, dependencies);
3182 addNamespaceDependency(namespace, decl.getNamespace(), importedNamespaces);
3183 componentList.add(decl);
3184 }
3185 }
|
1 /*
2 * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
3 */
4 /*
5 * Licensed to the Apache Software Foundation (ASF) under one or more
6 * contributor license agreements. See the NOTICE file distributed with
7 * this work for additional information regarding copyright ownership.
8 * The ASF licenses this file to You under the Apache License, Version 2.0
9 * (the "License"); you may not use this file except in compliance with
10 * the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21 package com.sun.org.apache.xerces.internal.impl.xs.traversers;
22
43 import com.sun.org.apache.xerces.internal.impl.xs.XSNotationDecl;
44 import com.sun.org.apache.xerces.internal.impl.xs.XSParticleDecl;
45 import com.sun.org.apache.xerces.internal.impl.xs.identity.IdentityConstraint;
46 import com.sun.org.apache.xerces.internal.impl.xs.opti.ElementImpl;
47 import com.sun.org.apache.xerces.internal.impl.xs.opti.SchemaDOMParser;
48 import com.sun.org.apache.xerces.internal.impl.xs.opti.SchemaParsingConfig;
49 import com.sun.org.apache.xerces.internal.impl.xs.util.SimpleLocator;
50 import com.sun.org.apache.xerces.internal.impl.xs.util.XSInputSource;
51 import com.sun.org.apache.xerces.internal.parsers.SAXParser;
52 import com.sun.org.apache.xerces.internal.parsers.XML11Configuration;
53 import com.sun.org.apache.xerces.internal.util.DOMInputSource;
54 import com.sun.org.apache.xerces.internal.util.DOMUtil;
55 import com.sun.org.apache.xerces.internal.util.DefaultErrorHandler;
56 import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper;
57 import com.sun.org.apache.xerces.internal.util.SAXInputSource;
58 import com.sun.org.apache.xerces.internal.util.StAXInputSource;
59 import com.sun.org.apache.xerces.internal.util.StAXLocationWrapper;
60 import com.sun.org.apache.xerces.internal.util.SymbolHash;
61 import com.sun.org.apache.xerces.internal.util.SymbolTable;
62 import com.sun.org.apache.xerces.internal.util.URI.MalformedURIException;
63 import com.sun.org.apache.xerces.internal.util.XMLChar;
64 import com.sun.org.apache.xerces.internal.util.XMLSymbols;
65 import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
66 import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
67 import com.sun.org.apache.xerces.internal.xni.QName;
68 import com.sun.org.apache.xerces.internal.xni.XNIException;
69 import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
70 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
71 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
72 import com.sun.org.apache.xerces.internal.xni.grammars.XMLSchemaDescription;
73 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
74 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
75 import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
76 import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
77 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
78 import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
79 import com.sun.org.apache.xerces.internal.xs.StringList;
80 import com.sun.org.apache.xerces.internal.xs.XSAttributeDeclaration;
81 import com.sun.org.apache.xerces.internal.xs.XSAttributeGroupDefinition;
82 import com.sun.org.apache.xerces.internal.xs.XSAttributeUse;
83 import com.sun.org.apache.xerces.internal.xs.XSConstants;
113 import org.w3c.dom.Node;
114 import org.xml.sax.InputSource;
115 import org.xml.sax.SAXException;
116 import org.xml.sax.SAXNotRecognizedException;
117 import org.xml.sax.SAXParseException;
118 import org.xml.sax.XMLReader;
119
120 /**
121 * The purpose of this class is to co-ordinate the construction of a
122 * grammar object corresponding to a schema. To do this, it must be
123 * prepared to parse several schema documents (for instance if the
124 * schema document originally referred to contains <include> or
125 * <redefined> information items). If any of the schemas imports a
126 * schema, other grammars may be constructed as a side-effect.
127 *
128 * @xerces.internal
129 *
130 * @author Neil Graham, IBM
131 * @author Pavani Mukthipudi, Sun Microsystems
132 *
133 * @LastModified: Apr 2019
134 */
135 @SuppressWarnings("deprecation") //org.xml.sax.helpers.XMLReaderFactory
136 public class XSDHandler {
137
138 /** Feature identifier: validation. */
139 protected static final String VALIDATION =
140 Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE;
141
142 /** feature identifier: XML Schema validation */
143 protected static final String XMLSCHEMA_VALIDATION =
144 Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE;
145
146 /** Feature identifier: allow java encodings */
147 protected static final String ALLOW_JAVA_ENCODINGS =
148 Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE;
149
150 /** Feature identifier: continue after fatal error */
151 protected static final String CONTINUE_AFTER_FATAL_ERROR =
152 Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE;
153
575 schemaRoot = getSchemaDocument(schemaNamespace, (SAXInputSource) is,
576 referType == XSDDescription.CONTEXT_PREPARSE,
577 referType, null);
578 } // SAXInputSource
579 else if (is instanceof StAXInputSource) {
580 schemaRoot = getSchemaDocument(schemaNamespace, (StAXInputSource) is,
581 referType == XSDDescription.CONTEXT_PREPARSE,
582 referType, null);
583 } // StAXInputSource
584 else if (is instanceof XSInputSource) {
585 schemaRoot = getSchemaDocument((XSInputSource) is, desc);
586 } // XSInputSource
587 else {
588 schemaRoot = getSchemaDocument(schemaNamespace, is,
589 referType == XSDDescription.CONTEXT_PREPARSE,
590 referType, null);
591
592 } //is instanceof XMLInputSource
593
594 if (schemaRoot == null) {
595 if (is instanceof XSInputSource) {
596 // Need to return a grammar. If the XSInputSource has a list
597 // of grammar objects, then get the first one and return it.
598 // If it has a list of components, then get the grammar that
599 // contains the first component and return it.
600 // If we return null, the XMLSchemaLoader will think nothing
601 // was loaded, and will not try to put the grammar objects
602 // into the grammar pool.
603 XSInputSource xsinput = (XSInputSource)is;
604 SchemaGrammar[] grammars = xsinput.getGrammars();
605 if (grammars != null && grammars.length > 0) {
606 grammar = fGrammarBucket.getGrammar(grammars[0].getTargetNamespace());
607 }
608 else {
609 XSObject[] components = xsinput.getComponents();
610 if (components != null && components.length > 0) {
611 grammar = fGrammarBucket.getGrammar(components[0].getNamespace());
612 }
613 }
614 }
615 // something went wrong right off the hop
616 return grammar;
617 }
618
619 if (referType == XSDDescription.CONTEXT_PREPARSE) {
620 Element schemaElem = schemaRoot;
621 schemaNamespace = DOMUtil.getAttrValue(schemaElem, SchemaSymbols.ATT_TARGETNAMESPACE);
622 if(schemaNamespace != null && schemaNamespace.length() > 0) {
623 // Since now we've discovered a namespace, we need to update xsd key
624 // and store this schema in traversed schemas bucket
625 schemaNamespace = fSymbolTable.addSymbol(schemaNamespace);
626 desc.setTargetNamespace(schemaNamespace);
627 }
628 else {
629 schemaNamespace = null;
630 }
631 grammar = findGrammar(desc, fNamespaceGrowth);
632 String schemaId = XMLEntityManager.expandSystemId(is.getSystemId(), is.getBaseSystemId(), false);
633 if (grammar != null) {
634 // When namespace growth is enabled and a null location is provided we cannot tell
635 // whether we've loaded this schema document before so we must assume that we haven't.
1300 else if (DOMUtil.getLocalName(globalComp).equals(SchemaSymbols.ELT_INCLUDE) ||
1301 DOMUtil.getLocalName(globalComp).equals(SchemaSymbols.ELT_IMPORT)) {
1302 if (!dependenciesCanOccur) {
1303 reportSchemaError("s4s-elt-invalid-content.3", new Object [] {DOMUtil.getLocalName(globalComp)}, globalComp);
1304 }
1305 DOMUtil.setHidden(globalComp, fHiddenNodes);
1306 }
1307 else if (DOMUtil.getLocalName(globalComp).equals(SchemaSymbols.ELT_REDEFINE)) {
1308 if (!dependenciesCanOccur) {
1309 reportSchemaError("s4s-elt-invalid-content.3", new Object [] {DOMUtil.getLocalName(globalComp)}, globalComp);
1310 }
1311 for (Element redefineComp = DOMUtil.getFirstChildElement(globalComp);
1312 redefineComp != null;
1313 redefineComp = DOMUtil.getNextSiblingElement(redefineComp)) {
1314 String lName = DOMUtil.getAttrValue(redefineComp, SchemaSymbols.ATT_NAME);
1315 if (lName.length() == 0) // an error we'll catch later
1316 continue;
1317 String qName = currSchemaDoc.fTargetNamespace == null ?
1318 ","+lName:
1319 currSchemaDoc.fTargetNamespace +","+lName;
1320 qName = XMLChar.trim(qName);
1321 String componentType = DOMUtil.getLocalName(redefineComp);
1322 if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
1323 checkForDuplicateNames(qName, ATTRIBUTEGROUP_TYPE, fUnparsedAttributeGroupRegistry, fUnparsedAttributeGroupRegistrySub, redefineComp, currSchemaDoc);
1324 // the check will have changed our name;
1325 String targetLName = DOMUtil.getAttrValue(redefineComp, SchemaSymbols.ATT_NAME)+REDEF_IDENTIFIER;
1326 // and all we need to do is error-check+rename our kkids:
1327 renameRedefiningComponents(currSchemaDoc, redefineComp, SchemaSymbols.ELT_ATTRIBUTEGROUP,
1328 lName, targetLName);
1329 }
1330 else if ((componentType.equals(SchemaSymbols.ELT_COMPLEXTYPE)) ||
1331 (componentType.equals(SchemaSymbols.ELT_SIMPLETYPE))) {
1332 checkForDuplicateNames(qName, TYPEDECL_TYPE, fUnparsedTypeRegistry, fUnparsedTypeRegistrySub, redefineComp, currSchemaDoc);
1333 // the check will have changed our name;
1334 String targetLName = DOMUtil.getAttrValue(redefineComp, SchemaSymbols.ATT_NAME) + REDEF_IDENTIFIER;
1335 // and all we need to do is error-check+rename our kkids:
1336 if (componentType.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
1337 renameRedefiningComponents(currSchemaDoc, redefineComp, SchemaSymbols.ELT_COMPLEXTYPE,
1338 lName, targetLName);
1339 }
1340 else { // must be simpleType
1345 else if (componentType.equals(SchemaSymbols.ELT_GROUP)) {
1346 checkForDuplicateNames(qName, GROUP_TYPE, fUnparsedGroupRegistry, fUnparsedGroupRegistrySub, redefineComp, currSchemaDoc);
1347 // the check will have changed our name;
1348 String targetLName = DOMUtil.getAttrValue(redefineComp, SchemaSymbols.ATT_NAME)+REDEF_IDENTIFIER;
1349 // and all we need to do is error-check+rename our kids:
1350 renameRedefiningComponents(currSchemaDoc, redefineComp, SchemaSymbols.ELT_GROUP,
1351 lName, targetLName);
1352 }
1353 } // end march through <redefine> children
1354 // and now set as traversed
1355 //DOMUtil.setHidden(globalComp);
1356 }
1357 else {
1358 dependenciesCanOccur = false;
1359 String lName = DOMUtil.getAttrValue(globalComp, SchemaSymbols.ATT_NAME);
1360 if (lName.length() == 0) // an error we'll catch later
1361 continue;
1362 String qName = currSchemaDoc.fTargetNamespace == null?
1363 ","+lName:
1364 currSchemaDoc.fTargetNamespace +","+lName;
1365 qName = XMLChar.trim(qName);
1366 String componentType = DOMUtil.getLocalName(globalComp);
1367
1368 if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
1369 checkForDuplicateNames(qName, ATTRIBUTE_TYPE, fUnparsedAttributeRegistry, fUnparsedAttributeRegistrySub, globalComp, currSchemaDoc);
1370 }
1371 else if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
1372 checkForDuplicateNames(qName, ATTRIBUTEGROUP_TYPE, fUnparsedAttributeGroupRegistry, fUnparsedAttributeGroupRegistrySub, globalComp, currSchemaDoc);
1373 }
1374 else if ((componentType.equals(SchemaSymbols.ELT_COMPLEXTYPE)) ||
1375 (componentType.equals(SchemaSymbols.ELT_SIMPLETYPE))) {
1376 checkForDuplicateNames(qName, TYPEDECL_TYPE, fUnparsedTypeRegistry, fUnparsedTypeRegistrySub, globalComp, currSchemaDoc);
1377 }
1378 else if (componentType.equals(SchemaSymbols.ELT_ELEMENT)) {
1379 checkForDuplicateNames(qName, ELEMENT_TYPE, fUnparsedElementRegistry, fUnparsedElementRegistrySub, globalComp, currSchemaDoc);
1380 }
1381 else if (componentType.equals(SchemaSymbols.ELT_GROUP)) {
1382 checkForDuplicateNames(qName, GROUP_TYPE, fUnparsedGroupRegistry, fUnparsedGroupRegistrySub, globalComp, currSchemaDoc);
1383 }
1384 else if (componentType.equals(SchemaSymbols.ELT_NOTATION)) {
1385 checkForDuplicateNames(qName, NOTATION_TYPE, fUnparsedNotationRegistry, fUnparsedNotationRegistrySub, globalComp, currSchemaDoc);
2469 fStAXSchemaParser.parse(streamReader);
2470 if (consumeRemainingContent) {
2471 while (streamReader.hasNext()) {
2472 streamReader.next();
2473 }
2474 }
2475 }
2476 else {
2477 fStAXSchemaParser.parse(eventReader);
2478 if (consumeRemainingContent) {
2479 while (eventReader.hasNext()) {
2480 eventReader.nextEvent();
2481 }
2482 }
2483 }
2484 Document schemaDocument = fStAXSchemaParser.getDocument();
2485 schemaElement = schemaDocument != null ? DOMUtil.getRoot(schemaDocument) : null;
2486 return getSchemaDocument0(key, schemaId, schemaElement);
2487 }
2488 catch (XMLStreamException e) {
2489 Throwable t = e.getNestedException();
2490 if (t instanceof IOException) {
2491 exception = (IOException) t;
2492 }
2493 else {
2494 StAXLocationWrapper slw = new StAXLocationWrapper();
2495 slw.setLocation(e.getLocation());
2496 throw new XMLParseException(slw, e.getMessage(), e);
2497 }
2498 }
2499 catch (IOException e) {
2500 exception = e;
2501 }
2502 return getSchemaDocument1(mustResolve, true, schemaSource, referElement, exception);
2503 } // getSchemaDocument(String, StAXInputSource, boolean, short, Element): Element
2504
2505 /**
2506 * Code shared between the various getSchemaDocument() methods which
2507 * stores mapping information for the document.
2508 */
2509 private Element getSchemaDocument0(XSDKey key, String schemaId, Element schemaElement) {
2510 // now we need to store the mapping information from system id
2511 // to the document. also from the document to the system id.
2512 if (key != null) {
2513 fTraversed.put(key, schemaElement);
2514 }
2515 if (schemaId != null) {
2516 fDoc2SystemId.put(schemaElement, schemaId);
2517 }
2518 fLastSchemaWasDuplicate = false;
2750 // update import list of the new grammar
2751 updateImportListFor(newGrammar);
2752 return newGrammar;
2753 }
2754
2755 private void addNewGrammarLocations(SchemaGrammar srcGrammar, SchemaGrammar dstGrammar) {
2756 final StringList locations = srcGrammar.getDocumentLocations();
2757 final int locSize = locations.size();
2758 final StringList locations2 = dstGrammar.getDocumentLocations();
2759
2760 for (int i=0; i<locSize; i++) {
2761 String loc = locations.item(i);
2762 if (!locations2.contains(loc)) {
2763 dstGrammar.addDocument(null, loc);
2764 }
2765 }
2766 }
2767
2768 @SuppressWarnings("unchecked")
2769 private void addNewImportedGrammars(SchemaGrammar srcGrammar, SchemaGrammar dstGrammar) {
2770 final ArrayList<SchemaGrammar> src = (ArrayList<SchemaGrammar>)srcGrammar.getImportedGrammars();
2771 if (src != null) {
2772 ArrayList<SchemaGrammar> dst = (ArrayList<SchemaGrammar>)dstGrammar.getImportedGrammars();
2773 if (dst == null) {
2774 dst = new ArrayList<>();
2775 dstGrammar.setImportedGrammars(dst);
2776 }
2777 for (SchemaGrammar sg :src) {
2778 // Can't use the object from the source import list directly.
2779 // It's possible there is already a grammar with the same
2780 // namespace in the bucket but a different object.
2781 // This can happen if the bucket has grammar A1, and we try
2782 // to add B and A2, where A2 imports B. When B is added, we
2783 // create a new object B' and store it in the bucket. Then we
2784 // try to merge A2 and A1. We can't use B. Need to get B' from
2785 // the bucket and store it in A's import list.
2786 SchemaGrammar sg1 = fGrammarBucket.getGrammar(sg.getTargetNamespace());
2787 if (sg1 != null) {
2788 sg = sg1;
2789 }
2790 if (!containedImportedGrammar(dst, sg)) {
2791 dst.add(sg);
2792 }
2793 }
2794 }
2795 }
2796
2797 private void updateImportList(List<SchemaGrammar> importedSrc, List<SchemaGrammar> importedDst)
2798 {
2799 final int size = importedSrc.size();
2800
2801 for (int i=0; i<size; i++) {
2802 final SchemaGrammar sg = importedSrc.get(i);
2803 if (!containedImportedGrammar(importedDst, sg)) {
2804 importedDst.add(sg);
2805 }
2806 }
2807 }
2808
2809 private void addNewGrammarComponents(SchemaGrammar srcGrammar, SchemaGrammar dstGrammar) {
2810 dstGrammar.resetComponents();
2811 addGlobalElementDecls(srcGrammar, dstGrammar);
2812 addGlobalAttributeDecls(srcGrammar, dstGrammar);
3184 break;
3185 case XSConstants.MODEL_GROUP :
3186 expandRelatedModelGroupComponents((XSModelGroup) term, componentList, namespace, dependencies);
3187 break;
3188 default:
3189 break;
3190 }
3191 }
3192
3193 private void expandRelatedModelGroupComponents(XSModelGroup modelGroup, List<XSObject> componentList,
3194 String namespace, Map<String, List<String>> dependencies) {
3195 XSObjectList particles = modelGroup.getParticles();
3196 final int length = (particles == null) ? 0 : particles.getLength();
3197 for (int i=0; i<length; i++) {
3198 expandRelatedParticleComponents((XSParticle)particles.item(i), componentList, namespace, dependencies);
3199 }
3200 }
3201
3202 private void addRelatedType(XSTypeDefinition type, List<XSObject> componentList, String namespace, Map<String, List<String>> dependencies) {
3203 if (!type.getAnonymous()) {
3204 if (!SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(type.getNamespace())) { //REVISIT - do we use == instead
3205 if (!componentList.contains(type)) {
3206 final List<String> importedNamespaces = findDependentNamespaces(namespace, dependencies);
3207 addNamespaceDependency(namespace, type.getNamespace(), importedNamespaces);
3208 componentList.add(type);
3209 }
3210 }
3211 }
3212 else {
3213 expandRelatedTypeComponents(type, componentList, namespace, dependencies);
3214 }
3215 }
3216
3217 private void addRelatedElement(XSElementDeclaration decl, List<XSObject> componentList, String namespace, Map<String, List<String>> dependencies) {
3218 if (decl.getScope() == XSConstants.SCOPE_GLOBAL) {
3219 if (!componentList.contains(decl)) {
3220 List<String> importedNamespaces = findDependentNamespaces(namespace, dependencies);
3221 addNamespaceDependency(namespace, decl.getNamespace(), importedNamespaces);
3222 componentList.add(decl);
3223 }
3224 }
|