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; } } }