190 lines
6.6 KiB
Java
190 lines
6.6 KiB
Java
package org.apache.xerces.parsers;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InputStreamReader;
|
|
import java.io.UnsupportedEncodingException;
|
|
import java.util.Properties;
|
|
|
|
class ObjectFactory {
|
|
private static final String DEFAULT_PROPERTIES_FILENAME = "xerces.properties";
|
|
|
|
private static final boolean DEBUG = false;
|
|
|
|
private static Properties fXercesProperties = null;
|
|
|
|
private static long fLastModified = -1L;
|
|
|
|
static Object createObject(String factoryId, String fallbackClassName) throws ConfigurationError {
|
|
return createObject(factoryId, null, fallbackClassName);
|
|
}
|
|
|
|
public static Object createObject(String factoryId, String propertiesFilename, String fallbackClassName) throws ConfigurationError {
|
|
debugPrintln("debug is on");
|
|
SecuritySupport ss = SecuritySupport.getInstance();
|
|
ClassLoader cl = findClassLoader();
|
|
try {
|
|
String systemProp = ss.getSystemProperty(factoryId);
|
|
if (systemProp != null) {
|
|
debugPrintln("found system property, value=" + systemProp);
|
|
return newInstance(systemProp, cl, true);
|
|
}
|
|
} catch (SecurityException se) {}
|
|
String factoryClassName = null;
|
|
if (propertiesFilename == null) {
|
|
String javah = ss.getSystemProperty("java.home");
|
|
propertiesFilename = javah + File.separator + "lib" + File.separator + "xerces.properties";
|
|
File propertiesFile = new File(propertiesFilename);
|
|
boolean propertiesFileExists = ss.getFileExists(propertiesFile);
|
|
synchronized (ObjectFactory.class) {
|
|
boolean loadProperties = false;
|
|
if (fLastModified >= 0L) {
|
|
if (propertiesFileExists && fLastModified < (fLastModified = ss.getLastModified(propertiesFile))) {
|
|
loadProperties = true;
|
|
} else if (!propertiesFileExists) {
|
|
fLastModified = -1L;
|
|
fXercesProperties = null;
|
|
}
|
|
} else if (propertiesFileExists) {
|
|
loadProperties = true;
|
|
fLastModified = ss.getLastModified(propertiesFile);
|
|
}
|
|
if (loadProperties)
|
|
try {
|
|
fXercesProperties = new Properties();
|
|
FileInputStream fis = ss.getFileInputStream(propertiesFile);
|
|
fXercesProperties.load(fis);
|
|
fis.close();
|
|
} catch (Exception x) {
|
|
fXercesProperties = null;
|
|
fLastModified = -1L;
|
|
}
|
|
}
|
|
if (fXercesProperties != null)
|
|
factoryClassName = fXercesProperties.getProperty(factoryId);
|
|
} else {
|
|
try {
|
|
FileInputStream fis = ss.getFileInputStream(new File(propertiesFilename));
|
|
Properties props = new Properties();
|
|
props.load(fis);
|
|
fis.close();
|
|
factoryClassName = props.getProperty(factoryId);
|
|
} catch (Exception x) {}
|
|
}
|
|
if (factoryClassName != null) {
|
|
debugPrintln("found in " + propertiesFilename + ", value=" + factoryClassName);
|
|
return newInstance(factoryClassName, cl, true);
|
|
}
|
|
Object provider = findJarServiceProvider(factoryId);
|
|
if (provider != null)
|
|
return provider;
|
|
if (fallbackClassName == null)
|
|
throw new ConfigurationError("Provider for " + factoryId + " cannot be found", null);
|
|
debugPrintln("using fallback, value=" + fallbackClassName);
|
|
return newInstance(fallbackClassName, cl, true);
|
|
}
|
|
|
|
private static void debugPrintln(String msg) {}
|
|
|
|
static ClassLoader findClassLoader() throws ConfigurationError {
|
|
SecuritySupport ss = SecuritySupport.getInstance();
|
|
ClassLoader cl = ss.getContextClassLoader();
|
|
if (cl == null)
|
|
cl = ObjectFactory.class.getClassLoader();
|
|
return cl;
|
|
}
|
|
|
|
static Object newInstance(String className, ClassLoader cl, boolean doFallback) throws ConfigurationError {
|
|
try {
|
|
Class providerClass = findProviderClass(className, cl, doFallback);
|
|
Object instance = providerClass.newInstance();
|
|
debugPrintln("created new instance of " + providerClass + " using ClassLoader: " + cl);
|
|
return instance;
|
|
} catch (ClassNotFoundException x) {
|
|
throw new ConfigurationError("Provider " + className + " not found", x);
|
|
} catch (Exception x) {
|
|
throw new ConfigurationError("Provider " + className + " could not be instantiated: " + x, x);
|
|
}
|
|
}
|
|
|
|
static Class findProviderClass(String className, ClassLoader cl, boolean doFallback) throws ClassNotFoundException, ConfigurationError {
|
|
Class providerClass;
|
|
SecurityManager security = System.getSecurityManager();
|
|
try {
|
|
if (security != null)
|
|
security.checkPackageAccess(className);
|
|
} catch (SecurityException e) {
|
|
throw e;
|
|
}
|
|
if (cl == null) {
|
|
providerClass = Class.forName(className);
|
|
} else {
|
|
try {
|
|
providerClass = cl.loadClass(className);
|
|
} catch (ClassNotFoundException x) {
|
|
if (doFallback) {
|
|
cl = ObjectFactory.class.getClassLoader();
|
|
providerClass = cl.loadClass(className);
|
|
} else {
|
|
throw x;
|
|
}
|
|
}
|
|
}
|
|
return providerClass;
|
|
}
|
|
|
|
private static Object findJarServiceProvider(String factoryId) throws ConfigurationError {
|
|
BufferedReader rd;
|
|
SecuritySupport ss = SecuritySupport.getInstance();
|
|
String serviceId = "META-INF/services/" + factoryId;
|
|
InputStream is = null;
|
|
ClassLoader cl = ss.getContextClassLoader();
|
|
if (cl != null) {
|
|
is = ss.getResourceAsStream(cl, serviceId);
|
|
if (is == null) {
|
|
cl = ObjectFactory.class.getClassLoader();
|
|
is = ss.getResourceAsStream(cl, serviceId);
|
|
}
|
|
} else {
|
|
cl = ObjectFactory.class.getClassLoader();
|
|
is = ss.getResourceAsStream(cl, serviceId);
|
|
}
|
|
if (is == null)
|
|
return null;
|
|
debugPrintln("found jar resource=" + serviceId + " using ClassLoader: " + cl);
|
|
try {
|
|
rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
|
|
} catch (UnsupportedEncodingException e) {
|
|
rd = new BufferedReader(new InputStreamReader(is));
|
|
}
|
|
String factoryClassName = null;
|
|
try {
|
|
factoryClassName = rd.readLine();
|
|
rd.close();
|
|
} catch (IOException x) {
|
|
return null;
|
|
}
|
|
if (factoryClassName != null && !"".equals(factoryClassName)) {
|
|
debugPrintln("found in resource, value=" + factoryClassName);
|
|
return newInstance(factoryClassName, cl, false);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
static class ConfigurationError extends Error {
|
|
private Exception exception;
|
|
|
|
ConfigurationError(String msg, Exception x) {
|
|
super(msg);
|
|
this.exception = x;
|
|
}
|
|
|
|
Exception getException() {
|
|
return this.exception;
|
|
}
|
|
}
|
|
}
|