--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java Wed Jul 05 20:04:04 2017 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java Mon Oct 13 14:09:03 2014 -0700
@@ -1,13 +1,13 @@
/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * Copyright 2000-2005 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
@@ -20,26 +20,12 @@
package com.sun.org.apache.xerces.internal.impl.xs;
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.io.StringReader;
-import java.util.Hashtable;
-import java.util.Locale;
-import java.util.StringTokenizer;
-import java.util.Vector;
-
import com.sun.org.apache.xerces.internal.dom.DOMErrorImpl;
import com.sun.org.apache.xerces.internal.dom.DOMMessageFormatter;
import com.sun.org.apache.xerces.internal.dom.DOMStringListImpl;
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
-import com.sun.org.apache.xerces.internal.impl.dv.DVFactoryException;
import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException;
import com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory;
import com.sun.org.apache.xerces.internal.impl.dv.xs.SchemaDVFactoryImpl;
@@ -49,13 +35,16 @@
import com.sun.org.apache.xerces.internal.util.DOMEntityResolverWrapper;
import com.sun.org.apache.xerces.internal.util.DOMErrorHandlerWrapper;
import com.sun.org.apache.xerces.internal.util.DefaultErrorHandler;
+import com.sun.org.apache.xerces.internal.util.MessageFormatter;
import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings;
import com.sun.org.apache.xerces.internal.util.Status;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
+import com.sun.org.apache.xerces.internal.util.URI.MalformedURIException;
import com.sun.org.apache.xerces.internal.util.XMLSymbols;
import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
+import com.sun.org.apache.xerces.internal.xni.QName;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
@@ -72,14 +61,26 @@
import com.sun.org.apache.xerces.internal.xs.StringList;
import com.sun.org.apache.xerces.internal.xs.XSLoader;
import com.sun.org.apache.xerces.internal.xs.XSModel;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Locale;
import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.WeakHashMap;
import javax.xml.XMLConstants;
import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.DOMError;
import org.w3c.dom.DOMErrorHandler;
+import org.w3c.dom.DOMException;
import org.w3c.dom.DOMStringList;
-import org.w3c.dom.DOMException;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSResourceResolver;
import org.xml.sax.InputSource;
@@ -101,7 +102,7 @@
* @author Neil Graham, IBM
*/
-public class XMLSchemaLoader implements XMLGrammarLoader, XMLComponent,
+public class XMLSchemaLoader implements XMLGrammarLoader, XMLComponent, XSElementDeclHelper,
// XML Component API
XSLoader, DOMConfiguration {
@@ -249,8 +250,7 @@
// Data
// features and properties
- private ParserConfigurationSettings fLoaderConfig = new ParserConfigurationSettings();
- private SymbolTable fSymbolTable = null;
+ private final ParserConfigurationSettings fLoaderConfig = new ParserConfigurationSettings();
private XMLErrorReporter fErrorReporter = new XMLErrorReporter ();
private XMLEntityManager fEntityManager = null;
private XMLEntityResolver fUserEntityResolver = null;
@@ -276,7 +276,7 @@
private XSDDescription fXSDDescription = new XSDDescription();
private String faccessExternalSchema = Constants.EXTERNAL_ACCESS_DEFAULT;
- private Map fJAXPCache;
+ private WeakHashMap fJAXPCache;
private Locale fLocale = Locale.getDefault();
// XSLoader attributes
@@ -350,8 +350,8 @@
grammarBucket = new XSGrammarBucket();
}
fGrammarBucket = grammarBucket;
- if(sHandler == null) {
- sHandler = new SubstitutionGroupHandler(fGrammarBucket);
+ if (sHandler == null) {
+ sHandler = new SubstitutionGroupHandler(this);
}
fSubGroupHandler = sHandler;
@@ -360,10 +360,7 @@
}
fCMBuilder = builder;
fSchemaHandler = new XSDHandler(fGrammarBucket);
- if (fDeclPool != null) {
- fDeclPool.reset();
- }
- fJAXPCache = new HashMap();
+ fJAXPCache = new WeakHashMap();
fSettingsChanged = true;
}
@@ -527,8 +524,8 @@
* Returns a Grammar object by parsing the contents of the
* entities pointed to by sources.
*
- * @param source[] the locations of the entity which forms
- * the staring point of the grammars to be constructed
+ * @param source the locations of the entity which forms
+ * the staring point of the grammars to be constructed
* @throws IOException when a problem is encounted reading the entity
* @throws XNIException when a condition arises (such as a FatalError) that requires parsing
* of the entity be terminated
@@ -618,7 +615,8 @@
return grammar;
} // loadSchema(XSDDescription, XMLInputSource): SchemaGrammar
- /** This method tries to resolve location of the given schema.
+ /**
+ * This method tries to resolve location of the given schema.
* The loader stores the namespace/location pairs in a hashtable (use "" as the
* namespace of absent namespace). When resolving an entity, loader first tries
* to find in the hashtable whether there is a value for that namespace,
@@ -627,7 +625,7 @@
* @param desc
* @param locationPairs
* @param entityResolver
- * @return
+ * @return the XMLInputSource
* @throws IOException
*/
public static XMLInputSource resolveDocument(XSDDescription desc, Map locationPairs,
@@ -671,7 +669,7 @@
XSAttributeDecl attrDecl = SchemaGrammar.SG_XSI.getGlobalAttributeDecl(SchemaSymbols.XSI_SCHEMALOCATION);
// validation the string value to get the list of URI's
attrDecl.fType.validate(sl, null, null);
- if (!tokenizeSchemaLocationStr(sl, locations)) {
+ if (!tokenizeSchemaLocationStr(sl, locations, null)) {
// report warning (odd number of items)
er.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
"SchemaLocation",
@@ -714,7 +712,7 @@
// @param schemaStr The schemaLocation string to tokenize
// @param locations HashMap mapping namespaces to LocationArray objects holding lists of locaitons
// @return true if no problems; false if string could not be tokenized
- public static boolean tokenizeSchemaLocationStr(String schemaStr, Map locations) {
+ public static boolean tokenizeSchemaLocationStr(String schemaStr, Map locations, String base) {
if (schemaStr!= null) {
StringTokenizer t = new StringTokenizer(schemaStr, " \n\t\r");
String namespace, location;
@@ -729,6 +727,12 @@
la = new LocationArray();
locations.put(namespace, la);
}
+ if (base != null) {
+ try {
+ location = XMLEntityManager.expandSystemId(location, base, false);
+ } catch (MalformedURIException e) {
+ }
+ }
la.addLocation(location);
}
}
@@ -756,10 +760,10 @@
String sid = null;
if (componentType == null) {
// Not an array
- if(fJAXPSource instanceof InputStream ||
+ if (fJAXPSource instanceof InputStream ||
fJAXPSource instanceof InputSource) {
SchemaGrammar g = (SchemaGrammar)fJAXPCache.get(fJAXPSource);
- if(g != null) {
+ if (g != null) {
fGrammarBucket.putGrammar(g);
return;
}
@@ -776,38 +780,40 @@
}
SchemaGrammar g = loadSchema(fXSDDescription, xis, locationPairs);
// it is possible that we won't be able to resolve JAXP schema-source location
- if (g != null){
- if(fJAXPSource instanceof InputStream ||
+ if (g != null) {
+ if (fJAXPSource instanceof InputStream ||
fJAXPSource instanceof InputSource) {
fJAXPCache.put(fJAXPSource, g);
- if(fIsCheckedFully) {
+ if (fIsCheckedFully) {
XSConstraints.fullSchemaChecking(fGrammarBucket, fSubGroupHandler, fCMBuilder, fErrorReporter);
}
}
fGrammarBucket.putGrammar(g);
}
- return ;
- } else if ( (componentType != Object.class) &&
+ return;
+ }
+ else if ( (componentType != Object.class) &&
(componentType != String.class) &&
- (componentType != File.class) &&
- (componentType != InputStream.class) &&
- (componentType != InputSource.class)
+ !File.class.isAssignableFrom(componentType) &&
+ !InputStream.class.isAssignableFrom(componentType) &&
+ !InputSource.class.isAssignableFrom(componentType) &&
+ !componentType.isInterface()
) {
// Not an Object[], String[], File[], InputStream[], InputSource[]
+ MessageFormatter mf = fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN);
throw new XMLConfigurationException(
- Status.NOT_SUPPORTED, "\""+JAXP_SCHEMA_SOURCE+
- "\" property cannot have an array of type {"+componentType.getName()+
- "}. Possible types of the array supported are Object, String, File, "+
- "InputStream, InputSource.");
+ Status.NOT_SUPPORTED,
+ mf.formatMessage(fErrorReporter.getLocale(), "jaxp12-schema-source-type.2",
+ new Object [] {componentType.getName()}));
}
// JAXP spec. allow []s of type String, File, InputStream,
// InputSource also, apart from [] of type Object.
Object[] objArr = (Object[]) fJAXPSource;
- //make local vector for storing targetn namespaces of schemasources specified in object arrays.
- Vector jaxpSchemaSourceNamespaces = new Vector() ;
+ // make local array for storing target namespaces of schemasources specified in object arrays.
+ ArrayList jaxpSchemaSourceNamespaces = new ArrayList();
for (int i = 0; i < objArr.length; i++) {
- if(objArr[i] instanceof InputStream ||
+ if (objArr[i] instanceof InputStream ||
objArr[i] instanceof InputSource) {
SchemaGrammar g = (SchemaGrammar)fJAXPCache.get(objArr[i]);
if (g != null) {
@@ -829,18 +835,18 @@
// load schema
SchemaGrammar grammar = fSchemaHandler.parseSchema(xis,fXSDDescription, locationPairs);
- if(fIsCheckedFully) {
+ if (fIsCheckedFully) {
XSConstraints.fullSchemaChecking(fGrammarBucket, fSubGroupHandler, fCMBuilder, fErrorReporter);
}
- if(grammar != null){
- targetNamespace = grammar.getTargetNamespace() ;
- if(jaxpSchemaSourceNamespaces.contains(targetNamespace)){
- //when an array of objects is passed it is illegal to have two schemas that share same namespace.
- throw new java.lang.IllegalArgumentException(
- " When using array of Objects as the value of SCHEMA_SOURCE property , " +
- "no two Schemas should share the same targetNamespace. " );
+ if (grammar != null) {
+ targetNamespace = grammar.getTargetNamespace();
+ if (jaxpSchemaSourceNamespaces.contains(targetNamespace)) {
+ // when an array of objects is passed it is illegal to have two schemas that share same namespace.
+ MessageFormatter mf = fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN);
+ throw new java.lang.IllegalArgumentException(mf.formatMessage(fErrorReporter.getLocale(),
+ "jaxp12-schema-source-ns", null));
}
- else{
+ else {
jaxpSchemaSourceNamespaces.add(targetNamespace) ;
}
if(objArr[i] instanceof InputStream ||
@@ -849,15 +855,13 @@
}
fGrammarBucket.putGrammar(grammar);
}
- else{
+ else {
//REVISIT: What should be the acutal behavior if grammar can't be loaded as specified in schema source?
}
}
}//processJAXPSchemaSource
- private XMLInputSource xsdToXMLInputSource(
- Object val)
- {
+ private XMLInputSource xsdToXMLInputSource(Object val) {
if (val instanceof String) {
// String value is treated as a URI that is passed through the
// EntityResolver
@@ -867,7 +871,8 @@
XMLInputSource xis = null;
try {
xis = fEntityManager.resolveEntity(fXSDDescription);
- } catch (IOException ex) {
+ }
+ catch (IOException ex) {
fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
"schema_reference.4",
new Object[] { loc }, XMLErrorReporter.SEVERITY_ERROR);
@@ -878,12 +883,15 @@
return new XMLInputSource(null, loc, null);
}
return xis;
- } else if (val instanceof InputSource) {
+ }
+ else if (val instanceof InputSource) {
return saxToXMLInputSource((InputSource) val);
- } else if (val instanceof InputStream) {
+ }
+ else if (val instanceof InputStream) {
return new XMLInputSource(null, null, null,
(InputStream) val, null);
- } else if (val instanceof File) {
+ }
+ else if (val instanceof File) {
File file = (File) val;
InputStream is = null;
try {
@@ -893,13 +901,13 @@
"schema_reference.4", new Object[] { file.toString() },
XMLErrorReporter.SEVERITY_ERROR);
}
- return new XMLInputSource(null, null, null, is, null);
+ return new XMLInputSource(null, file.toURI().toString(), null, is, null);
}
+ MessageFormatter mf = fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN);
throw new XMLConfigurationException(
- Status.NOT_SUPPORTED, "\""+JAXP_SCHEMA_SOURCE+
- "\" property cannot have a value of type {"+val.getClass().getName()+
- "}. Possible types of the value supported are String, File, InputStream, "+
- "InputSource OR an array of these types.");
+ Status.NOT_SUPPORTED,
+ mf.formatMessage(fErrorReporter.getLocale(), "jaxp12-schema-source-type.1",
+ new Object [] {val != null ? val.getClass().getName() : "null"}));
}
@@ -999,13 +1007,22 @@
fSubGroupHandler.reset();
- boolean parser_settings = componentManager.getFeature(PARSER_SETTINGS, true);
+ boolean parser_settings = true;
+ // If the component manager is the loader config don't bother querying it since it doesn't
+ // recognize the PARSER_SETTINGS feature. Prevents an XMLConfigurationException from being
+ // thrown.
+ if (componentManager != fLoaderConfig) {
+ parser_settings = componentManager.getFeature(PARSER_SETTINGS, true);
+ }
if (!parser_settings || !fSettingsChanged){
// need to reprocess JAXP schema sources
fJAXPProcessed = false;
// reinitialize grammar bucket
initGrammarBucket();
+ if (fDeclPool != null) {
+ fDeclPool.reset();
+ }
return;
}
@@ -1028,26 +1045,6 @@
fSchemaHandler.setDVFactory(dvFactory);
}
- boolean psvi = componentManager.getFeature(AUGMENT_PSVI, false);
-
- if (!psvi) {
- if (fDeclPool != null) {
- fDeclPool.reset();
- }
- else {
- fDeclPool = new XSDeclarationPool();
- }
- fCMBuilder.setDeclPool(fDeclPool);
- fSchemaHandler.setDeclPool(fDeclPool);
- if (dvFactory instanceof SchemaDVFactoryImpl) {
- fDeclPool.setDVFactory((SchemaDVFactoryImpl)dvFactory);
- ((SchemaDVFactoryImpl)dvFactory).setDeclPool(fDeclPool);
- }
- } else {
- fCMBuilder.setDeclPool(null);
- fSchemaHandler.setDeclPool(null);
- }
-
// get schema location properties
try {
fExternalSchemas = (String) componentManager.getProperty(SCHEMA_LOCATION);
@@ -1064,6 +1061,36 @@
// clear grammars, and put the one for schema namespace there
fGrammarPool = (XMLGrammarPool) componentManager.getProperty(XMLGRAMMAR_POOL, null);
initGrammarBucket();
+
+ boolean psvi = componentManager.getFeature(AUGMENT_PSVI, false);
+
+ // Only use the decl pool when there is no chance that the schema
+ // components will be exposed or cached.
+ // TODO: when someone calls loadGrammar(XMLInputSource), the schema is
+ // always exposed even without the use of a grammar pool.
+ // Disabling the "decl pool" feature for now until we understand when
+ // it can be safely used.
+ if (!psvi && fGrammarPool == null && false) {
+ if (fDeclPool != null) {
+ fDeclPool.reset();
+ }
+ else {
+ fDeclPool = new XSDeclarationPool();
+ }
+ fCMBuilder.setDeclPool(fDeclPool);
+ fSchemaHandler.setDeclPool(fDeclPool);
+ if (dvFactory instanceof SchemaDVFactoryImpl) {
+ fDeclPool.setDVFactory((SchemaDVFactoryImpl)dvFactory);
+ ((SchemaDVFactoryImpl)dvFactory).setDeclPool(fDeclPool);
+ }
+ } else {
+ fCMBuilder.setDeclPool(null);
+ fSchemaHandler.setDeclPool(null);
+ if (dvFactory instanceof SchemaDVFactoryImpl) {
+ ((SchemaDVFactoryImpl)dvFactory).setDeclPool(null);
+ }
+ }
+
// get continue-after-fatal-error feature
try {
boolean fatalError = componentManager.getFeature(CONTINUE_AFTER_FATAL_ERROR, false);
@@ -1083,7 +1110,8 @@
private void initGrammarBucket(){
if(fGrammarPool != null) {
Grammar [] initialGrammars = fGrammarPool.retrieveInitialGrammarSet(XMLGrammarDescription.XML_SCHEMA);
- for (int i = 0; i < initialGrammars.length; i++) {
+ final int length = (initialGrammars != null) ? initialGrammars.length : 0;
+ for (int i = 0; i < length; ++i) {
// put this grammar into the bucket, along with grammars
// imported by it (directly or indirectly)
if (!fGrammarBucket.putGrammar((SchemaGrammar)(initialGrammars[i]), true)) {
@@ -1119,7 +1147,7 @@
}
/* (non-Javadoc)
- * @see com.sun.org.apache.xerces.internal.xs.XSLoader#loadInputList(com.sun.org.apache.xerces.internal.xs.DOMInputList)
+ * @see com.sun.org.apache.xerces.internal.xs.XSLoader#loadInputList(com.sun.org.apache.xerces.internal.xs.LSInputList)
*/
public XSModel loadInputList(LSInputList is) {
int length = is.getLength();
@@ -1250,7 +1278,7 @@
*/
public DOMStringList getParameterNames() {
if (fRecognizedParameters == null){
- Vector v = new Vector();
+ ArrayList v = new ArrayList();
v.add(Constants.DOM_VALIDATE);
v.add(Constants.DOM_ERROR_HANDLER);
v.add(Constants.DOM_RESOURCE_RESOLVER);
@@ -1391,4 +1419,13 @@
return xis;
}
+ // Implements XSElementDeclHelper interface
+ public XSElementDecl getGlobalElementDecl(QName element) {
+ SchemaGrammar sGrammar = fGrammarBucket.getGrammar(element.uri);
+ if (sGrammar != null) {
+ return sGrammar.getGlobalElementDecl(element.localpart);
+ }
+ return null;
+ }
+
} // XMLGrammarLoader