--- old/src/javax/xml/validation/SchemaFactoryFinder.java 2013-01-09 12:44:09.000000000 +0100 +++ new/src/javax/xml/validation/SchemaFactoryFinder.java 2013-01-09 12:44:08.000000000 +0100 @@ -25,19 +25,16 @@ 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.Modifier; import java.net.URL; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.NoSuchElementException; +import java.security.AccessControlContext; +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)}. @@ -53,16 +50,15 @@ /** *
Take care of restrictions imposed by java security model
*/ - private static SecuritySupport ss = new SecuritySupport(); + private static final 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 final Properties cacheProps = new Properties(); + /** + *First time requires initialization overhead.
+ */ + private static volatile boolean firstTime = true; static { // Use try/catch block to support applets @@ -114,7 +110,7 @@ return; } } catch( Throwable _ ) { - ; // getContextClassLoader() undefined in JDK1.1 + // getContextClassLoader() undefined in JDK1.1 } if( classLoader==ClassLoader.getSystemClassLoader() ) { @@ -137,9 +133,13 @@ * * @throws NullPointerException * If theschemaLanguage
parameter is null.
+ * @throws SchemaFactoryConfigurationError
+ * If a configuration error is encountered.
*/
public SchemaFactory newFactory(String schemaLanguage) {
- if(schemaLanguage==null) throw new NullPointerException();
+ if(schemaLanguage==null) {
+ throw new NullPointerException();
+ }
SchemaFactory f = _newFactory(schemaLanguage);
if (f != null) {
debugPrintln("factory '" + f.getClass().getName() + "' was found for " + schemaLanguage);
@@ -182,7 +182,7 @@
String configFile = javah + File.separator +
"lib" + File.separator + "jaxp.properties";
- String factoryClassName = null ;
+ String factoryClassName;
// try to read from $java.home/lib/jaxp.properties
try {
@@ -213,43 +213,11 @@
}
}
- /**
- // 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 with ServiceLoader
+ final SchemaFactory factoryImpl = findServiceProvider(schemaLanguage);
+ assert factoryImpl == null || factoryImpl.isSchemaLanguageSupported(schemaLanguage);
+ if (factoryImpl != null) {
+ return factoryImpl;
}
// platform default
@@ -267,29 +235,31 @@
* @param className Name of class to create.
* @return Created class or null
.
*/
- private Class createClass(String className) {
- Class clazz;
+ private Class> createClass(String className) {
+ 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 = Class.forName(className, false, classLoader);
+ } 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. + * fully qualified class name to be instantiated. * * @return null * if it fails. Error messages will be printed by this method. @@ -304,7 +274,7 @@ debugPrintln("createInstance(" + className + ")"); // get Class from className - Class clazz = createClass(className); + Class> clazz = createClass(className); if (clazz == null) { debugPrintln("failed to getClass(" + className + ")"); return null; @@ -313,9 +283,13 @@ // instantiate Class as a SchemaFactory try { - if (!useServicesMechanism) { - schemaFactory = (SchemaFactory) newInstanceNoServiceLoader(clazz); - } + if (!SchemaFactory.class.isAssignableFrom(clazz)) { + throw new ClassCastException(clazz.getName() + + " cannot be cast to " + SchemaFactory.class); + } + if (!useServicesMechanism) { + schemaFactory = newInstanceNoServiceLoader(clazz); + } if (schemaFactory == null) { schemaFactory = (SchemaFactory) clazz.newInstance(); } @@ -341,11 +315,12 @@ return schemaFactory; } + /** - * Try to construct using newTransformerFactoryNoServiceLoader + * Try to construct using newXMLSchemaFactoryNoServiceLoader * method if available. */ - private static Object newInstanceNoServiceLoader( + private static SchemaFactory newInstanceNoServiceLoader( Class> providerClass ) { // Retain maximum compatibility if no security manager. @@ -353,196 +328,87 @@ return null; } try { - Method creationMethod = + final Method creationMethod = providerClass.getDeclaredMethod( "newXMLSchemaFactoryNoServiceLoader" ); - return creationMethod.invoke(null, (Object[])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(); - } + final int modifiers = creationMethod.getModifiers(); - protected abstract Object value(); - } - - /** - * Looks up a value in a property file - * while producing all sorts of debug messages. - * - * @return null - * if there was an error. - */ - 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"); + // Do not call the method if it's not public static. + if (!Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) { + return null; + } + + // Only calls "newXMLSchemaFactoryNoServiceLoader" if it's + // declared to return an instance of SchemaFactory. + final Class> returnType = creationMethod.getReturnType(); + if (SERVICE_CLASS.isAssignableFrom(returnType)) { + return SERVICE_CLASS.cast(creationMethod.invoke(null, (Object[])null)); + } else { + // Should not happen since + // XMLSchemaFactory.newXMLSchemaFactoryNoServiceLoader is + // declared to return XMLSchemaFactory. + throw new ClassCastException(returnType + + " cannot be cast to " + SERVICE_CLASS); + } + } catch(ClassCastException e) { + throw new SchemaFactoryConfigurationError(e.getMessage(), e); + } catch (NoSuchMethodException exc) { + return null; + } catch (Exception exc) { return null; } } - /** - *Look up a value in a property file.
- * - *Set debug
to true
to trace property evaluation.
InputStream
.
- * @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;
+ // Call isSchemaLanguageSupported with initial context.
+ private boolean isSchemaLanguageSupportedBy(final SchemaFactory factory,
+ final String schemaLanguage,
+ AccessControlContext acc) {
+ return AccessController.doPrivileged(new PrivilegedAction