src.javax.xml.stream.FactoryFinder Maven / Gradle / Ivy
package javax.xml.stream;
import java.io.InputStream;
import java.io.IOException;
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
import java.io.BufferedReader;
import java.io.InputStreamReader;
class FactoryFinder {
/** Temp debug code - this will be removed after we test everything
*/
private static boolean debug = false;
static {
// Use try/catch block to support applets
try {
debug = System.getProperty("xml.stream.debug") != null;
} catch (Exception x) {
}
}
private static void debugPrintln(String msg) {
if (debug) {
System.err.println("STREAM: " + msg);
}
}
private static ClassLoader findClassLoader()
throws FactoryConfigurationError
{
ClassLoader classLoader;
try {
// Construct the name of the concrete class to instantiate
Class clazz = Class.forName(FactoryFinder.class.getName()
+ "$ClassLoaderFinderConcrete");
ClassLoaderFinder clf = (ClassLoaderFinder) clazz.newInstance();
classLoader = clf.getContextClassLoader();
} catch (LinkageError le) {
// Assume that we are running JDK 1.1, use the current ClassLoader
classLoader = FactoryFinder.class.getClassLoader();
} catch (ClassNotFoundException x) {
// This case should not normally happen. MS IE can throw this
// instead of a LinkageError the second time Class.forName() is
// called so assume that we are running JDK 1.1 and use the
// current ClassLoader
classLoader = FactoryFinder.class.getClassLoader();
} catch (Exception x) {
// Something abnormal happened so throw an error
throw new FactoryConfigurationError(x.toString(), x);
}
return classLoader;
}
/**
* Create an instance of a class using the specified ClassLoader
*/
private static Object newInstance(String className,
ClassLoader classLoader)
throws FactoryConfigurationError
{
try {
Class spiClass;
if (classLoader == null) {
spiClass = Class.forName(className);
} else {
spiClass = classLoader.loadClass(className);
}
return spiClass.newInstance();
} catch (ClassNotFoundException x) {
throw new FactoryConfigurationError(
"Provider " + className + " not found", x);
} catch (Exception x) {
throw new FactoryConfigurationError(
"Provider " + className + " could not be instantiated: " + x,
x);
}
}
static Object find(String factoryId)
throws FactoryConfigurationError
{
return find(factoryId,null);
}
static Object find(String factoryId,
String fallbackClassName)
throws FactoryConfigurationError
{
ClassLoader classLoader = findClassLoader();
return find(factoryId,fallbackClassName,classLoader);
}
/**
* Finds the implementation Class object in the specified order. Main
* entry point.
* @return Class object of factory, never null
*
* @param factoryId Name of the factory to find, same as
* a property name
* @param fallbackClassName Implementation class name, if nothing else
* is found. Use null to mean no fallback.
*
* Package private so this code can be shared.
*/
static Object find(String factoryId,
String fallbackClassName,
ClassLoader classLoader)
throws FactoryConfigurationError
{
// Use the system property first
try {
String systemProp =
System.getProperty( factoryId );
if( systemProp!=null) {
debugPrintln("found system property" + systemProp);
return newInstance(systemProp, classLoader);
}
} catch (SecurityException se) {
}
// try to read from $java.home/lib/xml.properties
try {
String javah=System.getProperty( "java.home" );
String configFile = javah + File.separator +
"lib" + File.separator + "jaxp.properties";
File f=new File( configFile );
if( f.exists()) {
Properties props=new Properties();
props.load( new FileInputStream(f));
String factoryClassName = props.getProperty(factoryId);
debugPrintln("found java.home property " + factoryClassName);
return newInstance(factoryClassName, classLoader);
}
} catch(Exception ex ) {
if( debug ) ex.printStackTrace();
}
String serviceId = "META-INF/services/" + factoryId;
// try to find services in CLASSPATH
try {
InputStream is=null;
if (classLoader == null) {
is=ClassLoader.getSystemResourceAsStream( serviceId );
} else {
is=classLoader.getResourceAsStream( serviceId );
}
if( is!=null ) {
debugPrintln("found " + serviceId);
BufferedReader rd =
new BufferedReader(new InputStreamReader(is, "UTF-8"));
String factoryClassName = rd.readLine();
rd.close();
if (factoryClassName != null &&
! "".equals(factoryClassName)) {
debugPrintln("loaded from services: " + factoryClassName);
return newInstance(factoryClassName, classLoader);
}
}
} catch( Exception ex ) {
if( debug ) ex.printStackTrace();
}
if (fallbackClassName == null) {
throw new FactoryConfigurationError(
"Provider for " + factoryId + " cannot be found", null);
}
debugPrintln("loaded from fallback value: " + fallbackClassName);
return newInstance(fallbackClassName, classLoader);
}
/*
* The following nested classes allow getContextClassLoader() to be
* called only on JDK 1.2 and yet run in older JDK 1.1 JVMs
*/
private static abstract class ClassLoaderFinder {
abstract ClassLoader getContextClassLoader();
}
static class ClassLoaderFinderConcrete extends ClassLoaderFinder {
ClassLoader getContextClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy