--- old/src/javax/xml/validation/SchemaFactoryFinder.java 2012-08-27 21:27:32.344800400 -0700 +++ new/src/javax/xml/validation/SchemaFactoryFinder.java 2012-08-27 21:27:31.585413400 -0700 @@ -25,19 +25,15 @@ package javax.xml.validation; -import java.io.BufferedReader; import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.net.URL; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.NoSuchElementException; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Properties; +import java.util.ServiceConfigurationError; +import java.util.ServiceLoader; /** * Implementation of {@link SchemaFactory#newInstance(String)}. @@ -46,23 +42,25 @@ * @version $Revision: 1.8 $, $Date: 2010-11-01 04:36:13 $ * @since 1.5 */ -class SchemaFactoryFinder { +class SchemaFactoryFinder { - /** debug support code. */ + private static final String DEFAULT_IMPL_NAME = "com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory"; + /** + * debug support code. + */ private static boolean debug = false; /** - *
Take care of restrictions imposed by java security model
+ *Take care of restrictions imposed by java security model
*/ private static SecuritySupport ss = new SecuritySupport(); /** *Cache properties for performance.
*/ - private static Properties cacheProps = new Properties(); - - /** - *First time requires initialization overhead.
- */ - private static volatile boolean firstTime = true; + private static Properties cacheProps = new Properties(); + /** + *First time requires initialization overhead.
+ */ + private static volatile boolean firstTime = true; static { // Use try/catch block to support applets @@ -83,63 +81,64 @@ System.err.println("JAXP: " + msg); } } - /** - *ClassLoader
to use to find SchemaFactory
.
ClassLoader
to use to find
+ * SchemaFactory
.
Constructor that specifies ClassLoader
to use
- * to find SchemaFactory
.
Constructor that specifies
+ * ClassLoader
to use to find
+ * SchemaFactory
.
Creates a new {@link SchemaFactory} object for the specified - * schema language.
+ *Creates a new {@link SchemaFactory} object for the specified schema + * language.
* - * @param schemaLanguage - * See {@link SchemaFactory Schema Language} table inSchemaFactory
- * for the list of available schema languages.
+ * @param schemaLanguage See {@link SchemaFactory Schema Language} table
+ * in SchemaFactory
for the list of available schema languages.
*
* @return null
if the callee fails to create one.
*
- * @throws NullPointerException
- * If the schemaLanguage
parameter is null.
+ * @throws NullPointerException If the schemaLanguage
parameter
+ * is null.
*/
- public SchemaFactory newFactory(String schemaLanguage) {
- if(schemaLanguage==null) throw new NullPointerException();
+ public SchemaFactory newFactory(String schemaLanguage)
+ throws FactoryConfigurationError {
+ if (schemaLanguage == null) {
+ throw new NullPointerException();
+ }
SchemaFactory f = _newFactory(schemaLanguage);
if (f != null) {
debugPrintln("factory '" + f.getClass().getName() + "' was found for " + schemaLanguage);
@@ -150,48 +149,56 @@
}
/**
- * Lookup a SchemaFactory
for the given schemaLanguage
.
Lookup a
+ * SchemaFactory
for the given
+ * schemaLanguage
.
SchemaFactory
for.
+ * @param schemaLanguage Schema language to
+ * lookup SchemaFactory
for.
*
- * @return SchemaFactory
for the given schemaLanguage
.
+ * @return SchemaFactory
for the
+ * given schemaLanguage
.
*/
- private SchemaFactory _newFactory(String schemaLanguage) {
+ private SchemaFactory _newFactory(String schemaLanguage)
+ throws FactoryConfigurationError {
SchemaFactory sf;
String propertyName = SERVICE_CLASS.getName() + ":" + schemaLanguage;
// system property look up
try {
- debugPrintln("Looking up system property '"+propertyName+"'" );
+ debugPrintln("Looking up system property '" + propertyName + "'");
String r = ss.getSystemProperty(propertyName);
- if(r!=null) {
- debugPrintln("The value is '"+r+"'");
+ if (r != null) {
+ debugPrintln("The value is '" + r + "'");
sf = createInstance(r, true);
- if(sf!=null) return sf;
- } else
+ if (sf != null) {
+ return sf;
+ }
+ } else {
debugPrintln("The property is undefined.");
- } catch( Throwable t ) {
- if( debug ) {
- debugPrintln("failed to look up system property '"+propertyName+"'" );
+ }
+ } catch (Throwable t) {
+ if (debug) {
+ debugPrintln("failed to look up system property '" + propertyName + "'");
t.printStackTrace();
}
}
- String javah = ss.getSystemProperty( "java.home" );
- String configFile = javah + File.separator +
- "lib" + File.separator + "jaxp.properties";
+ String javah = ss.getSystemProperty("java.home");
+ String configFile = javah + File.separator
+ + "lib" + File.separator + "jaxp.properties";
- String factoryClassName = null ;
+ String factoryClassName = null;
// try to read from $java.home/lib/jaxp.properties
try {
- if(firstTime){
- synchronized(cacheProps){
- if(firstTime){
- File f=new File( configFile );
+ if (firstTime) {
+ synchronized (cacheProps) {
+ if (firstTime) {
+ File f = new File(configFile);
firstTime = false;
- if(ss.doesFileExist(f)){
+ if (ss.doesFileExist(f)) {
debugPrintln("Read properties file " + f);
cacheProps.load(ss.getFileInputStream(f));
}
@@ -203,7 +210,7 @@
if (factoryClassName != null) {
sf = createInstance(factoryClassName, true);
- if(sf != null){
+ if (sf != null) {
return sf;
}
}
@@ -213,92 +220,61 @@
}
}
- /**
- // try to read from $java.home/lib/jaxp.properties
- try {
- String javah = ss.getSystemProperty( "java.home" );
- String configFile = javah + File.separator +
- "lib" + File.separator + "jaxp.properties";
- File f = new File( configFile );
- if( ss.doesFileExist(f)) {
- sf = loadFromProperty(
- propertyName,f.getAbsolutePath(), new FileInputStream(f));
- if(sf!=null) return sf;
- } else {
- debugPrintln("Tried to read "+ f.getAbsolutePath()+", but it doesn't exist.");
- }
- } catch(Throwable e) {
- if( debug ) {
- debugPrintln("failed to read $java.home/lib/jaxp.properties");
- e.printStackTrace();
- }
- }
- */
-
- // try META-INF/services files
- Iterator sitr = createServiceFileIterator();
- while(sitr.hasNext()) {
- URL resource = (URL)sitr.next();
- debugPrintln("looking into " + resource);
- try {
- sf = loadFromService(schemaLanguage,resource.toExternalForm(),
- ss.getURLInputStream(resource));
- if(sf!=null) return sf;
- } catch(IOException e) {
- if( debug ) {
- debugPrintln("failed to read "+resource);
- e.printStackTrace();
- }
- }
+
+ // try finding a service provider
+ sf = findServiceProvider(schemaLanguage, DEFAULT_IMPL_NAME);
+ if (sf != null) {
+ return sf;
}
// platform default
- if(schemaLanguage.equals("http://www.w3.org/2001/XMLSchema")) {
+ if (schemaLanguage.equals("http://www.w3.org/2001/XMLSchema")) {
debugPrintln("attempting to use the platform default XML Schema validator");
- return createInstance("com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory", true);
+ return createInstance(DEFAULT_IMPL_NAME, true);
}
debugPrintln("all things were tried, but none was found. bailing out.");
return null;
}
- /** Create class using appropriate ClassLoader.
+ /** + *Create class using appropriate ClassLoader.
* * @param className Name of class to create. * @return Created class ornull
.
*/
private Class createClass(String className) {
- Class clazz;
+ Class clazz;
- // use approprite ClassLoader
- try {
- if (classLoader != null) {
- clazz = classLoader.loadClass(className);
- } else {
- clazz = Class.forName(className);
- }
- } catch (Throwable t) {
- if(debug) t.printStackTrace();
- return null;
+ // use approprite ClassLoader
+ try {
+ if (classLoader != null) {
+ clazz = classLoader.loadClass(className);
+ } else {
+ clazz = Class.forName(className);
}
+ } catch (Throwable t) {
+ if (debug) {
+ t.printStackTrace();
+ }
+ return null;
+ }
- return clazz;
+ return clazz;
}
/**
* Creates an instance of the specified and returns it.
* - * @param className - * fully qualified class name to be instanciated. + * @param className fully qualified class name to be instanciated. * - * @return null - * if it fails. Error messages will be printed by this method. + * @return null if it fails. Error messages will be printed by this method. */ - SchemaFactory createInstance( String className ) { - return createInstance( className, false ); + SchemaFactory createInstance(String className) { + return createInstance(className, false); } - SchemaFactory createInstance( String className, boolean useServicesMechanism ) { + SchemaFactory createInstance(String className, boolean useServicesMechanism) { SchemaFactory schemaFactory = null; debugPrintln("createInstance(" + className + ")"); @@ -306,8 +282,8 @@ // get Class from className Class clazz = createClass(className); if (clazz == null) { - debugPrintln("failed to getClass(" + className + ")"); - return null; + debugPrintln("failed to getClass(" + className + ")"); + return null; } debugPrintln("loaded " + className + " from " + which(clazz)); @@ -316,234 +292,118 @@ if (!useServicesMechanism) { schemaFactory = (SchemaFactory) newInstanceNoServiceLoader(clazz); } - if (schemaFactory == null) { - schemaFactory = (SchemaFactory) clazz.newInstance(); - } + if (schemaFactory == null) { + schemaFactory = (SchemaFactory) clazz.newInstance(); + } } catch (ClassCastException classCastException) { - debugPrintln("could not instantiate " + clazz.getName()); - if (debug) { - classCastException.printStackTrace(); - } - return null; + debugPrintln("could not instantiate " + clazz.getName()); + if (debug) { + classCastException.printStackTrace(); + } + return null; } catch (IllegalAccessException illegalAccessException) { - debugPrintln("could not instantiate " + clazz.getName()); - if (debug) { - illegalAccessException.printStackTrace(); - } - return null; + debugPrintln("could not instantiate " + clazz.getName()); + if (debug) { + illegalAccessException.printStackTrace(); + } + return null; } catch (InstantiationException instantiationException) { - debugPrintln("could not instantiate " + clazz.getName()); - if (debug) { - instantiationException.printStackTrace(); - } - return null; + debugPrintln("could not instantiate " + clazz.getName()); + if (debug) { + instantiationException.printStackTrace(); + } + return null; } return schemaFactory; } + /** - * Try to construct using newTransformerFactoryNoServiceLoader - * method if available. + * Try to construct using newTransformerFactoryNoServiceLoader method if + * available. */ private static Object newInstanceNoServiceLoader( - Class> providerClass - ) { + Class> providerClass) { // Retain maximum compatibility if no security manager. if (System.getSecurityManager() == null) { return null; } try { Method creationMethod = - providerClass.getDeclaredMethod( - "newXMLSchemaFactoryNoServiceLoader" - ); - return creationMethod.invoke(null, null); - } catch (NoSuchMethodException exc) { - return null; - } catch (Exception exc) { - return null; + providerClass.getDeclaredMethod( + "newXMLSchemaFactoryNoServiceLoader"); + return creationMethod.invoke(null, null); + } catch (NoSuchMethodException exc) { + return null; + } catch (Exception exc) { + return null; } } - /** Iterator that lazily computes one value and returns it. */ - private static abstract class SingleIterator implements Iterator { - private boolean seen = false; - - public final void remove() { throw new UnsupportedOperationException(); } - public final boolean hasNext() { return !seen; } - public final Object next() { - if(seen) throw new NoSuchElementException(); - seen = true; - return value(); - } - - protected abstract Object value(); - } - /** - * Looks up a value in a property file - * while producing all sorts of debug messages. + /* + * Try to find a provider using Service Loader * - * @return null - * if there was an error. + * @return instance of provider class if found or null */ - private SchemaFactory loadFromProperty( String keyName, String resourceName, InputStream in ) - throws IOException { - debugPrintln("Reading "+resourceName ); - - Properties props=new Properties(); - props.load(in); - in.close(); - String factoryClassName = props.getProperty(keyName); - if(factoryClassName != null){ - debugPrintln("found "+keyName+" = " + factoryClassName); - return createInstance(factoryClassName); - } else { - debugPrintln(keyName+" is not in the property file"); - return null; + private SchemaFactory findServiceProvider(final String schemaLanguage, final String fallbackClassName) + throws FactoryConfigurationError { + try { + return (SchemaFactory) AccessController.doPrivileged(new PrivilegedAction() { + public SchemaFactory run() { + SchemaFactory defaultProvider = null; + for (SchemaFactory schemaFactory : ServiceLoader.load(SchemaFactory.class, classLoader)) { + if (schemaFactory.getClass().getName().equals(fallbackClassName)) { + defaultProvider = schemaFactory; + } else { + if (isSchemaSupported(schemaFactory, schemaLanguage)) { + return schemaFactory; + } + } + } + if (defaultProvider != null) { + return defaultProvider; + } + return null; + } + }); + } catch (ServiceConfigurationError e) { + throw new FactoryConfigurationError(e.getMessage(), (Exception) e.getCause()); } } /** - *Look up a value in a property file.
- * - *Set debug
to true
to trace property evaluation.
Test if the specified schemas are supported by the provider.
* + * @param schemaFactory a Schema factory provider. * @param schemaLanguage Schema Language to support. - * @param inputName Name ofInputStream
.
- * @param in InputStream
of properties.
*
- * @return SchemaFactory
as determined by keyName
value or null
if there was an error.
- *
- * @throws IOException If IO error reading from in
.
- */
- private SchemaFactory loadFromService(
- String schemaLanguage,
- String inputName,
- InputStream in)
- throws IOException {
-
- SchemaFactory schemaFactory = null;
- final Class[] stringClassArray = {"".getClass()};
- final Object[] schemaLanguageObjectArray = {schemaLanguage};
- final String isSchemaLanguageSupportedMethod = "isSchemaLanguageSupported";
-
- debugPrintln("Reading " + inputName);
-
- // read from InputStream until a match is found
- BufferedReader configFile = new BufferedReader(new InputStreamReader(in));
- String line = null;
- while ((line = configFile.readLine()) != null) {
- // '#' is comment char
- int comment = line.indexOf("#");
- switch (comment) {
- case -1: break; // no comment
- case 0: line = ""; break; // entire line is a comment
- default: line = line.substring(0, comment); break; // trim comment
- }
-
- // trim whitespace
- line = line.trim();
-
- // any content left on line?
- if (line.length() == 0) {
- continue;
- }
-
- // line content is now the name of the class
- Class clazz = createClass(line);
- if (clazz == null) {
- continue;
- }
-
- // create an instance of the Class
- try {
- schemaFactory = (SchemaFactory) clazz.newInstance();
- } catch (ClassCastException classCastExcpetion) {
- schemaFactory = null;
- continue;
- } catch (InstantiationException instantiationException) {
- schemaFactory = null;
- continue;
- } catch (IllegalAccessException illegalAccessException) {
- schemaFactory = null;
- continue;
- }
-
- // does this Class support desired Schema?
- try {
- Method isSchemaLanguageSupported = clazz.getMethod(isSchemaLanguageSupportedMethod, stringClassArray);
- Boolean supported = (Boolean) isSchemaLanguageSupported.invoke(schemaFactory, schemaLanguageObjectArray);
- if (supported.booleanValue()) {
- break;
- }
- } catch (NoSuchMethodException noSuchMethodException) {
-
- } catch (IllegalAccessException illegalAccessException) {
-
- } catch (InvocationTargetException invocationTargetException) {
-
- }
- schemaFactory = null;
- }
-
- // clean up
- configFile.close();
-
- // return new instance of SchemaFactory or null
- return schemaFactory;
- }
-
- /**
- * Returns an {@link Iterator} that enumerates all
- * the META-INF/services files that we care.
+ * @return true
if the Schema Language is supported by the
+ * provider.
*/
- private Iterator createServiceFileIterator() {
- if (classLoader == null) {
- return new SingleIterator() {
- protected Object value() {
- ClassLoader classLoader = SchemaFactoryFinder.class.getClassLoader();
- //return (ClassLoader.getSystemResource( SERVICE_ID ));
- return ss.getResourceAsURL(classLoader, SERVICE_ID);
- }
- };
- } else {
- try {
- //final Enumeration e = classLoader.getResources(SERVICE_ID);
- final Enumeration e = ss.getResources(classLoader, SERVICE_ID);
- if(!e.hasMoreElements()) {
- debugPrintln("no "+SERVICE_ID+" file was found");
- }
-
- // wrap it into an Iterator.
- return new Iterator() {
- public void remove() {
- throw new UnsupportedOperationException();
- }
+ private static boolean isSchemaSupported(SchemaFactory schemaFactory, String schemaLanguage) {
+ final Class[] stringClassArray = {"".getClass()};
+ final Object[] schemaLanguageObjectArray = {schemaLanguage};
+ final String isSchemaLanguageSupportedMethod = "isSchemaLanguageSupported";
- public boolean hasNext() {
- return e.hasMoreElements();
- }
-
- public Object next() {
- return e.nextElement();
- }
- };
- } catch (IOException e) {
- debugPrintln("failed to enumerate resources "+SERVICE_ID);
- if(debug) e.printStackTrace();
- return new ArrayList().iterator(); // empty iterator
+ // does this Class support desired Schema?
+ try {
+ Method isSchemaLanguageSupported = schemaFactory.getClass().getMethod(isSchemaLanguageSupportedMethod, stringClassArray);
+ Boolean supported = (Boolean) isSchemaLanguageSupported.invoke(schemaFactory, schemaLanguageObjectArray);
+ if (supported.booleanValue()) {
+ return true;
}
+ } catch (NoSuchMethodException noSuchMethodException) {
+ } catch (IllegalAccessException illegalAccessException) {
+ } catch (InvocationTargetException invocationTargetException) {
}
- }
+ return false;
+ }
private static final Class SERVICE_CLASS = SchemaFactory.class;
- private static final String SERVICE_ID = "META-INF/services/" + SERVICE_CLASS.getName();
-
-
- private static String which( Class clazz ) {
- return which( clazz.getName(), clazz.getClassLoader() );
+ private static String which(Class clazz) {
+ return which(clazz.getName(), clazz.getClassLoader());
}
/**
@@ -558,7 +418,9 @@
String classnameAsResource = classname.replace('.', '/') + ".class";
- if( loader==null ) loader = ClassLoader.getSystemClassLoader();
+ if (loader == null) {
+ loader = ClassLoader.getSystemClassLoader();
+ }
//URL it = loader.getResource(classnameAsResource);
URL it = ss.getResourceAsURL(loader, classnameAsResource);