This commit was manufactured by cvs2svn to create tag
'jaxp_02_12_2004'.
git-svn-id: https://svn.apache.org/repos/asf/xalan/java/tags/jaxp_02_12_2004@337858 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/org/apache/xalan/extensions/ExtensionHandler.java b/src/org/apache/xalan/extensions/ExtensionHandler.java
index 4d365ae..f7fd5bf 100644
--- a/src/org/apache/xalan/extensions/ExtensionHandler.java
+++ b/src/org/apache/xalan/extensions/ExtensionHandler.java
@@ -65,7 +65,7 @@
import org.apache.xalan.templates.Stylesheet;
import org.apache.xalan.transformer.TransformerImpl;
import org.apache.xpath.functions.FuncExtFunction;
-import org.apache.xml.utils.ObjectFactory;
+
/**
* Abstract base class for handling an extension namespace for XPath.
diff --git a/src/org/apache/xalan/extensions/ExtensionHandlerGeneral.java b/src/org/apache/xalan/extensions/ExtensionHandlerGeneral.java
index 96b29dc..900e873 100644
--- a/src/org/apache/xalan/extensions/ExtensionHandlerGeneral.java
+++ b/src/org/apache/xalan/extensions/ExtensionHandlerGeneral.java
@@ -73,7 +73,7 @@
import org.apache.xalan.transformer.TransformerImpl;
import org.apache.xml.dtm.DTMIterator;
import org.apache.xml.dtm.ref.DTMNodeList;
-import org.apache.xml.utils.ObjectFactory;
+
import org.apache.xml.utils.StringVector;
import org.apache.xml.utils.SystemIDResolver;
import org.apache.xpath.XPathProcessorException;
diff --git a/src/org/apache/xalan/extensions/ObjectFactory.java b/src/org/apache/xalan/extensions/ObjectFactory.java
new file mode 100755
index 0000000..7302c1b
--- /dev/null
+++ b/src/org/apache/xalan/extensions/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.extensions;
+
+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;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+ //
+ // Constants
+ //
+
+ // name of default properties file to look for in JDK's jre/lib directory
+ private static final String DEFAULT_PROPERTIES_FILENAME =
+ "xalan.properties";
+
+ private static final String SERVICES_PATH = "META-INF/services";
+
+ /** Set to true for debugging */
+ private static final boolean DEBUG = false;
+
+ /** cache the contents of the xalan.properties file.
+ * Until an attempt has been made to read this file, this will
+ * be null; if the file does not exist or we encounter some other error
+ * during the read, this will be empty.
+ */
+ private static Properties fXalanProperties = null;
+
+ /***
+ * Cache the time stamp of the xalan.properties file so
+ * that we know if it's been modified and can invalidate
+ * the cache when necessary.
+ */
+ private static long fLastModified = -1;
+
+ //
+ // Public static methods
+ //
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance 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.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId, String fallbackClassName)
+ throws ConfigurationError {
+ return createObject(factoryId, null, fallbackClassName);
+ } // createObject(String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ Class factoryClass = lookUpFactoryClass(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+
+ if (factoryClass == null) {
+ throw new ConfigurationError(
+ "Provider for " + factoryId + " cannot be found", null);
+ }
+
+ try{
+ Object instance = factoryClass.newInstance();
+ debugPrintln("created new instance of factory " + factoryId);
+ return instance;
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider for factory " + factoryId
+ + " could not be instantiated: " + x, x);
+ }
+ } // createObject(String,String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId)
+ throws ConfigurationError
+ {
+ return lookUpFactoryClass(factoryId, null, null);
+ } // lookUpFactoryClass(String):Class
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ String factoryClassName = lookUpFactoryClassName(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+ ClassLoader cl = findClassLoader();
+
+ if (factoryClassName == null) {
+ factoryClassName = fallbackClassName;
+ }
+
+ // assert(className != null);
+ try{
+ Class providerClass = findProviderClass(factoryClassName,
+ cl,
+ true);
+ debugPrintln("created new instance of " + providerClass +
+ " using ClassLoader: " + cl);
+ return providerClass;
+ } catch (ClassNotFoundException x) {
+ throw new ConfigurationError(
+ "Provider " + factoryClassName + " not found", x);
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider "+factoryClassName+" could not be instantiated: "+x,
+ x);
+ }
+ } // lookUpFactoryClass(String,String,String):Class
+
+ /**
+ * Finds the name of the required implementation class in the specified
+ * order. The specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return name of class that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static String lookUpFactoryClassName(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Use the system property first
+ try {
+ String systemProp = ss.getSystemProperty(factoryId);
+ if (systemProp != null) {
+ debugPrintln("found system property, value=" + systemProp);
+ return systemProp;
+ }
+ } catch (SecurityException se) {
+ // Ignore and continue w/ next location
+ }
+
+ // Try to read from propertiesFilename, or
+ // $java.home/lib/xalan.properties
+ String factoryClassName = null;
+ // no properties file name specified; use
+ // $JAVA_HOME/lib/xalan.properties:
+ if (propertiesFilename == null) {
+ File propertiesFile = null;
+ boolean propertiesFileExists = false;
+ try {
+ String javah = ss.getSystemProperty("java.home");
+ propertiesFilename = javah + File.separator +
+ "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+ propertiesFile = new File(propertiesFilename);
+ propertiesFileExists = ss.getFileExists(propertiesFile);
+ } catch (SecurityException e) {
+ // try again...
+ fLastModified = -1;
+ fXalanProperties = null;
+ }
+
+ synchronized (ObjectFactory.class) {
+ boolean loadProperties = false;
+ try {
+ // file existed last time
+ if(fLastModified >= 0) {
+ if(propertiesFileExists &&
+ (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+ loadProperties = true;
+ } else {
+ // file has stopped existing...
+ if(!propertiesFileExists) {
+ fLastModified = -1;
+ fXalanProperties = null;
+ } // else, file wasn't modified!
+ }
+ } else {
+ // file has started to exist:
+ if(propertiesFileExists) {
+ loadProperties = true;
+ fLastModified = ss.getLastModified(propertiesFile);
+ } // else, nothing's changed
+ }
+ if(loadProperties) {
+ // must never have attempted to read xalan.properties
+ // before (or it's outdeated)
+ fXalanProperties = new Properties();
+ FileInputStream fis =
+ ss.getFileInputStream(propertiesFile);
+ fXalanProperties.load(fis);
+ fis.close();
+ }
+ } catch (Exception x) {
+ fXalanProperties = null;
+ fLastModified = -1;
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if(fXalanProperties != null) {
+ factoryClassName = fXalanProperties.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) {
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if (factoryClassName != null) {
+ debugPrintln("found in " + propertiesFilename + ", value="
+ + factoryClassName);
+ return factoryClassName;
+ }
+
+ // Try Jar Service Provider Mechanism
+ return findJarServiceProviderName(factoryId);
+ } // lookUpFactoryClass(String,String):String
+
+ //
+ // Private static methods
+ //
+
+ /** Prints a message to standard error if debugging is enabled. */
+ private static void debugPrintln(String msg) {
+ if (DEBUG) {
+ System.err.println("JAXP: " + msg);
+ }
+ } // debugPrintln(String)
+
+ /**
+ * Figure out which ClassLoader to use. For JDK 1.2 and later use
+ * the context ClassLoader.
+ */
+ static ClassLoader findClassLoader()
+ throws ConfigurationError
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Figure out which ClassLoader to use for loading the provider
+ // class. If there is a Context ClassLoader then use it.
+ ClassLoader context = ss.getContextClassLoader();
+ ClassLoader system = ss.getSystemClassLoader();
+
+ ClassLoader chain = system;
+ while (true) {
+ if (context == chain) {
+ // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+ // or any Context ClassLoader in chain of system classloader
+ // (including extension ClassLoader) so extend to widest
+ // ClassLoader (always look in system ClassLoader if Xalan
+ // is in boot/extension/system classpath and in current
+ // ClassLoader otherwise); normal classloaders delegate
+ // back to system ClassLoader first so this widening doesn't
+ // change the fact that context ClassLoader will be consulted
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+
+ chain = system;
+ while (true) {
+ if (current == chain) {
+ // Assert: Current ClassLoader in chain of
+ // boot/extension/system ClassLoaders
+ return system;
+ }
+ if (chain == null) {
+ break;
+ }
+ chain = ss.getParentClassLoader(chain);
+ }
+
+ // Assert: Current ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return current;
+ }
+
+ if (chain == null) {
+ // boot ClassLoader reached
+ break;
+ }
+
+ // Check for any extension ClassLoaders in chain up to
+ // boot ClassLoader
+ chain = ss.getParentClassLoader(chain);
+ };
+
+ // Assert: Context ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return context;
+ } // findClassLoader():ClassLoader
+
+ /**
+ * Create an instance of a class using the specified ClassLoader
+ */
+ static Object newInstance(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ConfigurationError
+ {
+ // assert(className != null);
+ 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);
+ }
+ }
+
+ /**
+ * Find a Class using the specified ClassLoader
+ */
+ static Class findProviderClass(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ClassNotFoundException, ConfigurationError
+ {
+
+ SecurityManager security = System.getSecurityManager();
+ try{
+ if (security != null)
+ security.checkPackageAccess(className);
+ }catch(SecurityException e){
+ throw e;
+ }
+
+ Class providerClass;
+ if (cl == null) {
+ // XXX Use the bootstrap ClassLoader. There is no way to
+ // load a class using the bootstrap ClassLoader that works
+ // in both JDK 1.1 and Java 2. However, this should still
+ // work b/c the following should be true:
+ //
+ // (cl == null) iff current ClassLoader == null
+ //
+ // Thus Class.forName(String) will use the current
+ // ClassLoader which will be the bootstrap ClassLoader.
+ providerClass = Class.forName(className);
+ } else {
+ try {
+ providerClass = cl.loadClass(className);
+ } catch (ClassNotFoundException x) {
+ if (doFallback) {
+ // Fall back to current classloader
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (current == null) {
+ providerClass = Class.forName(className);
+ } else if (cl != current) {
+ cl = current;
+ providerClass = cl.loadClass(className);
+ } else {
+ throw x;
+ }
+ } else {
+ throw x;
+ }
+ }
+ }
+
+ return providerClass;
+ }
+
+ /**
+ * Find the name of service provider using Jar Service Provider Mechanism
+ *
+ * @return instance of provider class if found or null
+ */
+ private static String findJarServiceProviderName(String factoryId)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+ String serviceId = SERVICES_PATH + factoryId;
+ InputStream is = null;
+
+ // First try the Context ClassLoader
+ ClassLoader cl = findClassLoader();
+
+ is = ss.getResourceAsStream(cl, serviceId);
+
+ // If no provider found then try the current ClassLoader
+ if (is == null) {
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (cl != current) {
+ cl = current;
+ is = ss.getResourceAsStream(cl, serviceId);
+ }
+ }
+
+ if (is == null) {
+ // No provider found
+ return null;
+ }
+
+ debugPrintln("found jar resource=" + serviceId +
+ " using ClassLoader: " + cl);
+
+ // Read the service provider name in UTF-8 as specified in
+ // the jar spec. Unfortunately this fails in Microsoft
+ // VJ++, which does not implement the UTF-8
+ // encoding. Theoretically, we should simply let it fail in
+ // that case, since the JVM is obviously broken if it
+ // doesn't support such a basic standard. But since there
+ // are still some users attempting to use VJ++ for
+ // development, we have dropped in a fallback which makes a
+ // second attempt using the platform's default encoding. In
+ // VJ++ this is apparently ASCII, which is a subset of
+ // UTF-8... and since the strings we'll be reading here are
+ // also primarily limited to the 7-bit ASCII range (at
+ // least, in English versions), this should work well
+ // enough to keep us on the air until we're ready to
+ // officially decommit from VJ++. [Edited comment from
+ // jkesselm]
+ BufferedReader rd;
+ try {
+ rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ } catch (java.io.UnsupportedEncodingException e) {
+ rd = new BufferedReader(new InputStreamReader(is));
+ }
+
+ String factoryClassName = null;
+ try {
+ // XXX Does not handle all possible input as specified by the
+ // Jar Service Provider specification
+ factoryClassName = rd.readLine();
+ rd.close();
+ } catch (IOException x) {
+ // No provider found
+ return null;
+ }
+
+ if (factoryClassName != null &&
+ ! "".equals(factoryClassName)) {
+ debugPrintln("found in resource, value="
+ + factoryClassName);
+
+ // Note: here we do not want to fall back to the current
+ // ClassLoader because we want to avoid the case where the
+ // resource file was found using one ClassLoader and the
+ // provider class was instantiated using a different one.
+ return factoryClassName;
+ }
+
+ // No provider found
+ return null;
+ }
+
+ //
+ // Classes
+ //
+
+ /**
+ * A configuration error.
+ */
+ static class ConfigurationError
+ extends Error {
+
+ //
+ // Data
+ //
+
+ /** Exception. */
+ private Exception exception;
+
+ //
+ // Constructors
+ //
+
+ /**
+ * Construct a new instance with the specified detail string and
+ * exception.
+ */
+ public ConfigurationError(String msg, Exception x) {
+ super(msg);
+ this.exception = x;
+ } // <init>(String,Exception)
+
+ //
+ // Public methods
+ //
+
+ /** Returns the exception associated to this error. */
+ public Exception getException() {
+ return exception;
+ } // getException():Exception
+
+ } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xalan/extensions/SecuritySupport.java b/src/org/apache/xalan/extensions/SecuritySupport.java
new file mode 100755
index 0000000..c647419
--- /dev/null
+++ b/src/org/apache/xalan/extensions/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.extensions;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+ /*
+ * Make this of type Object so that the verifier won't try to
+ * prove its type, thus possibly trying to load the SecuritySupport12
+ * class.
+ */
+ private static final Object securitySupport;
+
+ static {
+ SecuritySupport ss = null;
+ try {
+ Class c = Class.forName("java.security.AccessController");
+ // if that worked, we're on 1.2.
+ /*
+ // don't reference the class explicitly so it doesn't
+ // get dragged in accidentally.
+ c = Class.forName("javax.mail.SecuritySupport12");
+ Constructor cons = c.getConstructor(new Class[] { });
+ ss = (SecuritySupport)cons.newInstance(new Object[] { });
+ */
+ /*
+ * Unfortunately, we can't load the class using reflection
+ * because the class is package private. And the class has
+ * to be package private so the APIs aren't exposed to other
+ * code that could use them to circumvent security. Thus,
+ * we accept the risk that the direct reference might fail
+ * on some JDK 1.1 JVMs, even though we would never execute
+ * this code in such a case. Sigh...
+ */
+ ss = new SecuritySupport12();
+ } catch (Exception ex) {
+ // ignore it
+ } finally {
+ if (ss == null)
+ ss = new SecuritySupport();
+ securitySupport = ss;
+ }
+ }
+
+ /**
+ * Return an appropriate instance of this class, depending on whether
+ * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+ */
+ static SecuritySupport getInstance() {
+ return (SecuritySupport)securitySupport;
+ }
+
+ ClassLoader getContextClassLoader() {
+ return null;
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return null;
+ }
+
+ ClassLoader getParentClassLoader(ClassLoader cl) {
+ return null;
+ }
+
+ String getSystemProperty(String propName) {
+ return System.getProperty(propName);
+ }
+
+ FileInputStream getFileInputStream(File file)
+ throws FileNotFoundException
+ {
+ return new FileInputStream(file);
+ }
+
+ InputStream getResourceAsStream(ClassLoader cl, String name) {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+
+ boolean getFileExists(File f) {
+ return f.exists();
+ }
+
+ long getLastModified(File f) {
+ return f.lastModified();
+ }
+}
diff --git a/src/org/apache/xalan/extensions/SecuritySupport12.java b/src/org/apache/xalan/extensions/SecuritySupport12.java
new file mode 100755
index 0000000..4043e1d
--- /dev/null
+++ b/src/org/apache/xalan/extensions/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.extensions;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+ ClassLoader getContextClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = Thread.currentThread().getContextClassLoader();
+ } catch (SecurityException ex) { }
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = ClassLoader.getSystemClassLoader();
+ } catch (SecurityException ex) {}
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getParentClassLoader(final ClassLoader cl) {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader parent = null;
+ try {
+ parent = cl.getParent();
+ } catch (SecurityException ex) {}
+
+ // eliminate loops in case of the boot
+ // ClassLoader returning itself as a parent
+ return (parent == cl) ? null : parent;
+ }
+ });
+ }
+
+ String getSystemProperty(final String propName) {
+ return (String)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty(propName);
+ }
+ });
+ }
+
+ FileInputStream getFileInputStream(final File file)
+ throws FileNotFoundException
+ {
+ try {
+ return (FileInputStream)
+ AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws FileNotFoundException {
+ return new FileInputStream(file);
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ throw (FileNotFoundException)e.getException();
+ }
+ }
+
+ InputStream getResourceAsStream(final ClassLoader cl,
+ final String name)
+ {
+ return (InputStream)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+ });
+ }
+
+ boolean getFileExists(final File f) {
+ return ((Boolean)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Boolean(f.exists());
+ }
+ })).booleanValue();
+ }
+
+ long getLastModified(final File f) {
+ return ((Long)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Long(f.lastModified());
+ }
+ })).longValue();
+ }
+
+}
diff --git a/src/org/apache/xalan/lib/Extensions.java b/src/org/apache/xalan/lib/Extensions.java
index 8d2e883..2b46346 100644
--- a/src/org/apache/xalan/lib/Extensions.java
+++ b/src/org/apache/xalan/lib/Extensions.java
@@ -69,7 +69,7 @@
import org.apache.xpath.objects.XBoolean;
import org.apache.xpath.objects.XNumber;
import org.apache.xpath.objects.XObject;
-import org.apache.xml.utils.ObjectFactory;
+
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
diff --git a/src/org/apache/xalan/lib/ObjectFactory.java b/src/org/apache/xalan/lib/ObjectFactory.java
new file mode 100755
index 0000000..065faf2
--- /dev/null
+++ b/src/org/apache/xalan/lib/ObjectFactory.java
@@ -0,0 +1,666 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.lib;
+
+
+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;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+ //
+ // Constants
+ //
+
+ // name of default properties file to look for in JDK's jre/lib directory
+ private static final String DEFAULT_PROPERTIES_FILENAME =
+ "xalan.properties";
+
+ private static final String SERVICES_PATH = "META-INF/services";
+
+ /** Set to true for debugging */
+ private static final boolean DEBUG = false;
+
+ /** cache the contents of the xalan.properties file.
+ * Until an attempt has been made to read this file, this will
+ * be null; if the file does not exist or we encounter some other error
+ * during the read, this will be empty.
+ */
+ private static Properties fXalanProperties = null;
+
+ /***
+ * Cache the time stamp of the xalan.properties file so
+ * that we know if it's been modified and can invalidate
+ * the cache when necessary.
+ */
+ private static long fLastModified = -1;
+
+ //
+ // Public static methods
+ //
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance 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.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId, String fallbackClassName)
+ throws ConfigurationError {
+ return createObject(factoryId, null, fallbackClassName);
+ } // createObject(String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ Class factoryClass = lookUpFactoryClass(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+
+ if (factoryClass == null) {
+ throw new ConfigurationError(
+ "Provider for " + factoryId + " cannot be found", null);
+ }
+
+ try{
+ Object instance = factoryClass.newInstance();
+ debugPrintln("created new instance of factory " + factoryId);
+ return instance;
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider for factory " + factoryId
+ + " could not be instantiated: " + x, x);
+ }
+ } // createObject(String,String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId)
+ throws ConfigurationError
+ {
+ return lookUpFactoryClass(factoryId, null, null);
+ } // lookUpFactoryClass(String):Class
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ String factoryClassName = lookUpFactoryClassName(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+ ClassLoader cl = findClassLoader();
+
+ if (factoryClassName == null) {
+ factoryClassName = fallbackClassName;
+ }
+
+ // assert(className != null);
+ try{
+ Class providerClass = findProviderClass(factoryClassName,
+ cl,
+ true);
+ debugPrintln("created new instance of " + providerClass +
+ " using ClassLoader: " + cl);
+ return providerClass;
+ } catch (ClassNotFoundException x) {
+ throw new ConfigurationError(
+ "Provider " + factoryClassName + " not found", x);
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider "+factoryClassName+" could not be instantiated: "+x,
+ x);
+ }
+ } // lookUpFactoryClass(String,String,String):Class
+
+ /**
+ * Finds the name of the required implementation class in the specified
+ * order. The specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return name of class that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static String lookUpFactoryClassName(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Use the system property first
+ try {
+ String systemProp = ss.getSystemProperty(factoryId);
+ if (systemProp != null) {
+ debugPrintln("found system property, value=" + systemProp);
+ return systemProp;
+ }
+ } catch (SecurityException se) {
+ // Ignore and continue w/ next location
+ }
+
+ // Try to read from propertiesFilename, or
+ // $java.home/lib/xalan.properties
+ String factoryClassName = null;
+ // no properties file name specified; use
+ // $JAVA_HOME/lib/xalan.properties:
+ if (propertiesFilename == null) {
+ File propertiesFile = null;
+ boolean propertiesFileExists = false;
+ try {
+ String javah = ss.getSystemProperty("java.home");
+ propertiesFilename = javah + File.separator +
+ "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+ propertiesFile = new File(propertiesFilename);
+ propertiesFileExists = ss.getFileExists(propertiesFile);
+ } catch (SecurityException e) {
+ // try again...
+ fLastModified = -1;
+ fXalanProperties = null;
+ }
+
+ synchronized (ObjectFactory.class) {
+ boolean loadProperties = false;
+ try {
+ // file existed last time
+ if(fLastModified >= 0) {
+ if(propertiesFileExists &&
+ (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+ loadProperties = true;
+ } else {
+ // file has stopped existing...
+ if(!propertiesFileExists) {
+ fLastModified = -1;
+ fXalanProperties = null;
+ } // else, file wasn't modified!
+ }
+ } else {
+ // file has started to exist:
+ if(propertiesFileExists) {
+ loadProperties = true;
+ fLastModified = ss.getLastModified(propertiesFile);
+ } // else, nothing's changed
+ }
+ if(loadProperties) {
+ // must never have attempted to read xalan.properties
+ // before (or it's outdeated)
+ fXalanProperties = new Properties();
+ FileInputStream fis =
+ ss.getFileInputStream(propertiesFile);
+ fXalanProperties.load(fis);
+ fis.close();
+ }
+ } catch (Exception x) {
+ fXalanProperties = null;
+ fLastModified = -1;
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if(fXalanProperties != null) {
+ factoryClassName = fXalanProperties.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) {
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if (factoryClassName != null) {
+ debugPrintln("found in " + propertiesFilename + ", value="
+ + factoryClassName);
+ return factoryClassName;
+ }
+
+ // Try Jar Service Provider Mechanism
+ return findJarServiceProviderName(factoryId);
+ } // lookUpFactoryClass(String,String):String
+
+ //
+ // Private static methods
+ //
+
+ /** Prints a message to standard error if debugging is enabled. */
+ private static void debugPrintln(String msg) {
+ if (DEBUG) {
+ System.err.println("JAXP: " + msg);
+ }
+ } // debugPrintln(String)
+
+ /**
+ * Figure out which ClassLoader to use. For JDK 1.2 and later use
+ * the context ClassLoader.
+ */
+ static ClassLoader findClassLoader()
+ throws ConfigurationError
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Figure out which ClassLoader to use for loading the provider
+ // class. If there is a Context ClassLoader then use it.
+ ClassLoader context = ss.getContextClassLoader();
+ ClassLoader system = ss.getSystemClassLoader();
+
+ ClassLoader chain = system;
+ while (true) {
+ if (context == chain) {
+ // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+ // or any Context ClassLoader in chain of system classloader
+ // (including extension ClassLoader) so extend to widest
+ // ClassLoader (always look in system ClassLoader if Xalan
+ // is in boot/extension/system classpath and in current
+ // ClassLoader otherwise); normal classloaders delegate
+ // back to system ClassLoader first so this widening doesn't
+ // change the fact that context ClassLoader will be consulted
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+
+ chain = system;
+ while (true) {
+ if (current == chain) {
+ // Assert: Current ClassLoader in chain of
+ // boot/extension/system ClassLoaders
+ return system;
+ }
+ if (chain == null) {
+ break;
+ }
+ chain = ss.getParentClassLoader(chain);
+ }
+
+ // Assert: Current ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return current;
+ }
+
+ if (chain == null) {
+ // boot ClassLoader reached
+ break;
+ }
+
+ // Check for any extension ClassLoaders in chain up to
+ // boot ClassLoader
+ chain = ss.getParentClassLoader(chain);
+ };
+
+ // Assert: Context ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return context;
+ } // findClassLoader():ClassLoader
+
+ /**
+ * Create an instance of a class using the specified ClassLoader
+ */
+ static Object newInstance(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ConfigurationError
+ {
+ // assert(className != null);
+ 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);
+ }
+ }
+
+ /**
+ * Find a Class using the specified ClassLoader
+ */
+ static Class findProviderClass(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ClassNotFoundException, ConfigurationError
+ {
+
+ SecurityManager security = System.getSecurityManager();
+ try{
+ if (security != null)
+ security.checkPackageAccess(className);
+ }catch(SecurityException e){
+ throw e;
+ }
+
+ Class providerClass;
+ if (cl == null) {
+ // XXX Use the bootstrap ClassLoader. There is no way to
+ // load a class using the bootstrap ClassLoader that works
+ // in both JDK 1.1 and Java 2. However, this should still
+ // work b/c the following should be true:
+ //
+ // (cl == null) iff current ClassLoader == null
+ //
+ // Thus Class.forName(String) will use the current
+ // ClassLoader which will be the bootstrap ClassLoader.
+ providerClass = Class.forName(className);
+ } else {
+ try {
+ providerClass = cl.loadClass(className);
+ } catch (ClassNotFoundException x) {
+ if (doFallback) {
+ // Fall back to current classloader
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (current == null) {
+ providerClass = Class.forName(className);
+ } else if (cl != current) {
+ cl = current;
+ providerClass = cl.loadClass(className);
+ } else {
+ throw x;
+ }
+ } else {
+ throw x;
+ }
+ }
+ }
+
+ return providerClass;
+ }
+
+ /**
+ * Find the name of service provider using Jar Service Provider Mechanism
+ *
+ * @return instance of provider class if found or null
+ */
+ private static String findJarServiceProviderName(String factoryId)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+ String serviceId = SERVICES_PATH + factoryId;
+ InputStream is = null;
+
+ // First try the Context ClassLoader
+ ClassLoader cl = findClassLoader();
+
+ is = ss.getResourceAsStream(cl, serviceId);
+
+ // If no provider found then try the current ClassLoader
+ if (is == null) {
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (cl != current) {
+ cl = current;
+ is = ss.getResourceAsStream(cl, serviceId);
+ }
+ }
+
+ if (is == null) {
+ // No provider found
+ return null;
+ }
+
+ debugPrintln("found jar resource=" + serviceId +
+ " using ClassLoader: " + cl);
+
+ // Read the service provider name in UTF-8 as specified in
+ // the jar spec. Unfortunately this fails in Microsoft
+ // VJ++, which does not implement the UTF-8
+ // encoding. Theoretically, we should simply let it fail in
+ // that case, since the JVM is obviously broken if it
+ // doesn't support such a basic standard. But since there
+ // are still some users attempting to use VJ++ for
+ // development, we have dropped in a fallback which makes a
+ // second attempt using the platform's default encoding. In
+ // VJ++ this is apparently ASCII, which is a subset of
+ // UTF-8... and since the strings we'll be reading here are
+ // also primarily limited to the 7-bit ASCII range (at
+ // least, in English versions), this should work well
+ // enough to keep us on the air until we're ready to
+ // officially decommit from VJ++. [Edited comment from
+ // jkesselm]
+ BufferedReader rd;
+ try {
+ rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ } catch (java.io.UnsupportedEncodingException e) {
+ rd = new BufferedReader(new InputStreamReader(is));
+ }
+
+ String factoryClassName = null;
+ try {
+ // XXX Does not handle all possible input as specified by the
+ // Jar Service Provider specification
+ factoryClassName = rd.readLine();
+ rd.close();
+ } catch (IOException x) {
+ // No provider found
+ return null;
+ }
+
+ if (factoryClassName != null &&
+ ! "".equals(factoryClassName)) {
+ debugPrintln("found in resource, value="
+ + factoryClassName);
+
+ // Note: here we do not want to fall back to the current
+ // ClassLoader because we want to avoid the case where the
+ // resource file was found using one ClassLoader and the
+ // provider class was instantiated using a different one.
+ return factoryClassName;
+ }
+
+ // No provider found
+ return null;
+ }
+
+ //
+ // Classes
+ //
+
+ /**
+ * A configuration error.
+ */
+ static class ConfigurationError
+ extends Error {
+
+ //
+ // Data
+ //
+
+ /** Exception. */
+ private Exception exception;
+
+ //
+ // Constructors
+ //
+
+ /**
+ * Construct a new instance with the specified detail string and
+ * exception.
+ */
+ public ConfigurationError(String msg, Exception x) {
+ super(msg);
+ this.exception = x;
+ } // <init>(String,Exception)
+
+ //
+ // Public methods
+ //
+
+ /** Returns the exception associated to this error. */
+ public Exception getException() {
+ return exception;
+ } // getException():Exception
+
+ } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xalan/lib/SecuritySupport.java b/src/org/apache/xalan/lib/SecuritySupport.java
new file mode 100755
index 0000000..db79980
--- /dev/null
+++ b/src/org/apache/xalan/lib/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.lib;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+ /*
+ * Make this of type Object so that the verifier won't try to
+ * prove its type, thus possibly trying to load the SecuritySupport12
+ * class.
+ */
+ private static final Object securitySupport;
+
+ static {
+ SecuritySupport ss = null;
+ try {
+ Class c = Class.forName("java.security.AccessController");
+ // if that worked, we're on 1.2.
+ /*
+ // don't reference the class explicitly so it doesn't
+ // get dragged in accidentally.
+ c = Class.forName("javax.mail.SecuritySupport12");
+ Constructor cons = c.getConstructor(new Class[] { });
+ ss = (SecuritySupport)cons.newInstance(new Object[] { });
+ */
+ /*
+ * Unfortunately, we can't load the class using reflection
+ * because the class is package private. And the class has
+ * to be package private so the APIs aren't exposed to other
+ * code that could use them to circumvent security. Thus,
+ * we accept the risk that the direct reference might fail
+ * on some JDK 1.1 JVMs, even though we would never execute
+ * this code in such a case. Sigh...
+ */
+ ss = new SecuritySupport12();
+ } catch (Exception ex) {
+ // ignore it
+ } finally {
+ if (ss == null)
+ ss = new SecuritySupport();
+ securitySupport = ss;
+ }
+ }
+
+ /**
+ * Return an appropriate instance of this class, depending on whether
+ * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+ */
+ static SecuritySupport getInstance() {
+ return (SecuritySupport)securitySupport;
+ }
+
+ ClassLoader getContextClassLoader() {
+ return null;
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return null;
+ }
+
+ ClassLoader getParentClassLoader(ClassLoader cl) {
+ return null;
+ }
+
+ String getSystemProperty(String propName) {
+ return System.getProperty(propName);
+ }
+
+ FileInputStream getFileInputStream(File file)
+ throws FileNotFoundException
+ {
+ return new FileInputStream(file);
+ }
+
+ InputStream getResourceAsStream(ClassLoader cl, String name) {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+
+ boolean getFileExists(File f) {
+ return f.exists();
+ }
+
+ long getLastModified(File f) {
+ return f.lastModified();
+ }
+}
diff --git a/src/org/apache/xalan/lib/SecuritySupport12.java b/src/org/apache/xalan/lib/SecuritySupport12.java
new file mode 100755
index 0000000..a840d7f
--- /dev/null
+++ b/src/org/apache/xalan/lib/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.lib;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+ ClassLoader getContextClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = Thread.currentThread().getContextClassLoader();
+ } catch (SecurityException ex) { }
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = ClassLoader.getSystemClassLoader();
+ } catch (SecurityException ex) {}
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getParentClassLoader(final ClassLoader cl) {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader parent = null;
+ try {
+ parent = cl.getParent();
+ } catch (SecurityException ex) {}
+
+ // eliminate loops in case of the boot
+ // ClassLoader returning itself as a parent
+ return (parent == cl) ? null : parent;
+ }
+ });
+ }
+
+ String getSystemProperty(final String propName) {
+ return (String)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty(propName);
+ }
+ });
+ }
+
+ FileInputStream getFileInputStream(final File file)
+ throws FileNotFoundException
+ {
+ try {
+ return (FileInputStream)
+ AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws FileNotFoundException {
+ return new FileInputStream(file);
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ throw (FileNotFoundException)e.getException();
+ }
+ }
+
+ InputStream getResourceAsStream(final ClassLoader cl,
+ final String name)
+ {
+ return (InputStream)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+ });
+ }
+
+ boolean getFileExists(final File f) {
+ return ((Boolean)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Boolean(f.exists());
+ }
+ })).booleanValue();
+ }
+
+ long getLastModified(final File f) {
+ return ((Long)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Long(f.lastModified());
+ }
+ })).longValue();
+ }
+
+}
diff --git a/src/org/apache/xalan/lib/sql/DefaultConnectionPool.java b/src/org/apache/xalan/lib/sql/DefaultConnectionPool.java
index 030ddcb..4c86e5d 100644
--- a/src/org/apache/xalan/lib/sql/DefaultConnectionPool.java
+++ b/src/org/apache/xalan/lib/sql/DefaultConnectionPool.java
@@ -67,7 +67,7 @@
import org.apache.xalan.res.XSLMessages;
import org.apache.xalan.res.XSLTErrorResources;
-import org.apache.xml.utils.ObjectFactory;
+
/**
* For internal connectiones, i.e. Connection information supplies in the
diff --git a/src/org/apache/xalan/lib/sql/ObjectFactory.java b/src/org/apache/xalan/lib/sql/ObjectFactory.java
new file mode 100755
index 0000000..dbed753
--- /dev/null
+++ b/src/org/apache/xalan/lib/sql/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.lib.sql;
+
+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;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+ //
+ // Constants
+ //
+
+ // name of default properties file to look for in JDK's jre/lib directory
+ private static final String DEFAULT_PROPERTIES_FILENAME =
+ "xalan.properties";
+
+ private static final String SERVICES_PATH = "META-INF/services";
+
+ /** Set to true for debugging */
+ private static final boolean DEBUG = false;
+
+ /** cache the contents of the xalan.properties file.
+ * Until an attempt has been made to read this file, this will
+ * be null; if the file does not exist or we encounter some other error
+ * during the read, this will be empty.
+ */
+ private static Properties fXalanProperties = null;
+
+ /***
+ * Cache the time stamp of the xalan.properties file so
+ * that we know if it's been modified and can invalidate
+ * the cache when necessary.
+ */
+ private static long fLastModified = -1;
+
+ //
+ // Public static methods
+ //
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance 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.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId, String fallbackClassName)
+ throws ConfigurationError {
+ return createObject(factoryId, null, fallbackClassName);
+ } // createObject(String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ Class factoryClass = lookUpFactoryClass(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+
+ if (factoryClass == null) {
+ throw new ConfigurationError(
+ "Provider for " + factoryId + " cannot be found", null);
+ }
+
+ try{
+ Object instance = factoryClass.newInstance();
+ debugPrintln("created new instance of factory " + factoryId);
+ return instance;
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider for factory " + factoryId
+ + " could not be instantiated: " + x, x);
+ }
+ } // createObject(String,String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId)
+ throws ConfigurationError
+ {
+ return lookUpFactoryClass(factoryId, null, null);
+ } // lookUpFactoryClass(String):Class
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ String factoryClassName = lookUpFactoryClassName(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+ ClassLoader cl = findClassLoader();
+
+ if (factoryClassName == null) {
+ factoryClassName = fallbackClassName;
+ }
+
+ // assert(className != null);
+ try{
+ Class providerClass = findProviderClass(factoryClassName,
+ cl,
+ true);
+ debugPrintln("created new instance of " + providerClass +
+ " using ClassLoader: " + cl);
+ return providerClass;
+ } catch (ClassNotFoundException x) {
+ throw new ConfigurationError(
+ "Provider " + factoryClassName + " not found", x);
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider "+factoryClassName+" could not be instantiated: "+x,
+ x);
+ }
+ } // lookUpFactoryClass(String,String,String):Class
+
+ /**
+ * Finds the name of the required implementation class in the specified
+ * order. The specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return name of class that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static String lookUpFactoryClassName(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Use the system property first
+ try {
+ String systemProp = ss.getSystemProperty(factoryId);
+ if (systemProp != null) {
+ debugPrintln("found system property, value=" + systemProp);
+ return systemProp;
+ }
+ } catch (SecurityException se) {
+ // Ignore and continue w/ next location
+ }
+
+ // Try to read from propertiesFilename, or
+ // $java.home/lib/xalan.properties
+ String factoryClassName = null;
+ // no properties file name specified; use
+ // $JAVA_HOME/lib/xalan.properties:
+ if (propertiesFilename == null) {
+ File propertiesFile = null;
+ boolean propertiesFileExists = false;
+ try {
+ String javah = ss.getSystemProperty("java.home");
+ propertiesFilename = javah + File.separator +
+ "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+ propertiesFile = new File(propertiesFilename);
+ propertiesFileExists = ss.getFileExists(propertiesFile);
+ } catch (SecurityException e) {
+ // try again...
+ fLastModified = -1;
+ fXalanProperties = null;
+ }
+
+ synchronized (ObjectFactory.class) {
+ boolean loadProperties = false;
+ try {
+ // file existed last time
+ if(fLastModified >= 0) {
+ if(propertiesFileExists &&
+ (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+ loadProperties = true;
+ } else {
+ // file has stopped existing...
+ if(!propertiesFileExists) {
+ fLastModified = -1;
+ fXalanProperties = null;
+ } // else, file wasn't modified!
+ }
+ } else {
+ // file has started to exist:
+ if(propertiesFileExists) {
+ loadProperties = true;
+ fLastModified = ss.getLastModified(propertiesFile);
+ } // else, nothing's changed
+ }
+ if(loadProperties) {
+ // must never have attempted to read xalan.properties
+ // before (or it's outdeated)
+ fXalanProperties = new Properties();
+ FileInputStream fis =
+ ss.getFileInputStream(propertiesFile);
+ fXalanProperties.load(fis);
+ fis.close();
+ }
+ } catch (Exception x) {
+ fXalanProperties = null;
+ fLastModified = -1;
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if(fXalanProperties != null) {
+ factoryClassName = fXalanProperties.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) {
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if (factoryClassName != null) {
+ debugPrintln("found in " + propertiesFilename + ", value="
+ + factoryClassName);
+ return factoryClassName;
+ }
+
+ // Try Jar Service Provider Mechanism
+ return findJarServiceProviderName(factoryId);
+ } // lookUpFactoryClass(String,String):String
+
+ //
+ // Private static methods
+ //
+
+ /** Prints a message to standard error if debugging is enabled. */
+ private static void debugPrintln(String msg) {
+ if (DEBUG) {
+ System.err.println("JAXP: " + msg);
+ }
+ } // debugPrintln(String)
+
+ /**
+ * Figure out which ClassLoader to use. For JDK 1.2 and later use
+ * the context ClassLoader.
+ */
+ static ClassLoader findClassLoader()
+ throws ConfigurationError
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Figure out which ClassLoader to use for loading the provider
+ // class. If there is a Context ClassLoader then use it.
+ ClassLoader context = ss.getContextClassLoader();
+ ClassLoader system = ss.getSystemClassLoader();
+
+ ClassLoader chain = system;
+ while (true) {
+ if (context == chain) {
+ // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+ // or any Context ClassLoader in chain of system classloader
+ // (including extension ClassLoader) so extend to widest
+ // ClassLoader (always look in system ClassLoader if Xalan
+ // is in boot/extension/system classpath and in current
+ // ClassLoader otherwise); normal classloaders delegate
+ // back to system ClassLoader first so this widening doesn't
+ // change the fact that context ClassLoader will be consulted
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+
+ chain = system;
+ while (true) {
+ if (current == chain) {
+ // Assert: Current ClassLoader in chain of
+ // boot/extension/system ClassLoaders
+ return system;
+ }
+ if (chain == null) {
+ break;
+ }
+ chain = ss.getParentClassLoader(chain);
+ }
+
+ // Assert: Current ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return current;
+ }
+
+ if (chain == null) {
+ // boot ClassLoader reached
+ break;
+ }
+
+ // Check for any extension ClassLoaders in chain up to
+ // boot ClassLoader
+ chain = ss.getParentClassLoader(chain);
+ };
+
+ // Assert: Context ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return context;
+ } // findClassLoader():ClassLoader
+
+ /**
+ * Create an instance of a class using the specified ClassLoader
+ */
+ static Object newInstance(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ConfigurationError
+ {
+ // assert(className != null);
+ 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);
+ }
+ }
+
+ /**
+ * Find a Class using the specified ClassLoader
+ */
+ static Class findProviderClass(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ClassNotFoundException, ConfigurationError
+ {
+
+ SecurityManager security = System.getSecurityManager();
+ try{
+ if (security != null)
+ security.checkPackageAccess(className);
+ }catch(SecurityException e){
+ throw e;
+ }
+
+ Class providerClass;
+ if (cl == null) {
+ // XXX Use the bootstrap ClassLoader. There is no way to
+ // load a class using the bootstrap ClassLoader that works
+ // in both JDK 1.1 and Java 2. However, this should still
+ // work b/c the following should be true:
+ //
+ // (cl == null) iff current ClassLoader == null
+ //
+ // Thus Class.forName(String) will use the current
+ // ClassLoader which will be the bootstrap ClassLoader.
+ providerClass = Class.forName(className);
+ } else {
+ try {
+ providerClass = cl.loadClass(className);
+ } catch (ClassNotFoundException x) {
+ if (doFallback) {
+ // Fall back to current classloader
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (current == null) {
+ providerClass = Class.forName(className);
+ } else if (cl != current) {
+ cl = current;
+ providerClass = cl.loadClass(className);
+ } else {
+ throw x;
+ }
+ } else {
+ throw x;
+ }
+ }
+ }
+
+ return providerClass;
+ }
+
+ /**
+ * Find the name of service provider using Jar Service Provider Mechanism
+ *
+ * @return instance of provider class if found or null
+ */
+ private static String findJarServiceProviderName(String factoryId)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+ String serviceId = SERVICES_PATH + factoryId;
+ InputStream is = null;
+
+ // First try the Context ClassLoader
+ ClassLoader cl = findClassLoader();
+
+ is = ss.getResourceAsStream(cl, serviceId);
+
+ // If no provider found then try the current ClassLoader
+ if (is == null) {
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (cl != current) {
+ cl = current;
+ is = ss.getResourceAsStream(cl, serviceId);
+ }
+ }
+
+ if (is == null) {
+ // No provider found
+ return null;
+ }
+
+ debugPrintln("found jar resource=" + serviceId +
+ " using ClassLoader: " + cl);
+
+ // Read the service provider name in UTF-8 as specified in
+ // the jar spec. Unfortunately this fails in Microsoft
+ // VJ++, which does not implement the UTF-8
+ // encoding. Theoretically, we should simply let it fail in
+ // that case, since the JVM is obviously broken if it
+ // doesn't support such a basic standard. But since there
+ // are still some users attempting to use VJ++ for
+ // development, we have dropped in a fallback which makes a
+ // second attempt using the platform's default encoding. In
+ // VJ++ this is apparently ASCII, which is a subset of
+ // UTF-8... and since the strings we'll be reading here are
+ // also primarily limited to the 7-bit ASCII range (at
+ // least, in English versions), this should work well
+ // enough to keep us on the air until we're ready to
+ // officially decommit from VJ++. [Edited comment from
+ // jkesselm]
+ BufferedReader rd;
+ try {
+ rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ } catch (java.io.UnsupportedEncodingException e) {
+ rd = new BufferedReader(new InputStreamReader(is));
+ }
+
+ String factoryClassName = null;
+ try {
+ // XXX Does not handle all possible input as specified by the
+ // Jar Service Provider specification
+ factoryClassName = rd.readLine();
+ rd.close();
+ } catch (IOException x) {
+ // No provider found
+ return null;
+ }
+
+ if (factoryClassName != null &&
+ ! "".equals(factoryClassName)) {
+ debugPrintln("found in resource, value="
+ + factoryClassName);
+
+ // Note: here we do not want to fall back to the current
+ // ClassLoader because we want to avoid the case where the
+ // resource file was found using one ClassLoader and the
+ // provider class was instantiated using a different one.
+ return factoryClassName;
+ }
+
+ // No provider found
+ return null;
+ }
+
+ //
+ // Classes
+ //
+
+ /**
+ * A configuration error.
+ */
+ static class ConfigurationError
+ extends Error {
+
+ //
+ // Data
+ //
+
+ /** Exception. */
+ private Exception exception;
+
+ //
+ // Constructors
+ //
+
+ /**
+ * Construct a new instance with the specified detail string and
+ * exception.
+ */
+ public ConfigurationError(String msg, Exception x) {
+ super(msg);
+ this.exception = x;
+ } // <init>(String,Exception)
+
+ //
+ // Public methods
+ //
+
+ /** Returns the exception associated to this error. */
+ public Exception getException() {
+ return exception;
+ } // getException():Exception
+
+ } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xalan/lib/sql/SecuritySupport.java b/src/org/apache/xalan/lib/sql/SecuritySupport.java
new file mode 100755
index 0000000..4d547d5
--- /dev/null
+++ b/src/org/apache/xalan/lib/sql/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.lib.sql;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+ /*
+ * Make this of type Object so that the verifier won't try to
+ * prove its type, thus possibly trying to load the SecuritySupport12
+ * class.
+ */
+ private static final Object securitySupport;
+
+ static {
+ SecuritySupport ss = null;
+ try {
+ Class c = Class.forName("java.security.AccessController");
+ // if that worked, we're on 1.2.
+ /*
+ // don't reference the class explicitly so it doesn't
+ // get dragged in accidentally.
+ c = Class.forName("javax.mail.SecuritySupport12");
+ Constructor cons = c.getConstructor(new Class[] { });
+ ss = (SecuritySupport)cons.newInstance(new Object[] { });
+ */
+ /*
+ * Unfortunately, we can't load the class using reflection
+ * because the class is package private. And the class has
+ * to be package private so the APIs aren't exposed to other
+ * code that could use them to circumvent security. Thus,
+ * we accept the risk that the direct reference might fail
+ * on some JDK 1.1 JVMs, even though we would never execute
+ * this code in such a case. Sigh...
+ */
+ ss = new SecuritySupport12();
+ } catch (Exception ex) {
+ // ignore it
+ } finally {
+ if (ss == null)
+ ss = new SecuritySupport();
+ securitySupport = ss;
+ }
+ }
+
+ /**
+ * Return an appropriate instance of this class, depending on whether
+ * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+ */
+ static SecuritySupport getInstance() {
+ return (SecuritySupport)securitySupport;
+ }
+
+ ClassLoader getContextClassLoader() {
+ return null;
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return null;
+ }
+
+ ClassLoader getParentClassLoader(ClassLoader cl) {
+ return null;
+ }
+
+ String getSystemProperty(String propName) {
+ return System.getProperty(propName);
+ }
+
+ FileInputStream getFileInputStream(File file)
+ throws FileNotFoundException
+ {
+ return new FileInputStream(file);
+ }
+
+ InputStream getResourceAsStream(ClassLoader cl, String name) {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+
+ boolean getFileExists(File f) {
+ return f.exists();
+ }
+
+ long getLastModified(File f) {
+ return f.lastModified();
+ }
+}
diff --git a/src/org/apache/xalan/lib/sql/SecuritySupport12.java b/src/org/apache/xalan/lib/sql/SecuritySupport12.java
new file mode 100755
index 0000000..90c83b5
--- /dev/null
+++ b/src/org/apache/xalan/lib/sql/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.lib.sql;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+ ClassLoader getContextClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = Thread.currentThread().getContextClassLoader();
+ } catch (SecurityException ex) { }
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = ClassLoader.getSystemClassLoader();
+ } catch (SecurityException ex) {}
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getParentClassLoader(final ClassLoader cl) {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader parent = null;
+ try {
+ parent = cl.getParent();
+ } catch (SecurityException ex) {}
+
+ // eliminate loops in case of the boot
+ // ClassLoader returning itself as a parent
+ return (parent == cl) ? null : parent;
+ }
+ });
+ }
+
+ String getSystemProperty(final String propName) {
+ return (String)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty(propName);
+ }
+ });
+ }
+
+ FileInputStream getFileInputStream(final File file)
+ throws FileNotFoundException
+ {
+ try {
+ return (FileInputStream)
+ AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws FileNotFoundException {
+ return new FileInputStream(file);
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ throw (FileNotFoundException)e.getException();
+ }
+ }
+
+ InputStream getResourceAsStream(final ClassLoader cl,
+ final String name)
+ {
+ return (InputStream)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+ });
+ }
+
+ boolean getFileExists(final File f) {
+ return ((Boolean)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Boolean(f.exists());
+ }
+ })).booleanValue();
+ }
+
+ long getLastModified(final File f) {
+ return ((Long)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Long(f.lastModified());
+ }
+ })).longValue();
+ }
+
+}
diff --git a/src/org/apache/xalan/xslt/EnvironmentCheck.java b/src/org/apache/xalan/xslt/EnvironmentCheck.java
index bd0d9c9..abf09db 100644
--- a/src/org/apache/xalan/xslt/EnvironmentCheck.java
+++ b/src/org/apache/xalan/xslt/EnvironmentCheck.java
@@ -66,7 +66,7 @@
import java.util.StringTokenizer;
import java.util.Vector;
-import org.apache.xml.utils.ObjectFactory;
+
import org.w3c.dom.Document;
import org.w3c.dom.Element;
diff --git a/src/org/apache/xalan/xslt/ObjectFactory.java b/src/org/apache/xalan/xslt/ObjectFactory.java
new file mode 100755
index 0000000..b96f7de
--- /dev/null
+++ b/src/org/apache/xalan/xslt/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xslt;
+
+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;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+ //
+ // Constants
+ //
+
+ // name of default properties file to look for in JDK's jre/lib directory
+ private static final String DEFAULT_PROPERTIES_FILENAME =
+ "xalan.properties";
+
+ private static final String SERVICES_PATH = "META-INF/services";
+
+ /** Set to true for debugging */
+ private static final boolean DEBUG = false;
+
+ /** cache the contents of the xalan.properties file.
+ * Until an attempt has been made to read this file, this will
+ * be null; if the file does not exist or we encounter some other error
+ * during the read, this will be empty.
+ */
+ private static Properties fXalanProperties = null;
+
+ /***
+ * Cache the time stamp of the xalan.properties file so
+ * that we know if it's been modified and can invalidate
+ * the cache when necessary.
+ */
+ private static long fLastModified = -1;
+
+ //
+ // Public static methods
+ //
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance 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.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId, String fallbackClassName)
+ throws ConfigurationError {
+ return createObject(factoryId, null, fallbackClassName);
+ } // createObject(String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ Class factoryClass = lookUpFactoryClass(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+
+ if (factoryClass == null) {
+ throw new ConfigurationError(
+ "Provider for " + factoryId + " cannot be found", null);
+ }
+
+ try{
+ Object instance = factoryClass.newInstance();
+ debugPrintln("created new instance of factory " + factoryId);
+ return instance;
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider for factory " + factoryId
+ + " could not be instantiated: " + x, x);
+ }
+ } // createObject(String,String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId)
+ throws ConfigurationError
+ {
+ return lookUpFactoryClass(factoryId, null, null);
+ } // lookUpFactoryClass(String):Class
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ String factoryClassName = lookUpFactoryClassName(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+ ClassLoader cl = findClassLoader();
+
+ if (factoryClassName == null) {
+ factoryClassName = fallbackClassName;
+ }
+
+ // assert(className != null);
+ try{
+ Class providerClass = findProviderClass(factoryClassName,
+ cl,
+ true);
+ debugPrintln("created new instance of " + providerClass +
+ " using ClassLoader: " + cl);
+ return providerClass;
+ } catch (ClassNotFoundException x) {
+ throw new ConfigurationError(
+ "Provider " + factoryClassName + " not found", x);
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider "+factoryClassName+" could not be instantiated: "+x,
+ x);
+ }
+ } // lookUpFactoryClass(String,String,String):Class
+
+ /**
+ * Finds the name of the required implementation class in the specified
+ * order. The specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return name of class that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static String lookUpFactoryClassName(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Use the system property first
+ try {
+ String systemProp = ss.getSystemProperty(factoryId);
+ if (systemProp != null) {
+ debugPrintln("found system property, value=" + systemProp);
+ return systemProp;
+ }
+ } catch (SecurityException se) {
+ // Ignore and continue w/ next location
+ }
+
+ // Try to read from propertiesFilename, or
+ // $java.home/lib/xalan.properties
+ String factoryClassName = null;
+ // no properties file name specified; use
+ // $JAVA_HOME/lib/xalan.properties:
+ if (propertiesFilename == null) {
+ File propertiesFile = null;
+ boolean propertiesFileExists = false;
+ try {
+ String javah = ss.getSystemProperty("java.home");
+ propertiesFilename = javah + File.separator +
+ "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+ propertiesFile = new File(propertiesFilename);
+ propertiesFileExists = ss.getFileExists(propertiesFile);
+ } catch (SecurityException e) {
+ // try again...
+ fLastModified = -1;
+ fXalanProperties = null;
+ }
+
+ synchronized (ObjectFactory.class) {
+ boolean loadProperties = false;
+ try {
+ // file existed last time
+ if(fLastModified >= 0) {
+ if(propertiesFileExists &&
+ (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+ loadProperties = true;
+ } else {
+ // file has stopped existing...
+ if(!propertiesFileExists) {
+ fLastModified = -1;
+ fXalanProperties = null;
+ } // else, file wasn't modified!
+ }
+ } else {
+ // file has started to exist:
+ if(propertiesFileExists) {
+ loadProperties = true;
+ fLastModified = ss.getLastModified(propertiesFile);
+ } // else, nothing's changed
+ }
+ if(loadProperties) {
+ // must never have attempted to read xalan.properties
+ // before (or it's outdeated)
+ fXalanProperties = new Properties();
+ FileInputStream fis =
+ ss.getFileInputStream(propertiesFile);
+ fXalanProperties.load(fis);
+ fis.close();
+ }
+ } catch (Exception x) {
+ fXalanProperties = null;
+ fLastModified = -1;
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if(fXalanProperties != null) {
+ factoryClassName = fXalanProperties.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) {
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if (factoryClassName != null) {
+ debugPrintln("found in " + propertiesFilename + ", value="
+ + factoryClassName);
+ return factoryClassName;
+ }
+
+ // Try Jar Service Provider Mechanism
+ return findJarServiceProviderName(factoryId);
+ } // lookUpFactoryClass(String,String):String
+
+ //
+ // Private static methods
+ //
+
+ /** Prints a message to standard error if debugging is enabled. */
+ private static void debugPrintln(String msg) {
+ if (DEBUG) {
+ System.err.println("JAXP: " + msg);
+ }
+ } // debugPrintln(String)
+
+ /**
+ * Figure out which ClassLoader to use. For JDK 1.2 and later use
+ * the context ClassLoader.
+ */
+ static ClassLoader findClassLoader()
+ throws ConfigurationError
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Figure out which ClassLoader to use for loading the provider
+ // class. If there is a Context ClassLoader then use it.
+ ClassLoader context = ss.getContextClassLoader();
+ ClassLoader system = ss.getSystemClassLoader();
+
+ ClassLoader chain = system;
+ while (true) {
+ if (context == chain) {
+ // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+ // or any Context ClassLoader in chain of system classloader
+ // (including extension ClassLoader) so extend to widest
+ // ClassLoader (always look in system ClassLoader if Xalan
+ // is in boot/extension/system classpath and in current
+ // ClassLoader otherwise); normal classloaders delegate
+ // back to system ClassLoader first so this widening doesn't
+ // change the fact that context ClassLoader will be consulted
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+
+ chain = system;
+ while (true) {
+ if (current == chain) {
+ // Assert: Current ClassLoader in chain of
+ // boot/extension/system ClassLoaders
+ return system;
+ }
+ if (chain == null) {
+ break;
+ }
+ chain = ss.getParentClassLoader(chain);
+ }
+
+ // Assert: Current ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return current;
+ }
+
+ if (chain == null) {
+ // boot ClassLoader reached
+ break;
+ }
+
+ // Check for any extension ClassLoaders in chain up to
+ // boot ClassLoader
+ chain = ss.getParentClassLoader(chain);
+ };
+
+ // Assert: Context ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return context;
+ } // findClassLoader():ClassLoader
+
+ /**
+ * Create an instance of a class using the specified ClassLoader
+ */
+ static Object newInstance(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ConfigurationError
+ {
+ // assert(className != null);
+ 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);
+ }
+ }
+
+ /**
+ * Find a Class using the specified ClassLoader
+ */
+ static Class findProviderClass(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ClassNotFoundException, ConfigurationError
+ {
+
+ SecurityManager security = System.getSecurityManager();
+ try{
+ if (security != null)
+ security.checkPackageAccess(className);
+ }catch(SecurityException e){
+ throw e;
+ }
+
+ Class providerClass;
+ if (cl == null) {
+ // XXX Use the bootstrap ClassLoader. There is no way to
+ // load a class using the bootstrap ClassLoader that works
+ // in both JDK 1.1 and Java 2. However, this should still
+ // work b/c the following should be true:
+ //
+ // (cl == null) iff current ClassLoader == null
+ //
+ // Thus Class.forName(String) will use the current
+ // ClassLoader which will be the bootstrap ClassLoader.
+ providerClass = Class.forName(className);
+ } else {
+ try {
+ providerClass = cl.loadClass(className);
+ } catch (ClassNotFoundException x) {
+ if (doFallback) {
+ // Fall back to current classloader
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (current == null) {
+ providerClass = Class.forName(className);
+ } else if (cl != current) {
+ cl = current;
+ providerClass = cl.loadClass(className);
+ } else {
+ throw x;
+ }
+ } else {
+ throw x;
+ }
+ }
+ }
+
+ return providerClass;
+ }
+
+ /**
+ * Find the name of service provider using Jar Service Provider Mechanism
+ *
+ * @return instance of provider class if found or null
+ */
+ private static String findJarServiceProviderName(String factoryId)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+ String serviceId = SERVICES_PATH + factoryId;
+ InputStream is = null;
+
+ // First try the Context ClassLoader
+ ClassLoader cl = findClassLoader();
+
+ is = ss.getResourceAsStream(cl, serviceId);
+
+ // If no provider found then try the current ClassLoader
+ if (is == null) {
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (cl != current) {
+ cl = current;
+ is = ss.getResourceAsStream(cl, serviceId);
+ }
+ }
+
+ if (is == null) {
+ // No provider found
+ return null;
+ }
+
+ debugPrintln("found jar resource=" + serviceId +
+ " using ClassLoader: " + cl);
+
+ // Read the service provider name in UTF-8 as specified in
+ // the jar spec. Unfortunately this fails in Microsoft
+ // VJ++, which does not implement the UTF-8
+ // encoding. Theoretically, we should simply let it fail in
+ // that case, since the JVM is obviously broken if it
+ // doesn't support such a basic standard. But since there
+ // are still some users attempting to use VJ++ for
+ // development, we have dropped in a fallback which makes a
+ // second attempt using the platform's default encoding. In
+ // VJ++ this is apparently ASCII, which is a subset of
+ // UTF-8... and since the strings we'll be reading here are
+ // also primarily limited to the 7-bit ASCII range (at
+ // least, in English versions), this should work well
+ // enough to keep us on the air until we're ready to
+ // officially decommit from VJ++. [Edited comment from
+ // jkesselm]
+ BufferedReader rd;
+ try {
+ rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ } catch (java.io.UnsupportedEncodingException e) {
+ rd = new BufferedReader(new InputStreamReader(is));
+ }
+
+ String factoryClassName = null;
+ try {
+ // XXX Does not handle all possible input as specified by the
+ // Jar Service Provider specification
+ factoryClassName = rd.readLine();
+ rd.close();
+ } catch (IOException x) {
+ // No provider found
+ return null;
+ }
+
+ if (factoryClassName != null &&
+ ! "".equals(factoryClassName)) {
+ debugPrintln("found in resource, value="
+ + factoryClassName);
+
+ // Note: here we do not want to fall back to the current
+ // ClassLoader because we want to avoid the case where the
+ // resource file was found using one ClassLoader and the
+ // provider class was instantiated using a different one.
+ return factoryClassName;
+ }
+
+ // No provider found
+ return null;
+ }
+
+ //
+ // Classes
+ //
+
+ /**
+ * A configuration error.
+ */
+ static class ConfigurationError
+ extends Error {
+
+ //
+ // Data
+ //
+
+ /** Exception. */
+ private Exception exception;
+
+ //
+ // Constructors
+ //
+
+ /**
+ * Construct a new instance with the specified detail string and
+ * exception.
+ */
+ public ConfigurationError(String msg, Exception x) {
+ super(msg);
+ this.exception = x;
+ } // <init>(String,Exception)
+
+ //
+ // Public methods
+ //
+
+ /** Returns the exception associated to this error. */
+ public Exception getException() {
+ return exception;
+ } // getException():Exception
+
+ } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xalan/xslt/Process.java b/src/org/apache/xalan/xslt/Process.java
index 939ada6..86e042c 100644
--- a/src/org/apache/xalan/xslt/Process.java
+++ b/src/org/apache/xalan/xslt/Process.java
@@ -90,7 +90,7 @@
import org.apache.xalan.trace.TraceManager;
import org.apache.xalan.transformer.XalanProperties;
import org.apache.xml.utils.DefaultErrorHandler;
-import org.apache.xml.utils.ObjectFactory;
+
import org.w3c.dom.Document;
import org.w3c.dom.Node;
diff --git a/src/org/apache/xalan/xslt/SecuritySupport.java b/src/org/apache/xalan/xslt/SecuritySupport.java
new file mode 100755
index 0000000..9349fac
--- /dev/null
+++ b/src/org/apache/xalan/xslt/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xslt;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+ /*
+ * Make this of type Object so that the verifier won't try to
+ * prove its type, thus possibly trying to load the SecuritySupport12
+ * class.
+ */
+ private static final Object securitySupport;
+
+ static {
+ SecuritySupport ss = null;
+ try {
+ Class c = Class.forName("java.security.AccessController");
+ // if that worked, we're on 1.2.
+ /*
+ // don't reference the class explicitly so it doesn't
+ // get dragged in accidentally.
+ c = Class.forName("javax.mail.SecuritySupport12");
+ Constructor cons = c.getConstructor(new Class[] { });
+ ss = (SecuritySupport)cons.newInstance(new Object[] { });
+ */
+ /*
+ * Unfortunately, we can't load the class using reflection
+ * because the class is package private. And the class has
+ * to be package private so the APIs aren't exposed to other
+ * code that could use them to circumvent security. Thus,
+ * we accept the risk that the direct reference might fail
+ * on some JDK 1.1 JVMs, even though we would never execute
+ * this code in such a case. Sigh...
+ */
+ ss = new SecuritySupport12();
+ } catch (Exception ex) {
+ // ignore it
+ } finally {
+ if (ss == null)
+ ss = new SecuritySupport();
+ securitySupport = ss;
+ }
+ }
+
+ /**
+ * Return an appropriate instance of this class, depending on whether
+ * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+ */
+ static SecuritySupport getInstance() {
+ return (SecuritySupport)securitySupport;
+ }
+
+ ClassLoader getContextClassLoader() {
+ return null;
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return null;
+ }
+
+ ClassLoader getParentClassLoader(ClassLoader cl) {
+ return null;
+ }
+
+ String getSystemProperty(String propName) {
+ return System.getProperty(propName);
+ }
+
+ FileInputStream getFileInputStream(File file)
+ throws FileNotFoundException
+ {
+ return new FileInputStream(file);
+ }
+
+ InputStream getResourceAsStream(ClassLoader cl, String name) {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+
+ boolean getFileExists(File f) {
+ return f.exists();
+ }
+
+ long getLastModified(File f) {
+ return f.lastModified();
+ }
+}
diff --git a/src/org/apache/xalan/xslt/SecuritySupport12.java b/src/org/apache/xalan/xslt/SecuritySupport12.java
new file mode 100755
index 0000000..f62d65c
--- /dev/null
+++ b/src/org/apache/xalan/xslt/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xslt;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+ ClassLoader getContextClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = Thread.currentThread().getContextClassLoader();
+ } catch (SecurityException ex) { }
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = ClassLoader.getSystemClassLoader();
+ } catch (SecurityException ex) {}
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getParentClassLoader(final ClassLoader cl) {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader parent = null;
+ try {
+ parent = cl.getParent();
+ } catch (SecurityException ex) {}
+
+ // eliminate loops in case of the boot
+ // ClassLoader returning itself as a parent
+ return (parent == cl) ? null : parent;
+ }
+ });
+ }
+
+ String getSystemProperty(final String propName) {
+ return (String)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty(propName);
+ }
+ });
+ }
+
+ FileInputStream getFileInputStream(final File file)
+ throws FileNotFoundException
+ {
+ try {
+ return (FileInputStream)
+ AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws FileNotFoundException {
+ return new FileInputStream(file);
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ throw (FileNotFoundException)e.getException();
+ }
+ }
+
+ InputStream getResourceAsStream(final ClassLoader cl,
+ final String name)
+ {
+ return (InputStream)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+ });
+ }
+
+ boolean getFileExists(final File f) {
+ return ((Boolean)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Boolean(f.exists());
+ }
+ })).booleanValue();
+ }
+
+ long getLastModified(final File f) {
+ return ((Long)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Long(f.lastModified());
+ }
+ })).longValue();
+ }
+
+}
diff --git a/src/org/apache/xalan/xsltc/cmdline/ObjectFactory.java b/src/org/apache/xalan/xsltc/cmdline/ObjectFactory.java
new file mode 100755
index 0000000..c2bc107
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/cmdline/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.cmdline;
+
+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;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+ //
+ // Constants
+ //
+
+ // name of default properties file to look for in JDK's jre/lib directory
+ private static final String DEFAULT_PROPERTIES_FILENAME =
+ "xalan.properties";
+
+ private static final String SERVICES_PATH = "META-INF/services";
+
+ /** Set to true for debugging */
+ private static final boolean DEBUG = false;
+
+ /** cache the contents of the xalan.properties file.
+ * Until an attempt has been made to read this file, this will
+ * be null; if the file does not exist or we encounter some other error
+ * during the read, this will be empty.
+ */
+ private static Properties fXalanProperties = null;
+
+ /***
+ * Cache the time stamp of the xalan.properties file so
+ * that we know if it's been modified and can invalidate
+ * the cache when necessary.
+ */
+ private static long fLastModified = -1;
+
+ //
+ // Public static methods
+ //
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance 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.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId, String fallbackClassName)
+ throws ConfigurationError {
+ return createObject(factoryId, null, fallbackClassName);
+ } // createObject(String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ Class factoryClass = lookUpFactoryClass(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+
+ if (factoryClass == null) {
+ throw new ConfigurationError(
+ "Provider for " + factoryId + " cannot be found", null);
+ }
+
+ try{
+ Object instance = factoryClass.newInstance();
+ debugPrintln("created new instance of factory " + factoryId);
+ return instance;
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider for factory " + factoryId
+ + " could not be instantiated: " + x, x);
+ }
+ } // createObject(String,String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId)
+ throws ConfigurationError
+ {
+ return lookUpFactoryClass(factoryId, null, null);
+ } // lookUpFactoryClass(String):Class
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ String factoryClassName = lookUpFactoryClassName(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+ ClassLoader cl = findClassLoader();
+
+ if (factoryClassName == null) {
+ factoryClassName = fallbackClassName;
+ }
+
+ // assert(className != null);
+ try{
+ Class providerClass = findProviderClass(factoryClassName,
+ cl,
+ true);
+ debugPrintln("created new instance of " + providerClass +
+ " using ClassLoader: " + cl);
+ return providerClass;
+ } catch (ClassNotFoundException x) {
+ throw new ConfigurationError(
+ "Provider " + factoryClassName + " not found", x);
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider "+factoryClassName+" could not be instantiated: "+x,
+ x);
+ }
+ } // lookUpFactoryClass(String,String,String):Class
+
+ /**
+ * Finds the name of the required implementation class in the specified
+ * order. The specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return name of class that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static String lookUpFactoryClassName(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Use the system property first
+ try {
+ String systemProp = ss.getSystemProperty(factoryId);
+ if (systemProp != null) {
+ debugPrintln("found system property, value=" + systemProp);
+ return systemProp;
+ }
+ } catch (SecurityException se) {
+ // Ignore and continue w/ next location
+ }
+
+ // Try to read from propertiesFilename, or
+ // $java.home/lib/xalan.properties
+ String factoryClassName = null;
+ // no properties file name specified; use
+ // $JAVA_HOME/lib/xalan.properties:
+ if (propertiesFilename == null) {
+ File propertiesFile = null;
+ boolean propertiesFileExists = false;
+ try {
+ String javah = ss.getSystemProperty("java.home");
+ propertiesFilename = javah + File.separator +
+ "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+ propertiesFile = new File(propertiesFilename);
+ propertiesFileExists = ss.getFileExists(propertiesFile);
+ } catch (SecurityException e) {
+ // try again...
+ fLastModified = -1;
+ fXalanProperties = null;
+ }
+
+ synchronized (ObjectFactory.class) {
+ boolean loadProperties = false;
+ try {
+ // file existed last time
+ if(fLastModified >= 0) {
+ if(propertiesFileExists &&
+ (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+ loadProperties = true;
+ } else {
+ // file has stopped existing...
+ if(!propertiesFileExists) {
+ fLastModified = -1;
+ fXalanProperties = null;
+ } // else, file wasn't modified!
+ }
+ } else {
+ // file has started to exist:
+ if(propertiesFileExists) {
+ loadProperties = true;
+ fLastModified = ss.getLastModified(propertiesFile);
+ } // else, nothing's changed
+ }
+ if(loadProperties) {
+ // must never have attempted to read xalan.properties
+ // before (or it's outdeated)
+ fXalanProperties = new Properties();
+ FileInputStream fis =
+ ss.getFileInputStream(propertiesFile);
+ fXalanProperties.load(fis);
+ fis.close();
+ }
+ } catch (Exception x) {
+ fXalanProperties = null;
+ fLastModified = -1;
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if(fXalanProperties != null) {
+ factoryClassName = fXalanProperties.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) {
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if (factoryClassName != null) {
+ debugPrintln("found in " + propertiesFilename + ", value="
+ + factoryClassName);
+ return factoryClassName;
+ }
+
+ // Try Jar Service Provider Mechanism
+ return findJarServiceProviderName(factoryId);
+ } // lookUpFactoryClass(String,String):String
+
+ //
+ // Private static methods
+ //
+
+ /** Prints a message to standard error if debugging is enabled. */
+ private static void debugPrintln(String msg) {
+ if (DEBUG) {
+ System.err.println("JAXP: " + msg);
+ }
+ } // debugPrintln(String)
+
+ /**
+ * Figure out which ClassLoader to use. For JDK 1.2 and later use
+ * the context ClassLoader.
+ */
+ static ClassLoader findClassLoader()
+ throws ConfigurationError
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Figure out which ClassLoader to use for loading the provider
+ // class. If there is a Context ClassLoader then use it.
+ ClassLoader context = ss.getContextClassLoader();
+ ClassLoader system = ss.getSystemClassLoader();
+
+ ClassLoader chain = system;
+ while (true) {
+ if (context == chain) {
+ // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+ // or any Context ClassLoader in chain of system classloader
+ // (including extension ClassLoader) so extend to widest
+ // ClassLoader (always look in system ClassLoader if Xalan
+ // is in boot/extension/system classpath and in current
+ // ClassLoader otherwise); normal classloaders delegate
+ // back to system ClassLoader first so this widening doesn't
+ // change the fact that context ClassLoader will be consulted
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+
+ chain = system;
+ while (true) {
+ if (current == chain) {
+ // Assert: Current ClassLoader in chain of
+ // boot/extension/system ClassLoaders
+ return system;
+ }
+ if (chain == null) {
+ break;
+ }
+ chain = ss.getParentClassLoader(chain);
+ }
+
+ // Assert: Current ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return current;
+ }
+
+ if (chain == null) {
+ // boot ClassLoader reached
+ break;
+ }
+
+ // Check for any extension ClassLoaders in chain up to
+ // boot ClassLoader
+ chain = ss.getParentClassLoader(chain);
+ };
+
+ // Assert: Context ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return context;
+ } // findClassLoader():ClassLoader
+
+ /**
+ * Create an instance of a class using the specified ClassLoader
+ */
+ static Object newInstance(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ConfigurationError
+ {
+ // assert(className != null);
+ 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);
+ }
+ }
+
+ /**
+ * Find a Class using the specified ClassLoader
+ */
+ static Class findProviderClass(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ClassNotFoundException, ConfigurationError
+ {
+
+ SecurityManager security = System.getSecurityManager();
+ try{
+ if (security != null)
+ security.checkPackageAccess(className);
+ }catch(SecurityException e){
+ throw e;
+ }
+
+ Class providerClass;
+ if (cl == null) {
+ // XXX Use the bootstrap ClassLoader. There is no way to
+ // load a class using the bootstrap ClassLoader that works
+ // in both JDK 1.1 and Java 2. However, this should still
+ // work b/c the following should be true:
+ //
+ // (cl == null) iff current ClassLoader == null
+ //
+ // Thus Class.forName(String) will use the current
+ // ClassLoader which will be the bootstrap ClassLoader.
+ providerClass = Class.forName(className);
+ } else {
+ try {
+ providerClass = cl.loadClass(className);
+ } catch (ClassNotFoundException x) {
+ if (doFallback) {
+ // Fall back to current classloader
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (current == null) {
+ providerClass = Class.forName(className);
+ } else if (cl != current) {
+ cl = current;
+ providerClass = cl.loadClass(className);
+ } else {
+ throw x;
+ }
+ } else {
+ throw x;
+ }
+ }
+ }
+
+ return providerClass;
+ }
+
+ /**
+ * Find the name of service provider using Jar Service Provider Mechanism
+ *
+ * @return instance of provider class if found or null
+ */
+ private static String findJarServiceProviderName(String factoryId)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+ String serviceId = SERVICES_PATH + factoryId;
+ InputStream is = null;
+
+ // First try the Context ClassLoader
+ ClassLoader cl = findClassLoader();
+
+ is = ss.getResourceAsStream(cl, serviceId);
+
+ // If no provider found then try the current ClassLoader
+ if (is == null) {
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (cl != current) {
+ cl = current;
+ is = ss.getResourceAsStream(cl, serviceId);
+ }
+ }
+
+ if (is == null) {
+ // No provider found
+ return null;
+ }
+
+ debugPrintln("found jar resource=" + serviceId +
+ " using ClassLoader: " + cl);
+
+ // Read the service provider name in UTF-8 as specified in
+ // the jar spec. Unfortunately this fails in Microsoft
+ // VJ++, which does not implement the UTF-8
+ // encoding. Theoretically, we should simply let it fail in
+ // that case, since the JVM is obviously broken if it
+ // doesn't support such a basic standard. But since there
+ // are still some users attempting to use VJ++ for
+ // development, we have dropped in a fallback which makes a
+ // second attempt using the platform's default encoding. In
+ // VJ++ this is apparently ASCII, which is a subset of
+ // UTF-8... and since the strings we'll be reading here are
+ // also primarily limited to the 7-bit ASCII range (at
+ // least, in English versions), this should work well
+ // enough to keep us on the air until we're ready to
+ // officially decommit from VJ++. [Edited comment from
+ // jkesselm]
+ BufferedReader rd;
+ try {
+ rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ } catch (java.io.UnsupportedEncodingException e) {
+ rd = new BufferedReader(new InputStreamReader(is));
+ }
+
+ String factoryClassName = null;
+ try {
+ // XXX Does not handle all possible input as specified by the
+ // Jar Service Provider specification
+ factoryClassName = rd.readLine();
+ rd.close();
+ } catch (IOException x) {
+ // No provider found
+ return null;
+ }
+
+ if (factoryClassName != null &&
+ ! "".equals(factoryClassName)) {
+ debugPrintln("found in resource, value="
+ + factoryClassName);
+
+ // Note: here we do not want to fall back to the current
+ // ClassLoader because we want to avoid the case where the
+ // resource file was found using one ClassLoader and the
+ // provider class was instantiated using a different one.
+ return factoryClassName;
+ }
+
+ // No provider found
+ return null;
+ }
+
+ //
+ // Classes
+ //
+
+ /**
+ * A configuration error.
+ */
+ static class ConfigurationError
+ extends Error {
+
+ //
+ // Data
+ //
+
+ /** Exception. */
+ private Exception exception;
+
+ //
+ // Constructors
+ //
+
+ /**
+ * Construct a new instance with the specified detail string and
+ * exception.
+ */
+ public ConfigurationError(String msg, Exception x) {
+ super(msg);
+ this.exception = x;
+ } // <init>(String,Exception)
+
+ //
+ // Public methods
+ //
+
+ /** Returns the exception associated to this error. */
+ public Exception getException() {
+ return exception;
+ } // getException():Exception
+
+ } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xalan/xsltc/cmdline/SecuritySupport.java b/src/org/apache/xalan/xsltc/cmdline/SecuritySupport.java
new file mode 100755
index 0000000..ec1bda9
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/cmdline/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.cmdline;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+ /*
+ * Make this of type Object so that the verifier won't try to
+ * prove its type, thus possibly trying to load the SecuritySupport12
+ * class.
+ */
+ private static final Object securitySupport;
+
+ static {
+ SecuritySupport ss = null;
+ try {
+ Class c = Class.forName("java.security.AccessController");
+ // if that worked, we're on 1.2.
+ /*
+ // don't reference the class explicitly so it doesn't
+ // get dragged in accidentally.
+ c = Class.forName("javax.mail.SecuritySupport12");
+ Constructor cons = c.getConstructor(new Class[] { });
+ ss = (SecuritySupport)cons.newInstance(new Object[] { });
+ */
+ /*
+ * Unfortunately, we can't load the class using reflection
+ * because the class is package private. And the class has
+ * to be package private so the APIs aren't exposed to other
+ * code that could use them to circumvent security. Thus,
+ * we accept the risk that the direct reference might fail
+ * on some JDK 1.1 JVMs, even though we would never execute
+ * this code in such a case. Sigh...
+ */
+ ss = new SecuritySupport12();
+ } catch (Exception ex) {
+ // ignore it
+ } finally {
+ if (ss == null)
+ ss = new SecuritySupport();
+ securitySupport = ss;
+ }
+ }
+
+ /**
+ * Return an appropriate instance of this class, depending on whether
+ * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+ */
+ static SecuritySupport getInstance() {
+ return (SecuritySupport)securitySupport;
+ }
+
+ ClassLoader getContextClassLoader() {
+ return null;
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return null;
+ }
+
+ ClassLoader getParentClassLoader(ClassLoader cl) {
+ return null;
+ }
+
+ String getSystemProperty(String propName) {
+ return System.getProperty(propName);
+ }
+
+ FileInputStream getFileInputStream(File file)
+ throws FileNotFoundException
+ {
+ return new FileInputStream(file);
+ }
+
+ InputStream getResourceAsStream(ClassLoader cl, String name) {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+
+ boolean getFileExists(File f) {
+ return f.exists();
+ }
+
+ long getLastModified(File f) {
+ return f.lastModified();
+ }
+}
diff --git a/src/org/apache/xalan/xsltc/cmdline/SecuritySupport12.java b/src/org/apache/xalan/xsltc/cmdline/SecuritySupport12.java
new file mode 100755
index 0000000..a4b4089
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/cmdline/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.cmdline;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+ ClassLoader getContextClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = Thread.currentThread().getContextClassLoader();
+ } catch (SecurityException ex) { }
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = ClassLoader.getSystemClassLoader();
+ } catch (SecurityException ex) {}
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getParentClassLoader(final ClassLoader cl) {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader parent = null;
+ try {
+ parent = cl.getParent();
+ } catch (SecurityException ex) {}
+
+ // eliminate loops in case of the boot
+ // ClassLoader returning itself as a parent
+ return (parent == cl) ? null : parent;
+ }
+ });
+ }
+
+ String getSystemProperty(final String propName) {
+ return (String)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty(propName);
+ }
+ });
+ }
+
+ FileInputStream getFileInputStream(final File file)
+ throws FileNotFoundException
+ {
+ try {
+ return (FileInputStream)
+ AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws FileNotFoundException {
+ return new FileInputStream(file);
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ throw (FileNotFoundException)e.getException();
+ }
+ }
+
+ InputStream getResourceAsStream(final ClassLoader cl,
+ final String name)
+ {
+ return (InputStream)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+ });
+ }
+
+ boolean getFileExists(final File f) {
+ return ((Boolean)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Boolean(f.exists());
+ }
+ })).booleanValue();
+ }
+
+ long getLastModified(final File f) {
+ return ((Long)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Long(f.lastModified());
+ }
+ })).longValue();
+ }
+
+}
diff --git a/src/org/apache/xalan/xsltc/cmdline/Transform.java b/src/org/apache/xalan/xsltc/cmdline/Transform.java
index 8035a49..69ca677 100644
--- a/src/org/apache/xalan/xsltc/cmdline/Transform.java
+++ b/src/org/apache/xalan/xsltc/cmdline/Transform.java
@@ -80,7 +80,7 @@
import org.apache.xalan.xsltc.dom.XSLTCDTMManager;
import org.apache.xalan.xsltc.runtime.AbstractTranslet;
import org.apache.xalan.xsltc.runtime.Constants;
-import org.apache.xml.utils.ObjectFactory;
+
import org.apache.xalan.xsltc.runtime.Parameter;
import org.apache.xalan.xsltc.runtime.output.TransletOutputHandlerFactory;
import org.apache.xml.serializer.SerializationHandler;
diff --git a/src/org/apache/xalan/xsltc/compiler/FunctionAvailableCall.java b/src/org/apache/xalan/xsltc/compiler/FunctionAvailableCall.java
index 4828dde..428ea96 100644
--- a/src/org/apache/xalan/xsltc/compiler/FunctionAvailableCall.java
+++ b/src/org/apache/xalan/xsltc/compiler/FunctionAvailableCall.java
@@ -75,7 +75,7 @@
import org.apache.xalan.xsltc.compiler.util.Type;
import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
import org.apache.xalan.xsltc.compiler.util.Util;
-import org.apache.xml.utils.ObjectFactory;
+
final class FunctionAvailableCall extends FunctionCall {
diff --git a/src/org/apache/xalan/xsltc/compiler/FunctionCall.java b/src/org/apache/xalan/xsltc/compiler/FunctionCall.java
index 2a7f667..afa0375 100644
--- a/src/org/apache/xalan/xsltc/compiler/FunctionCall.java
+++ b/src/org/apache/xalan/xsltc/compiler/FunctionCall.java
@@ -95,7 +95,7 @@
import org.apache.xalan.xsltc.compiler.util.ReferenceType;
import org.apache.xalan.xsltc.compiler.util.Type;
import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
-import org.apache.xml.utils.ObjectFactory;
+
class FunctionCall extends Expression {
diff --git a/src/org/apache/xalan/xsltc/compiler/ObjectFactory.java b/src/org/apache/xalan/xsltc/compiler/ObjectFactory.java
new file mode 100755
index 0000000..9702f13
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/compiler/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.compiler;
+
+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;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+ //
+ // Constants
+ //
+
+ // name of default properties file to look for in JDK's jre/lib directory
+ private static final String DEFAULT_PROPERTIES_FILENAME =
+ "xalan.properties";
+
+ private static final String SERVICES_PATH = "META-INF/services";
+
+ /** Set to true for debugging */
+ private static final boolean DEBUG = false;
+
+ /** cache the contents of the xalan.properties file.
+ * Until an attempt has been made to read this file, this will
+ * be null; if the file does not exist or we encounter some other error
+ * during the read, this will be empty.
+ */
+ private static Properties fXalanProperties = null;
+
+ /***
+ * Cache the time stamp of the xalan.properties file so
+ * that we know if it's been modified and can invalidate
+ * the cache when necessary.
+ */
+ private static long fLastModified = -1;
+
+ //
+ // Public static methods
+ //
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance 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.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId, String fallbackClassName)
+ throws ConfigurationError {
+ return createObject(factoryId, null, fallbackClassName);
+ } // createObject(String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ Class factoryClass = lookUpFactoryClass(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+
+ if (factoryClass == null) {
+ throw new ConfigurationError(
+ "Provider for " + factoryId + " cannot be found", null);
+ }
+
+ try{
+ Object instance = factoryClass.newInstance();
+ debugPrintln("created new instance of factory " + factoryId);
+ return instance;
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider for factory " + factoryId
+ + " could not be instantiated: " + x, x);
+ }
+ } // createObject(String,String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId)
+ throws ConfigurationError
+ {
+ return lookUpFactoryClass(factoryId, null, null);
+ } // lookUpFactoryClass(String):Class
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ String factoryClassName = lookUpFactoryClassName(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+ ClassLoader cl = findClassLoader();
+
+ if (factoryClassName == null) {
+ factoryClassName = fallbackClassName;
+ }
+
+ // assert(className != null);
+ try{
+ Class providerClass = findProviderClass(factoryClassName,
+ cl,
+ true);
+ debugPrintln("created new instance of " + providerClass +
+ " using ClassLoader: " + cl);
+ return providerClass;
+ } catch (ClassNotFoundException x) {
+ throw new ConfigurationError(
+ "Provider " + factoryClassName + " not found", x);
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider "+factoryClassName+" could not be instantiated: "+x,
+ x);
+ }
+ } // lookUpFactoryClass(String,String,String):Class
+
+ /**
+ * Finds the name of the required implementation class in the specified
+ * order. The specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return name of class that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static String lookUpFactoryClassName(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Use the system property first
+ try {
+ String systemProp = ss.getSystemProperty(factoryId);
+ if (systemProp != null) {
+ debugPrintln("found system property, value=" + systemProp);
+ return systemProp;
+ }
+ } catch (SecurityException se) {
+ // Ignore and continue w/ next location
+ }
+
+ // Try to read from propertiesFilename, or
+ // $java.home/lib/xalan.properties
+ String factoryClassName = null;
+ // no properties file name specified; use
+ // $JAVA_HOME/lib/xalan.properties:
+ if (propertiesFilename == null) {
+ File propertiesFile = null;
+ boolean propertiesFileExists = false;
+ try {
+ String javah = ss.getSystemProperty("java.home");
+ propertiesFilename = javah + File.separator +
+ "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+ propertiesFile = new File(propertiesFilename);
+ propertiesFileExists = ss.getFileExists(propertiesFile);
+ } catch (SecurityException e) {
+ // try again...
+ fLastModified = -1;
+ fXalanProperties = null;
+ }
+
+ synchronized (ObjectFactory.class) {
+ boolean loadProperties = false;
+ try {
+ // file existed last time
+ if(fLastModified >= 0) {
+ if(propertiesFileExists &&
+ (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+ loadProperties = true;
+ } else {
+ // file has stopped existing...
+ if(!propertiesFileExists) {
+ fLastModified = -1;
+ fXalanProperties = null;
+ } // else, file wasn't modified!
+ }
+ } else {
+ // file has started to exist:
+ if(propertiesFileExists) {
+ loadProperties = true;
+ fLastModified = ss.getLastModified(propertiesFile);
+ } // else, nothing's changed
+ }
+ if(loadProperties) {
+ // must never have attempted to read xalan.properties
+ // before (or it's outdeated)
+ fXalanProperties = new Properties();
+ FileInputStream fis =
+ ss.getFileInputStream(propertiesFile);
+ fXalanProperties.load(fis);
+ fis.close();
+ }
+ } catch (Exception x) {
+ fXalanProperties = null;
+ fLastModified = -1;
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if(fXalanProperties != null) {
+ factoryClassName = fXalanProperties.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) {
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if (factoryClassName != null) {
+ debugPrintln("found in " + propertiesFilename + ", value="
+ + factoryClassName);
+ return factoryClassName;
+ }
+
+ // Try Jar Service Provider Mechanism
+ return findJarServiceProviderName(factoryId);
+ } // lookUpFactoryClass(String,String):String
+
+ //
+ // Private static methods
+ //
+
+ /** Prints a message to standard error if debugging is enabled. */
+ private static void debugPrintln(String msg) {
+ if (DEBUG) {
+ System.err.println("JAXP: " + msg);
+ }
+ } // debugPrintln(String)
+
+ /**
+ * Figure out which ClassLoader to use. For JDK 1.2 and later use
+ * the context ClassLoader.
+ */
+ static ClassLoader findClassLoader()
+ throws ConfigurationError
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Figure out which ClassLoader to use for loading the provider
+ // class. If there is a Context ClassLoader then use it.
+ ClassLoader context = ss.getContextClassLoader();
+ ClassLoader system = ss.getSystemClassLoader();
+
+ ClassLoader chain = system;
+ while (true) {
+ if (context == chain) {
+ // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+ // or any Context ClassLoader in chain of system classloader
+ // (including extension ClassLoader) so extend to widest
+ // ClassLoader (always look in system ClassLoader if Xalan
+ // is in boot/extension/system classpath and in current
+ // ClassLoader otherwise); normal classloaders delegate
+ // back to system ClassLoader first so this widening doesn't
+ // change the fact that context ClassLoader will be consulted
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+
+ chain = system;
+ while (true) {
+ if (current == chain) {
+ // Assert: Current ClassLoader in chain of
+ // boot/extension/system ClassLoaders
+ return system;
+ }
+ if (chain == null) {
+ break;
+ }
+ chain = ss.getParentClassLoader(chain);
+ }
+
+ // Assert: Current ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return current;
+ }
+
+ if (chain == null) {
+ // boot ClassLoader reached
+ break;
+ }
+
+ // Check for any extension ClassLoaders in chain up to
+ // boot ClassLoader
+ chain = ss.getParentClassLoader(chain);
+ };
+
+ // Assert: Context ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return context;
+ } // findClassLoader():ClassLoader
+
+ /**
+ * Create an instance of a class using the specified ClassLoader
+ */
+ static Object newInstance(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ConfigurationError
+ {
+ // assert(className != null);
+ 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);
+ }
+ }
+
+ /**
+ * Find a Class using the specified ClassLoader
+ */
+ static Class findProviderClass(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ClassNotFoundException, ConfigurationError
+ {
+
+ SecurityManager security = System.getSecurityManager();
+ try{
+ if (security != null)
+ security.checkPackageAccess(className);
+ }catch(SecurityException e){
+ throw e;
+ }
+
+ Class providerClass;
+ if (cl == null) {
+ // XXX Use the bootstrap ClassLoader. There is no way to
+ // load a class using the bootstrap ClassLoader that works
+ // in both JDK 1.1 and Java 2. However, this should still
+ // work b/c the following should be true:
+ //
+ // (cl == null) iff current ClassLoader == null
+ //
+ // Thus Class.forName(String) will use the current
+ // ClassLoader which will be the bootstrap ClassLoader.
+ providerClass = Class.forName(className);
+ } else {
+ try {
+ providerClass = cl.loadClass(className);
+ } catch (ClassNotFoundException x) {
+ if (doFallback) {
+ // Fall back to current classloader
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (current == null) {
+ providerClass = Class.forName(className);
+ } else if (cl != current) {
+ cl = current;
+ providerClass = cl.loadClass(className);
+ } else {
+ throw x;
+ }
+ } else {
+ throw x;
+ }
+ }
+ }
+
+ return providerClass;
+ }
+
+ /**
+ * Find the name of service provider using Jar Service Provider Mechanism
+ *
+ * @return instance of provider class if found or null
+ */
+ private static String findJarServiceProviderName(String factoryId)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+ String serviceId = SERVICES_PATH + factoryId;
+ InputStream is = null;
+
+ // First try the Context ClassLoader
+ ClassLoader cl = findClassLoader();
+
+ is = ss.getResourceAsStream(cl, serviceId);
+
+ // If no provider found then try the current ClassLoader
+ if (is == null) {
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (cl != current) {
+ cl = current;
+ is = ss.getResourceAsStream(cl, serviceId);
+ }
+ }
+
+ if (is == null) {
+ // No provider found
+ return null;
+ }
+
+ debugPrintln("found jar resource=" + serviceId +
+ " using ClassLoader: " + cl);
+
+ // Read the service provider name in UTF-8 as specified in
+ // the jar spec. Unfortunately this fails in Microsoft
+ // VJ++, which does not implement the UTF-8
+ // encoding. Theoretically, we should simply let it fail in
+ // that case, since the JVM is obviously broken if it
+ // doesn't support such a basic standard. But since there
+ // are still some users attempting to use VJ++ for
+ // development, we have dropped in a fallback which makes a
+ // second attempt using the platform's default encoding. In
+ // VJ++ this is apparently ASCII, which is a subset of
+ // UTF-8... and since the strings we'll be reading here are
+ // also primarily limited to the 7-bit ASCII range (at
+ // least, in English versions), this should work well
+ // enough to keep us on the air until we're ready to
+ // officially decommit from VJ++. [Edited comment from
+ // jkesselm]
+ BufferedReader rd;
+ try {
+ rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ } catch (java.io.UnsupportedEncodingException e) {
+ rd = new BufferedReader(new InputStreamReader(is));
+ }
+
+ String factoryClassName = null;
+ try {
+ // XXX Does not handle all possible input as specified by the
+ // Jar Service Provider specification
+ factoryClassName = rd.readLine();
+ rd.close();
+ } catch (IOException x) {
+ // No provider found
+ return null;
+ }
+
+ if (factoryClassName != null &&
+ ! "".equals(factoryClassName)) {
+ debugPrintln("found in resource, value="
+ + factoryClassName);
+
+ // Note: here we do not want to fall back to the current
+ // ClassLoader because we want to avoid the case where the
+ // resource file was found using one ClassLoader and the
+ // provider class was instantiated using a different one.
+ return factoryClassName;
+ }
+
+ // No provider found
+ return null;
+ }
+
+ //
+ // Classes
+ //
+
+ /**
+ * A configuration error.
+ */
+ static class ConfigurationError
+ extends Error {
+
+ //
+ // Data
+ //
+
+ /** Exception. */
+ private Exception exception;
+
+ //
+ // Constructors
+ //
+
+ /**
+ * Construct a new instance with the specified detail string and
+ * exception.
+ */
+ public ConfigurationError(String msg, Exception x) {
+ super(msg);
+ this.exception = x;
+ } // <init>(String,Exception)
+
+ //
+ // Public methods
+ //
+
+ /** Returns the exception associated to this error. */
+ public Exception getException() {
+ return exception;
+ } // getException():Exception
+
+ } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xalan/xsltc/compiler/Parser.java b/src/org/apache/xalan/xsltc/compiler/Parser.java
index abd6784..1b61789 100644
--- a/src/org/apache/xalan/xsltc/compiler/Parser.java
+++ b/src/org/apache/xalan/xsltc/compiler/Parser.java
@@ -87,7 +87,7 @@
import org.apache.xalan.xsltc.compiler.util.Type;
import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
import org.apache.xalan.xsltc.runtime.AttributeList;
-import org.apache.xml.utils.ObjectFactory;
+
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
diff --git a/src/org/apache/xalan/xsltc/compiler/SecuritySupport.java b/src/org/apache/xalan/xsltc/compiler/SecuritySupport.java
new file mode 100755
index 0000000..4c4571d
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/compiler/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.compiler;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+ /*
+ * Make this of type Object so that the verifier won't try to
+ * prove its type, thus possibly trying to load the SecuritySupport12
+ * class.
+ */
+ private static final Object securitySupport;
+
+ static {
+ SecuritySupport ss = null;
+ try {
+ Class c = Class.forName("java.security.AccessController");
+ // if that worked, we're on 1.2.
+ /*
+ // don't reference the class explicitly so it doesn't
+ // get dragged in accidentally.
+ c = Class.forName("javax.mail.SecuritySupport12");
+ Constructor cons = c.getConstructor(new Class[] { });
+ ss = (SecuritySupport)cons.newInstance(new Object[] { });
+ */
+ /*
+ * Unfortunately, we can't load the class using reflection
+ * because the class is package private. And the class has
+ * to be package private so the APIs aren't exposed to other
+ * code that could use them to circumvent security. Thus,
+ * we accept the risk that the direct reference might fail
+ * on some JDK 1.1 JVMs, even though we would never execute
+ * this code in such a case. Sigh...
+ */
+ ss = new SecuritySupport12();
+ } catch (Exception ex) {
+ // ignore it
+ } finally {
+ if (ss == null)
+ ss = new SecuritySupport();
+ securitySupport = ss;
+ }
+ }
+
+ /**
+ * Return an appropriate instance of this class, depending on whether
+ * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+ */
+ static SecuritySupport getInstance() {
+ return (SecuritySupport)securitySupport;
+ }
+
+ ClassLoader getContextClassLoader() {
+ return null;
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return null;
+ }
+
+ ClassLoader getParentClassLoader(ClassLoader cl) {
+ return null;
+ }
+
+ String getSystemProperty(String propName) {
+ return System.getProperty(propName);
+ }
+
+ FileInputStream getFileInputStream(File file)
+ throws FileNotFoundException
+ {
+ return new FileInputStream(file);
+ }
+
+ InputStream getResourceAsStream(ClassLoader cl, String name) {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+
+ boolean getFileExists(File f) {
+ return f.exists();
+ }
+
+ long getLastModified(File f) {
+ return f.lastModified();
+ }
+}
diff --git a/src/org/apache/xalan/xsltc/compiler/SecuritySupport12.java b/src/org/apache/xalan/xsltc/compiler/SecuritySupport12.java
new file mode 100755
index 0000000..cead24e
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/compiler/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.compiler;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+ ClassLoader getContextClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = Thread.currentThread().getContextClassLoader();
+ } catch (SecurityException ex) { }
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = ClassLoader.getSystemClassLoader();
+ } catch (SecurityException ex) {}
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getParentClassLoader(final ClassLoader cl) {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader parent = null;
+ try {
+ parent = cl.getParent();
+ } catch (SecurityException ex) {}
+
+ // eliminate loops in case of the boot
+ // ClassLoader returning itself as a parent
+ return (parent == cl) ? null : parent;
+ }
+ });
+ }
+
+ String getSystemProperty(final String propName) {
+ return (String)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty(propName);
+ }
+ });
+ }
+
+ FileInputStream getFileInputStream(final File file)
+ throws FileNotFoundException
+ {
+ try {
+ return (FileInputStream)
+ AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws FileNotFoundException {
+ return new FileInputStream(file);
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ throw (FileNotFoundException)e.getException();
+ }
+ }
+
+ InputStream getResourceAsStream(final ClassLoader cl,
+ final String name)
+ {
+ return (InputStream)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+ });
+ }
+
+ boolean getFileExists(final File f) {
+ return ((Boolean)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Boolean(f.exists());
+ }
+ })).booleanValue();
+ }
+
+ long getLastModified(final File f) {
+ return ((Long)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Long(f.lastModified());
+ }
+ })).longValue();
+ }
+
+}
diff --git a/src/org/apache/xalan/xsltc/compiler/util/ObjectFactory.java b/src/org/apache/xalan/xsltc/compiler/util/ObjectFactory.java
new file mode 100755
index 0000000..2b8e1d0
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/compiler/util/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.compiler.util;
+
+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;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+ //
+ // Constants
+ //
+
+ // name of default properties file to look for in JDK's jre/lib directory
+ private static final String DEFAULT_PROPERTIES_FILENAME =
+ "xalan.properties";
+
+ private static final String SERVICES_PATH = "META-INF/services";
+
+ /** Set to true for debugging */
+ private static final boolean DEBUG = false;
+
+ /** cache the contents of the xalan.properties file.
+ * Until an attempt has been made to read this file, this will
+ * be null; if the file does not exist or we encounter some other error
+ * during the read, this will be empty.
+ */
+ private static Properties fXalanProperties = null;
+
+ /***
+ * Cache the time stamp of the xalan.properties file so
+ * that we know if it's been modified and can invalidate
+ * the cache when necessary.
+ */
+ private static long fLastModified = -1;
+
+ //
+ // Public static methods
+ //
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance 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.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId, String fallbackClassName)
+ throws ConfigurationError {
+ return createObject(factoryId, null, fallbackClassName);
+ } // createObject(String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ Class factoryClass = lookUpFactoryClass(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+
+ if (factoryClass == null) {
+ throw new ConfigurationError(
+ "Provider for " + factoryId + " cannot be found", null);
+ }
+
+ try{
+ Object instance = factoryClass.newInstance();
+ debugPrintln("created new instance of factory " + factoryId);
+ return instance;
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider for factory " + factoryId
+ + " could not be instantiated: " + x, x);
+ }
+ } // createObject(String,String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId)
+ throws ConfigurationError
+ {
+ return lookUpFactoryClass(factoryId, null, null);
+ } // lookUpFactoryClass(String):Class
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ String factoryClassName = lookUpFactoryClassName(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+ ClassLoader cl = findClassLoader();
+
+ if (factoryClassName == null) {
+ factoryClassName = fallbackClassName;
+ }
+
+ // assert(className != null);
+ try{
+ Class providerClass = findProviderClass(factoryClassName,
+ cl,
+ true);
+ debugPrintln("created new instance of " + providerClass +
+ " using ClassLoader: " + cl);
+ return providerClass;
+ } catch (ClassNotFoundException x) {
+ throw new ConfigurationError(
+ "Provider " + factoryClassName + " not found", x);
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider "+factoryClassName+" could not be instantiated: "+x,
+ x);
+ }
+ } // lookUpFactoryClass(String,String,String):Class
+
+ /**
+ * Finds the name of the required implementation class in the specified
+ * order. The specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return name of class that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static String lookUpFactoryClassName(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Use the system property first
+ try {
+ String systemProp = ss.getSystemProperty(factoryId);
+ if (systemProp != null) {
+ debugPrintln("found system property, value=" + systemProp);
+ return systemProp;
+ }
+ } catch (SecurityException se) {
+ // Ignore and continue w/ next location
+ }
+
+ // Try to read from propertiesFilename, or
+ // $java.home/lib/xalan.properties
+ String factoryClassName = null;
+ // no properties file name specified; use
+ // $JAVA_HOME/lib/xalan.properties:
+ if (propertiesFilename == null) {
+ File propertiesFile = null;
+ boolean propertiesFileExists = false;
+ try {
+ String javah = ss.getSystemProperty("java.home");
+ propertiesFilename = javah + File.separator +
+ "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+ propertiesFile = new File(propertiesFilename);
+ propertiesFileExists = ss.getFileExists(propertiesFile);
+ } catch (SecurityException e) {
+ // try again...
+ fLastModified = -1;
+ fXalanProperties = null;
+ }
+
+ synchronized (ObjectFactory.class) {
+ boolean loadProperties = false;
+ try {
+ // file existed last time
+ if(fLastModified >= 0) {
+ if(propertiesFileExists &&
+ (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+ loadProperties = true;
+ } else {
+ // file has stopped existing...
+ if(!propertiesFileExists) {
+ fLastModified = -1;
+ fXalanProperties = null;
+ } // else, file wasn't modified!
+ }
+ } else {
+ // file has started to exist:
+ if(propertiesFileExists) {
+ loadProperties = true;
+ fLastModified = ss.getLastModified(propertiesFile);
+ } // else, nothing's changed
+ }
+ if(loadProperties) {
+ // must never have attempted to read xalan.properties
+ // before (or it's outdeated)
+ fXalanProperties = new Properties();
+ FileInputStream fis =
+ ss.getFileInputStream(propertiesFile);
+ fXalanProperties.load(fis);
+ fis.close();
+ }
+ } catch (Exception x) {
+ fXalanProperties = null;
+ fLastModified = -1;
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if(fXalanProperties != null) {
+ factoryClassName = fXalanProperties.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) {
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if (factoryClassName != null) {
+ debugPrintln("found in " + propertiesFilename + ", value="
+ + factoryClassName);
+ return factoryClassName;
+ }
+
+ // Try Jar Service Provider Mechanism
+ return findJarServiceProviderName(factoryId);
+ } // lookUpFactoryClass(String,String):String
+
+ //
+ // Private static methods
+ //
+
+ /** Prints a message to standard error if debugging is enabled. */
+ private static void debugPrintln(String msg) {
+ if (DEBUG) {
+ System.err.println("JAXP: " + msg);
+ }
+ } // debugPrintln(String)
+
+ /**
+ * Figure out which ClassLoader to use. For JDK 1.2 and later use
+ * the context ClassLoader.
+ */
+ static ClassLoader findClassLoader()
+ throws ConfigurationError
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Figure out which ClassLoader to use for loading the provider
+ // class. If there is a Context ClassLoader then use it.
+ ClassLoader context = ss.getContextClassLoader();
+ ClassLoader system = ss.getSystemClassLoader();
+
+ ClassLoader chain = system;
+ while (true) {
+ if (context == chain) {
+ // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+ // or any Context ClassLoader in chain of system classloader
+ // (including extension ClassLoader) so extend to widest
+ // ClassLoader (always look in system ClassLoader if Xalan
+ // is in boot/extension/system classpath and in current
+ // ClassLoader otherwise); normal classloaders delegate
+ // back to system ClassLoader first so this widening doesn't
+ // change the fact that context ClassLoader will be consulted
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+
+ chain = system;
+ while (true) {
+ if (current == chain) {
+ // Assert: Current ClassLoader in chain of
+ // boot/extension/system ClassLoaders
+ return system;
+ }
+ if (chain == null) {
+ break;
+ }
+ chain = ss.getParentClassLoader(chain);
+ }
+
+ // Assert: Current ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return current;
+ }
+
+ if (chain == null) {
+ // boot ClassLoader reached
+ break;
+ }
+
+ // Check for any extension ClassLoaders in chain up to
+ // boot ClassLoader
+ chain = ss.getParentClassLoader(chain);
+ };
+
+ // Assert: Context ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return context;
+ } // findClassLoader():ClassLoader
+
+ /**
+ * Create an instance of a class using the specified ClassLoader
+ */
+ static Object newInstance(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ConfigurationError
+ {
+ // assert(className != null);
+ 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);
+ }
+ }
+
+ /**
+ * Find a Class using the specified ClassLoader
+ */
+ static Class findProviderClass(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ClassNotFoundException, ConfigurationError
+ {
+
+ SecurityManager security = System.getSecurityManager();
+ try{
+ if (security != null)
+ security.checkPackageAccess(className);
+ }catch(SecurityException e){
+ throw e;
+ }
+
+ Class providerClass;
+ if (cl == null) {
+ // XXX Use the bootstrap ClassLoader. There is no way to
+ // load a class using the bootstrap ClassLoader that works
+ // in both JDK 1.1 and Java 2. However, this should still
+ // work b/c the following should be true:
+ //
+ // (cl == null) iff current ClassLoader == null
+ //
+ // Thus Class.forName(String) will use the current
+ // ClassLoader which will be the bootstrap ClassLoader.
+ providerClass = Class.forName(className);
+ } else {
+ try {
+ providerClass = cl.loadClass(className);
+ } catch (ClassNotFoundException x) {
+ if (doFallback) {
+ // Fall back to current classloader
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (current == null) {
+ providerClass = Class.forName(className);
+ } else if (cl != current) {
+ cl = current;
+ providerClass = cl.loadClass(className);
+ } else {
+ throw x;
+ }
+ } else {
+ throw x;
+ }
+ }
+ }
+
+ return providerClass;
+ }
+
+ /**
+ * Find the name of service provider using Jar Service Provider Mechanism
+ *
+ * @return instance of provider class if found or null
+ */
+ private static String findJarServiceProviderName(String factoryId)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+ String serviceId = SERVICES_PATH + factoryId;
+ InputStream is = null;
+
+ // First try the Context ClassLoader
+ ClassLoader cl = findClassLoader();
+
+ is = ss.getResourceAsStream(cl, serviceId);
+
+ // If no provider found then try the current ClassLoader
+ if (is == null) {
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (cl != current) {
+ cl = current;
+ is = ss.getResourceAsStream(cl, serviceId);
+ }
+ }
+
+ if (is == null) {
+ // No provider found
+ return null;
+ }
+
+ debugPrintln("found jar resource=" + serviceId +
+ " using ClassLoader: " + cl);
+
+ // Read the service provider name in UTF-8 as specified in
+ // the jar spec. Unfortunately this fails in Microsoft
+ // VJ++, which does not implement the UTF-8
+ // encoding. Theoretically, we should simply let it fail in
+ // that case, since the JVM is obviously broken if it
+ // doesn't support such a basic standard. But since there
+ // are still some users attempting to use VJ++ for
+ // development, we have dropped in a fallback which makes a
+ // second attempt using the platform's default encoding. In
+ // VJ++ this is apparently ASCII, which is a subset of
+ // UTF-8... and since the strings we'll be reading here are
+ // also primarily limited to the 7-bit ASCII range (at
+ // least, in English versions), this should work well
+ // enough to keep us on the air until we're ready to
+ // officially decommit from VJ++. [Edited comment from
+ // jkesselm]
+ BufferedReader rd;
+ try {
+ rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ } catch (java.io.UnsupportedEncodingException e) {
+ rd = new BufferedReader(new InputStreamReader(is));
+ }
+
+ String factoryClassName = null;
+ try {
+ // XXX Does not handle all possible input as specified by the
+ // Jar Service Provider specification
+ factoryClassName = rd.readLine();
+ rd.close();
+ } catch (IOException x) {
+ // No provider found
+ return null;
+ }
+
+ if (factoryClassName != null &&
+ ! "".equals(factoryClassName)) {
+ debugPrintln("found in resource, value="
+ + factoryClassName);
+
+ // Note: here we do not want to fall back to the current
+ // ClassLoader because we want to avoid the case where the
+ // resource file was found using one ClassLoader and the
+ // provider class was instantiated using a different one.
+ return factoryClassName;
+ }
+
+ // No provider found
+ return null;
+ }
+
+ //
+ // Classes
+ //
+
+ /**
+ * A configuration error.
+ */
+ static class ConfigurationError
+ extends Error {
+
+ //
+ // Data
+ //
+
+ /** Exception. */
+ private Exception exception;
+
+ //
+ // Constructors
+ //
+
+ /**
+ * Construct a new instance with the specified detail string and
+ * exception.
+ */
+ public ConfigurationError(String msg, Exception x) {
+ super(msg);
+ this.exception = x;
+ } // <init>(String,Exception)
+
+ //
+ // Public methods
+ //
+
+ /** Returns the exception associated to this error. */
+ public Exception getException() {
+ return exception;
+ } // getException():Exception
+
+ } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xalan/xsltc/compiler/util/ObjectType.java b/src/org/apache/xalan/xsltc/compiler/util/ObjectType.java
index 0f31317..94389c7 100644
--- a/src/org/apache/xalan/xsltc/compiler/util/ObjectType.java
+++ b/src/org/apache/xalan/xsltc/compiler/util/ObjectType.java
@@ -74,7 +74,7 @@
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.PUSH;
import org.apache.xalan.xsltc.compiler.Constants;
-import org.apache.xml.utils.ObjectFactory;
+
public final class ObjectType extends Type {
diff --git a/src/org/apache/xalan/xsltc/compiler/util/SecuritySupport.java b/src/org/apache/xalan/xsltc/compiler/util/SecuritySupport.java
new file mode 100755
index 0000000..e75b963
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/compiler/util/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.compiler.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+ /*
+ * Make this of type Object so that the verifier won't try to
+ * prove its type, thus possibly trying to load the SecuritySupport12
+ * class.
+ */
+ private static final Object securitySupport;
+
+ static {
+ SecuritySupport ss = null;
+ try {
+ Class c = Class.forName("java.security.AccessController");
+ // if that worked, we're on 1.2.
+ /*
+ // don't reference the class explicitly so it doesn't
+ // get dragged in accidentally.
+ c = Class.forName("javax.mail.SecuritySupport12");
+ Constructor cons = c.getConstructor(new Class[] { });
+ ss = (SecuritySupport)cons.newInstance(new Object[] { });
+ */
+ /*
+ * Unfortunately, we can't load the class using reflection
+ * because the class is package private. And the class has
+ * to be package private so the APIs aren't exposed to other
+ * code that could use them to circumvent security. Thus,
+ * we accept the risk that the direct reference might fail
+ * on some JDK 1.1 JVMs, even though we would never execute
+ * this code in such a case. Sigh...
+ */
+ ss = new SecuritySupport12();
+ } catch (Exception ex) {
+ // ignore it
+ } finally {
+ if (ss == null)
+ ss = new SecuritySupport();
+ securitySupport = ss;
+ }
+ }
+
+ /**
+ * Return an appropriate instance of this class, depending on whether
+ * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+ */
+ static SecuritySupport getInstance() {
+ return (SecuritySupport)securitySupport;
+ }
+
+ ClassLoader getContextClassLoader() {
+ return null;
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return null;
+ }
+
+ ClassLoader getParentClassLoader(ClassLoader cl) {
+ return null;
+ }
+
+ String getSystemProperty(String propName) {
+ return System.getProperty(propName);
+ }
+
+ FileInputStream getFileInputStream(File file)
+ throws FileNotFoundException
+ {
+ return new FileInputStream(file);
+ }
+
+ InputStream getResourceAsStream(ClassLoader cl, String name) {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+
+ boolean getFileExists(File f) {
+ return f.exists();
+ }
+
+ long getLastModified(File f) {
+ return f.lastModified();
+ }
+}
diff --git a/src/org/apache/xalan/xsltc/compiler/util/SecuritySupport12.java b/src/org/apache/xalan/xsltc/compiler/util/SecuritySupport12.java
new file mode 100755
index 0000000..4fc7cd7
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/compiler/util/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.compiler.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+ ClassLoader getContextClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = Thread.currentThread().getContextClassLoader();
+ } catch (SecurityException ex) { }
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = ClassLoader.getSystemClassLoader();
+ } catch (SecurityException ex) {}
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getParentClassLoader(final ClassLoader cl) {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader parent = null;
+ try {
+ parent = cl.getParent();
+ } catch (SecurityException ex) {}
+
+ // eliminate loops in case of the boot
+ // ClassLoader returning itself as a parent
+ return (parent == cl) ? null : parent;
+ }
+ });
+ }
+
+ String getSystemProperty(final String propName) {
+ return (String)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty(propName);
+ }
+ });
+ }
+
+ FileInputStream getFileInputStream(final File file)
+ throws FileNotFoundException
+ {
+ try {
+ return (FileInputStream)
+ AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws FileNotFoundException {
+ return new FileInputStream(file);
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ throw (FileNotFoundException)e.getException();
+ }
+ }
+
+ InputStream getResourceAsStream(final ClassLoader cl,
+ final String name)
+ {
+ return (InputStream)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+ });
+ }
+
+ boolean getFileExists(final File f) {
+ return ((Boolean)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Boolean(f.exists());
+ }
+ })).booleanValue();
+ }
+
+ long getLastModified(final File f) {
+ return ((Long)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Long(f.lastModified());
+ }
+ })).longValue();
+ }
+
+}
diff --git a/src/org/apache/xalan/xsltc/dom/NodeSortRecordFactory.java b/src/org/apache/xalan/xsltc/dom/NodeSortRecordFactory.java
index 1b59a71..9987105 100644
--- a/src/org/apache/xalan/xsltc/dom/NodeSortRecordFactory.java
+++ b/src/org/apache/xalan/xsltc/dom/NodeSortRecordFactory.java
@@ -68,7 +68,7 @@
import org.apache.xalan.xsltc.Translet;
import org.apache.xalan.xsltc.TransletException;
import org.apache.xalan.xsltc.runtime.AbstractTranslet;
-import org.apache.xml.utils.ObjectFactory;
+
public class NodeSortRecordFactory {
diff --git a/src/org/apache/xalan/xsltc/dom/ObjectFactory.java b/src/org/apache/xalan/xsltc/dom/ObjectFactory.java
new file mode 100755
index 0000000..fc356b9
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/dom/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.dom;
+
+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;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+ //
+ // Constants
+ //
+
+ // name of default properties file to look for in JDK's jre/lib directory
+ private static final String DEFAULT_PROPERTIES_FILENAME =
+ "xalan.properties";
+
+ private static final String SERVICES_PATH = "META-INF/services";
+
+ /** Set to true for debugging */
+ private static final boolean DEBUG = false;
+
+ /** cache the contents of the xalan.properties file.
+ * Until an attempt has been made to read this file, this will
+ * be null; if the file does not exist or we encounter some other error
+ * during the read, this will be empty.
+ */
+ private static Properties fXalanProperties = null;
+
+ /***
+ * Cache the time stamp of the xalan.properties file so
+ * that we know if it's been modified and can invalidate
+ * the cache when necessary.
+ */
+ private static long fLastModified = -1;
+
+ //
+ // Public static methods
+ //
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance 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.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId, String fallbackClassName)
+ throws ConfigurationError {
+ return createObject(factoryId, null, fallbackClassName);
+ } // createObject(String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ Class factoryClass = lookUpFactoryClass(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+
+ if (factoryClass == null) {
+ throw new ConfigurationError(
+ "Provider for " + factoryId + " cannot be found", null);
+ }
+
+ try{
+ Object instance = factoryClass.newInstance();
+ debugPrintln("created new instance of factory " + factoryId);
+ return instance;
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider for factory " + factoryId
+ + " could not be instantiated: " + x, x);
+ }
+ } // createObject(String,String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId)
+ throws ConfigurationError
+ {
+ return lookUpFactoryClass(factoryId, null, null);
+ } // lookUpFactoryClass(String):Class
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ String factoryClassName = lookUpFactoryClassName(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+ ClassLoader cl = findClassLoader();
+
+ if (factoryClassName == null) {
+ factoryClassName = fallbackClassName;
+ }
+
+ // assert(className != null);
+ try{
+ Class providerClass = findProviderClass(factoryClassName,
+ cl,
+ true);
+ debugPrintln("created new instance of " + providerClass +
+ " using ClassLoader: " + cl);
+ return providerClass;
+ } catch (ClassNotFoundException x) {
+ throw new ConfigurationError(
+ "Provider " + factoryClassName + " not found", x);
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider "+factoryClassName+" could not be instantiated: "+x,
+ x);
+ }
+ } // lookUpFactoryClass(String,String,String):Class
+
+ /**
+ * Finds the name of the required implementation class in the specified
+ * order. The specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return name of class that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static String lookUpFactoryClassName(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Use the system property first
+ try {
+ String systemProp = ss.getSystemProperty(factoryId);
+ if (systemProp != null) {
+ debugPrintln("found system property, value=" + systemProp);
+ return systemProp;
+ }
+ } catch (SecurityException se) {
+ // Ignore and continue w/ next location
+ }
+
+ // Try to read from propertiesFilename, or
+ // $java.home/lib/xalan.properties
+ String factoryClassName = null;
+ // no properties file name specified; use
+ // $JAVA_HOME/lib/xalan.properties:
+ if (propertiesFilename == null) {
+ File propertiesFile = null;
+ boolean propertiesFileExists = false;
+ try {
+ String javah = ss.getSystemProperty("java.home");
+ propertiesFilename = javah + File.separator +
+ "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+ propertiesFile = new File(propertiesFilename);
+ propertiesFileExists = ss.getFileExists(propertiesFile);
+ } catch (SecurityException e) {
+ // try again...
+ fLastModified = -1;
+ fXalanProperties = null;
+ }
+
+ synchronized (ObjectFactory.class) {
+ boolean loadProperties = false;
+ try {
+ // file existed last time
+ if(fLastModified >= 0) {
+ if(propertiesFileExists &&
+ (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+ loadProperties = true;
+ } else {
+ // file has stopped existing...
+ if(!propertiesFileExists) {
+ fLastModified = -1;
+ fXalanProperties = null;
+ } // else, file wasn't modified!
+ }
+ } else {
+ // file has started to exist:
+ if(propertiesFileExists) {
+ loadProperties = true;
+ fLastModified = ss.getLastModified(propertiesFile);
+ } // else, nothing's changed
+ }
+ if(loadProperties) {
+ // must never have attempted to read xalan.properties
+ // before (or it's outdeated)
+ fXalanProperties = new Properties();
+ FileInputStream fis =
+ ss.getFileInputStream(propertiesFile);
+ fXalanProperties.load(fis);
+ fis.close();
+ }
+ } catch (Exception x) {
+ fXalanProperties = null;
+ fLastModified = -1;
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if(fXalanProperties != null) {
+ factoryClassName = fXalanProperties.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) {
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if (factoryClassName != null) {
+ debugPrintln("found in " + propertiesFilename + ", value="
+ + factoryClassName);
+ return factoryClassName;
+ }
+
+ // Try Jar Service Provider Mechanism
+ return findJarServiceProviderName(factoryId);
+ } // lookUpFactoryClass(String,String):String
+
+ //
+ // Private static methods
+ //
+
+ /** Prints a message to standard error if debugging is enabled. */
+ private static void debugPrintln(String msg) {
+ if (DEBUG) {
+ System.err.println("JAXP: " + msg);
+ }
+ } // debugPrintln(String)
+
+ /**
+ * Figure out which ClassLoader to use. For JDK 1.2 and later use
+ * the context ClassLoader.
+ */
+ static ClassLoader findClassLoader()
+ throws ConfigurationError
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Figure out which ClassLoader to use for loading the provider
+ // class. If there is a Context ClassLoader then use it.
+ ClassLoader context = ss.getContextClassLoader();
+ ClassLoader system = ss.getSystemClassLoader();
+
+ ClassLoader chain = system;
+ while (true) {
+ if (context == chain) {
+ // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+ // or any Context ClassLoader in chain of system classloader
+ // (including extension ClassLoader) so extend to widest
+ // ClassLoader (always look in system ClassLoader if Xalan
+ // is in boot/extension/system classpath and in current
+ // ClassLoader otherwise); normal classloaders delegate
+ // back to system ClassLoader first so this widening doesn't
+ // change the fact that context ClassLoader will be consulted
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+
+ chain = system;
+ while (true) {
+ if (current == chain) {
+ // Assert: Current ClassLoader in chain of
+ // boot/extension/system ClassLoaders
+ return system;
+ }
+ if (chain == null) {
+ break;
+ }
+ chain = ss.getParentClassLoader(chain);
+ }
+
+ // Assert: Current ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return current;
+ }
+
+ if (chain == null) {
+ // boot ClassLoader reached
+ break;
+ }
+
+ // Check for any extension ClassLoaders in chain up to
+ // boot ClassLoader
+ chain = ss.getParentClassLoader(chain);
+ };
+
+ // Assert: Context ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return context;
+ } // findClassLoader():ClassLoader
+
+ /**
+ * Create an instance of a class using the specified ClassLoader
+ */
+ static Object newInstance(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ConfigurationError
+ {
+ // assert(className != null);
+ 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);
+ }
+ }
+
+ /**
+ * Find a Class using the specified ClassLoader
+ */
+ static Class findProviderClass(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ClassNotFoundException, ConfigurationError
+ {
+
+ SecurityManager security = System.getSecurityManager();
+ try{
+ if (security != null)
+ security.checkPackageAccess(className);
+ }catch(SecurityException e){
+ throw e;
+ }
+
+ Class providerClass;
+ if (cl == null) {
+ // XXX Use the bootstrap ClassLoader. There is no way to
+ // load a class using the bootstrap ClassLoader that works
+ // in both JDK 1.1 and Java 2. However, this should still
+ // work b/c the following should be true:
+ //
+ // (cl == null) iff current ClassLoader == null
+ //
+ // Thus Class.forName(String) will use the current
+ // ClassLoader which will be the bootstrap ClassLoader.
+ providerClass = Class.forName(className);
+ } else {
+ try {
+ providerClass = cl.loadClass(className);
+ } catch (ClassNotFoundException x) {
+ if (doFallback) {
+ // Fall back to current classloader
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (current == null) {
+ providerClass = Class.forName(className);
+ } else if (cl != current) {
+ cl = current;
+ providerClass = cl.loadClass(className);
+ } else {
+ throw x;
+ }
+ } else {
+ throw x;
+ }
+ }
+ }
+
+ return providerClass;
+ }
+
+ /**
+ * Find the name of service provider using Jar Service Provider Mechanism
+ *
+ * @return instance of provider class if found or null
+ */
+ private static String findJarServiceProviderName(String factoryId)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+ String serviceId = SERVICES_PATH + factoryId;
+ InputStream is = null;
+
+ // First try the Context ClassLoader
+ ClassLoader cl = findClassLoader();
+
+ is = ss.getResourceAsStream(cl, serviceId);
+
+ // If no provider found then try the current ClassLoader
+ if (is == null) {
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (cl != current) {
+ cl = current;
+ is = ss.getResourceAsStream(cl, serviceId);
+ }
+ }
+
+ if (is == null) {
+ // No provider found
+ return null;
+ }
+
+ debugPrintln("found jar resource=" + serviceId +
+ " using ClassLoader: " + cl);
+
+ // Read the service provider name in UTF-8 as specified in
+ // the jar spec. Unfortunately this fails in Microsoft
+ // VJ++, which does not implement the UTF-8
+ // encoding. Theoretically, we should simply let it fail in
+ // that case, since the JVM is obviously broken if it
+ // doesn't support such a basic standard. But since there
+ // are still some users attempting to use VJ++ for
+ // development, we have dropped in a fallback which makes a
+ // second attempt using the platform's default encoding. In
+ // VJ++ this is apparently ASCII, which is a subset of
+ // UTF-8... and since the strings we'll be reading here are
+ // also primarily limited to the 7-bit ASCII range (at
+ // least, in English versions), this should work well
+ // enough to keep us on the air until we're ready to
+ // officially decommit from VJ++. [Edited comment from
+ // jkesselm]
+ BufferedReader rd;
+ try {
+ rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ } catch (java.io.UnsupportedEncodingException e) {
+ rd = new BufferedReader(new InputStreamReader(is));
+ }
+
+ String factoryClassName = null;
+ try {
+ // XXX Does not handle all possible input as specified by the
+ // Jar Service Provider specification
+ factoryClassName = rd.readLine();
+ rd.close();
+ } catch (IOException x) {
+ // No provider found
+ return null;
+ }
+
+ if (factoryClassName != null &&
+ ! "".equals(factoryClassName)) {
+ debugPrintln("found in resource, value="
+ + factoryClassName);
+
+ // Note: here we do not want to fall back to the current
+ // ClassLoader because we want to avoid the case where the
+ // resource file was found using one ClassLoader and the
+ // provider class was instantiated using a different one.
+ return factoryClassName;
+ }
+
+ // No provider found
+ return null;
+ }
+
+ //
+ // Classes
+ //
+
+ /**
+ * A configuration error.
+ */
+ static class ConfigurationError
+ extends Error {
+
+ //
+ // Data
+ //
+
+ /** Exception. */
+ private Exception exception;
+
+ //
+ // Constructors
+ //
+
+ /**
+ * Construct a new instance with the specified detail string and
+ * exception.
+ */
+ public ConfigurationError(String msg, Exception x) {
+ super(msg);
+ this.exception = x;
+ } // <init>(String,Exception)
+
+ //
+ // Public methods
+ //
+
+ /** Returns the exception associated to this error. */
+ public Exception getException() {
+ return exception;
+ } // getException():Exception
+
+ } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xalan/xsltc/dom/SecuritySupport.java b/src/org/apache/xalan/xsltc/dom/SecuritySupport.java
new file mode 100755
index 0000000..07f3c20
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/dom/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.dom;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+ /*
+ * Make this of type Object so that the verifier won't try to
+ * prove its type, thus possibly trying to load the SecuritySupport12
+ * class.
+ */
+ private static final Object securitySupport;
+
+ static {
+ SecuritySupport ss = null;
+ try {
+ Class c = Class.forName("java.security.AccessController");
+ // if that worked, we're on 1.2.
+ /*
+ // don't reference the class explicitly so it doesn't
+ // get dragged in accidentally.
+ c = Class.forName("javax.mail.SecuritySupport12");
+ Constructor cons = c.getConstructor(new Class[] { });
+ ss = (SecuritySupport)cons.newInstance(new Object[] { });
+ */
+ /*
+ * Unfortunately, we can't load the class using reflection
+ * because the class is package private. And the class has
+ * to be package private so the APIs aren't exposed to other
+ * code that could use them to circumvent security. Thus,
+ * we accept the risk that the direct reference might fail
+ * on some JDK 1.1 JVMs, even though we would never execute
+ * this code in such a case. Sigh...
+ */
+ ss = new SecuritySupport12();
+ } catch (Exception ex) {
+ // ignore it
+ } finally {
+ if (ss == null)
+ ss = new SecuritySupport();
+ securitySupport = ss;
+ }
+ }
+
+ /**
+ * Return an appropriate instance of this class, depending on whether
+ * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+ */
+ static SecuritySupport getInstance() {
+ return (SecuritySupport)securitySupport;
+ }
+
+ ClassLoader getContextClassLoader() {
+ return null;
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return null;
+ }
+
+ ClassLoader getParentClassLoader(ClassLoader cl) {
+ return null;
+ }
+
+ String getSystemProperty(String propName) {
+ return System.getProperty(propName);
+ }
+
+ FileInputStream getFileInputStream(File file)
+ throws FileNotFoundException
+ {
+ return new FileInputStream(file);
+ }
+
+ InputStream getResourceAsStream(ClassLoader cl, String name) {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+
+ boolean getFileExists(File f) {
+ return f.exists();
+ }
+
+ long getLastModified(File f) {
+ return f.lastModified();
+ }
+}
diff --git a/src/org/apache/xalan/xsltc/dom/SecuritySupport12.java b/src/org/apache/xalan/xsltc/dom/SecuritySupport12.java
new file mode 100755
index 0000000..31f37ed
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/dom/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.dom;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+ ClassLoader getContextClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = Thread.currentThread().getContextClassLoader();
+ } catch (SecurityException ex) { }
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = ClassLoader.getSystemClassLoader();
+ } catch (SecurityException ex) {}
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getParentClassLoader(final ClassLoader cl) {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader parent = null;
+ try {
+ parent = cl.getParent();
+ } catch (SecurityException ex) {}
+
+ // eliminate loops in case of the boot
+ // ClassLoader returning itself as a parent
+ return (parent == cl) ? null : parent;
+ }
+ });
+ }
+
+ String getSystemProperty(final String propName) {
+ return (String)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty(propName);
+ }
+ });
+ }
+
+ FileInputStream getFileInputStream(final File file)
+ throws FileNotFoundException
+ {
+ try {
+ return (FileInputStream)
+ AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws FileNotFoundException {
+ return new FileInputStream(file);
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ throw (FileNotFoundException)e.getException();
+ }
+ }
+
+ InputStream getResourceAsStream(final ClassLoader cl,
+ final String name)
+ {
+ return (InputStream)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+ });
+ }
+
+ boolean getFileExists(final File f) {
+ return ((Boolean)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Boolean(f.exists());
+ }
+ })).booleanValue();
+ }
+
+ long getLastModified(final File f) {
+ return ((Long)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Long(f.lastModified());
+ }
+ })).longValue();
+ }
+
+}
diff --git a/src/org/apache/xalan/xsltc/dom/XSLTCDTMManager.java b/src/org/apache/xalan/xsltc/dom/XSLTCDTMManager.java
index ac79ae1..4d4eabb 100644
--- a/src/org/apache/xalan/xsltc/dom/XSLTCDTMManager.java
+++ b/src/org/apache/xalan/xsltc/dom/XSLTCDTMManager.java
@@ -68,7 +68,7 @@
import org.apache.xml.dtm.ref.DTMManagerDefault;
import org.apache.xml.res.XMLErrorResources;
import org.apache.xml.res.XMLMessages;
-import org.apache.xml.utils.ObjectFactory;
+
import org.apache.xml.utils.SystemIDResolver;
import org.apache.xalan.xsltc.trax.DOM2SAX;
diff --git a/src/org/apache/xalan/xsltc/trax/ObjectFactory.java b/src/org/apache/xalan/xsltc/trax/ObjectFactory.java
new file mode 100755
index 0000000..3ceee7b
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/trax/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.trax;
+
+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;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+ //
+ // Constants
+ //
+
+ // name of default properties file to look for in JDK's jre/lib directory
+ private static final String DEFAULT_PROPERTIES_FILENAME =
+ "xalan.properties";
+
+ private static final String SERVICES_PATH = "META-INF/services";
+
+ /** Set to true for debugging */
+ private static final boolean DEBUG = false;
+
+ /** cache the contents of the xalan.properties file.
+ * Until an attempt has been made to read this file, this will
+ * be null; if the file does not exist or we encounter some other error
+ * during the read, this will be empty.
+ */
+ private static Properties fXalanProperties = null;
+
+ /***
+ * Cache the time stamp of the xalan.properties file so
+ * that we know if it's been modified and can invalidate
+ * the cache when necessary.
+ */
+ private static long fLastModified = -1;
+
+ //
+ // Public static methods
+ //
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance 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.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId, String fallbackClassName)
+ throws ConfigurationError {
+ return createObject(factoryId, null, fallbackClassName);
+ } // createObject(String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ Class factoryClass = lookUpFactoryClass(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+
+ if (factoryClass == null) {
+ throw new ConfigurationError(
+ "Provider for " + factoryId + " cannot be found", null);
+ }
+
+ try{
+ Object instance = factoryClass.newInstance();
+ debugPrintln("created new instance of factory " + factoryId);
+ return instance;
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider for factory " + factoryId
+ + " could not be instantiated: " + x, x);
+ }
+ } // createObject(String,String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId)
+ throws ConfigurationError
+ {
+ return lookUpFactoryClass(factoryId, null, null);
+ } // lookUpFactoryClass(String):Class
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ String factoryClassName = lookUpFactoryClassName(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+ ClassLoader cl = findClassLoader();
+
+ if (factoryClassName == null) {
+ factoryClassName = fallbackClassName;
+ }
+
+ // assert(className != null);
+ try{
+ Class providerClass = findProviderClass(factoryClassName,
+ cl,
+ true);
+ debugPrintln("created new instance of " + providerClass +
+ " using ClassLoader: " + cl);
+ return providerClass;
+ } catch (ClassNotFoundException x) {
+ throw new ConfigurationError(
+ "Provider " + factoryClassName + " not found", x);
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider "+factoryClassName+" could not be instantiated: "+x,
+ x);
+ }
+ } // lookUpFactoryClass(String,String,String):Class
+
+ /**
+ * Finds the name of the required implementation class in the specified
+ * order. The specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return name of class that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static String lookUpFactoryClassName(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Use the system property first
+ try {
+ String systemProp = ss.getSystemProperty(factoryId);
+ if (systemProp != null) {
+ debugPrintln("found system property, value=" + systemProp);
+ return systemProp;
+ }
+ } catch (SecurityException se) {
+ // Ignore and continue w/ next location
+ }
+
+ // Try to read from propertiesFilename, or
+ // $java.home/lib/xalan.properties
+ String factoryClassName = null;
+ // no properties file name specified; use
+ // $JAVA_HOME/lib/xalan.properties:
+ if (propertiesFilename == null) {
+ File propertiesFile = null;
+ boolean propertiesFileExists = false;
+ try {
+ String javah = ss.getSystemProperty("java.home");
+ propertiesFilename = javah + File.separator +
+ "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+ propertiesFile = new File(propertiesFilename);
+ propertiesFileExists = ss.getFileExists(propertiesFile);
+ } catch (SecurityException e) {
+ // try again...
+ fLastModified = -1;
+ fXalanProperties = null;
+ }
+
+ synchronized (ObjectFactory.class) {
+ boolean loadProperties = false;
+ try {
+ // file existed last time
+ if(fLastModified >= 0) {
+ if(propertiesFileExists &&
+ (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+ loadProperties = true;
+ } else {
+ // file has stopped existing...
+ if(!propertiesFileExists) {
+ fLastModified = -1;
+ fXalanProperties = null;
+ } // else, file wasn't modified!
+ }
+ } else {
+ // file has started to exist:
+ if(propertiesFileExists) {
+ loadProperties = true;
+ fLastModified = ss.getLastModified(propertiesFile);
+ } // else, nothing's changed
+ }
+ if(loadProperties) {
+ // must never have attempted to read xalan.properties
+ // before (or it's outdeated)
+ fXalanProperties = new Properties();
+ FileInputStream fis =
+ ss.getFileInputStream(propertiesFile);
+ fXalanProperties.load(fis);
+ fis.close();
+ }
+ } catch (Exception x) {
+ fXalanProperties = null;
+ fLastModified = -1;
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if(fXalanProperties != null) {
+ factoryClassName = fXalanProperties.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) {
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if (factoryClassName != null) {
+ debugPrintln("found in " + propertiesFilename + ", value="
+ + factoryClassName);
+ return factoryClassName;
+ }
+
+ // Try Jar Service Provider Mechanism
+ return findJarServiceProviderName(factoryId);
+ } // lookUpFactoryClass(String,String):String
+
+ //
+ // Private static methods
+ //
+
+ /** Prints a message to standard error if debugging is enabled. */
+ private static void debugPrintln(String msg) {
+ if (DEBUG) {
+ System.err.println("JAXP: " + msg);
+ }
+ } // debugPrintln(String)
+
+ /**
+ * Figure out which ClassLoader to use. For JDK 1.2 and later use
+ * the context ClassLoader.
+ */
+ static ClassLoader findClassLoader()
+ throws ConfigurationError
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Figure out which ClassLoader to use for loading the provider
+ // class. If there is a Context ClassLoader then use it.
+ ClassLoader context = ss.getContextClassLoader();
+ ClassLoader system = ss.getSystemClassLoader();
+
+ ClassLoader chain = system;
+ while (true) {
+ if (context == chain) {
+ // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+ // or any Context ClassLoader in chain of system classloader
+ // (including extension ClassLoader) so extend to widest
+ // ClassLoader (always look in system ClassLoader if Xalan
+ // is in boot/extension/system classpath and in current
+ // ClassLoader otherwise); normal classloaders delegate
+ // back to system ClassLoader first so this widening doesn't
+ // change the fact that context ClassLoader will be consulted
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+
+ chain = system;
+ while (true) {
+ if (current == chain) {
+ // Assert: Current ClassLoader in chain of
+ // boot/extension/system ClassLoaders
+ return system;
+ }
+ if (chain == null) {
+ break;
+ }
+ chain = ss.getParentClassLoader(chain);
+ }
+
+ // Assert: Current ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return current;
+ }
+
+ if (chain == null) {
+ // boot ClassLoader reached
+ break;
+ }
+
+ // Check for any extension ClassLoaders in chain up to
+ // boot ClassLoader
+ chain = ss.getParentClassLoader(chain);
+ };
+
+ // Assert: Context ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return context;
+ } // findClassLoader():ClassLoader
+
+ /**
+ * Create an instance of a class using the specified ClassLoader
+ */
+ static Object newInstance(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ConfigurationError
+ {
+ // assert(className != null);
+ 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);
+ }
+ }
+
+ /**
+ * Find a Class using the specified ClassLoader
+ */
+ static Class findProviderClass(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ClassNotFoundException, ConfigurationError
+ {
+
+ SecurityManager security = System.getSecurityManager();
+ try{
+ if (security != null)
+ security.checkPackageAccess(className);
+ }catch(SecurityException e){
+ throw e;
+ }
+
+ Class providerClass;
+ if (cl == null) {
+ // XXX Use the bootstrap ClassLoader. There is no way to
+ // load a class using the bootstrap ClassLoader that works
+ // in both JDK 1.1 and Java 2. However, this should still
+ // work b/c the following should be true:
+ //
+ // (cl == null) iff current ClassLoader == null
+ //
+ // Thus Class.forName(String) will use the current
+ // ClassLoader which will be the bootstrap ClassLoader.
+ providerClass = Class.forName(className);
+ } else {
+ try {
+ providerClass = cl.loadClass(className);
+ } catch (ClassNotFoundException x) {
+ if (doFallback) {
+ // Fall back to current classloader
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (current == null) {
+ providerClass = Class.forName(className);
+ } else if (cl != current) {
+ cl = current;
+ providerClass = cl.loadClass(className);
+ } else {
+ throw x;
+ }
+ } else {
+ throw x;
+ }
+ }
+ }
+
+ return providerClass;
+ }
+
+ /**
+ * Find the name of service provider using Jar Service Provider Mechanism
+ *
+ * @return instance of provider class if found or null
+ */
+ private static String findJarServiceProviderName(String factoryId)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+ String serviceId = SERVICES_PATH + factoryId;
+ InputStream is = null;
+
+ // First try the Context ClassLoader
+ ClassLoader cl = findClassLoader();
+
+ is = ss.getResourceAsStream(cl, serviceId);
+
+ // If no provider found then try the current ClassLoader
+ if (is == null) {
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (cl != current) {
+ cl = current;
+ is = ss.getResourceAsStream(cl, serviceId);
+ }
+ }
+
+ if (is == null) {
+ // No provider found
+ return null;
+ }
+
+ debugPrintln("found jar resource=" + serviceId +
+ " using ClassLoader: " + cl);
+
+ // Read the service provider name in UTF-8 as specified in
+ // the jar spec. Unfortunately this fails in Microsoft
+ // VJ++, which does not implement the UTF-8
+ // encoding. Theoretically, we should simply let it fail in
+ // that case, since the JVM is obviously broken if it
+ // doesn't support such a basic standard. But since there
+ // are still some users attempting to use VJ++ for
+ // development, we have dropped in a fallback which makes a
+ // second attempt using the platform's default encoding. In
+ // VJ++ this is apparently ASCII, which is a subset of
+ // UTF-8... and since the strings we'll be reading here are
+ // also primarily limited to the 7-bit ASCII range (at
+ // least, in English versions), this should work well
+ // enough to keep us on the air until we're ready to
+ // officially decommit from VJ++. [Edited comment from
+ // jkesselm]
+ BufferedReader rd;
+ try {
+ rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ } catch (java.io.UnsupportedEncodingException e) {
+ rd = new BufferedReader(new InputStreamReader(is));
+ }
+
+ String factoryClassName = null;
+ try {
+ // XXX Does not handle all possible input as specified by the
+ // Jar Service Provider specification
+ factoryClassName = rd.readLine();
+ rd.close();
+ } catch (IOException x) {
+ // No provider found
+ return null;
+ }
+
+ if (factoryClassName != null &&
+ ! "".equals(factoryClassName)) {
+ debugPrintln("found in resource, value="
+ + factoryClassName);
+
+ // Note: here we do not want to fall back to the current
+ // ClassLoader because we want to avoid the case where the
+ // resource file was found using one ClassLoader and the
+ // provider class was instantiated using a different one.
+ return factoryClassName;
+ }
+
+ // No provider found
+ return null;
+ }
+
+ //
+ // Classes
+ //
+
+ /**
+ * A configuration error.
+ */
+ static class ConfigurationError
+ extends Error {
+
+ //
+ // Data
+ //
+
+ /** Exception. */
+ private Exception exception;
+
+ //
+ // Constructors
+ //
+
+ /**
+ * Construct a new instance with the specified detail string and
+ * exception.
+ */
+ public ConfigurationError(String msg, Exception x) {
+ super(msg);
+ this.exception = x;
+ } // <init>(String,Exception)
+
+ //
+ // Public methods
+ //
+
+ /** Returns the exception associated to this error. */
+ public Exception getException() {
+ return exception;
+ } // getException():Exception
+
+ } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xalan/xsltc/trax/SecuritySupport.java b/src/org/apache/xalan/xsltc/trax/SecuritySupport.java
new file mode 100755
index 0000000..a1e8f44
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/trax/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.trax;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+ /*
+ * Make this of type Object so that the verifier won't try to
+ * prove its type, thus possibly trying to load the SecuritySupport12
+ * class.
+ */
+ private static final Object securitySupport;
+
+ static {
+ SecuritySupport ss = null;
+ try {
+ Class c = Class.forName("java.security.AccessController");
+ // if that worked, we're on 1.2.
+ /*
+ // don't reference the class explicitly so it doesn't
+ // get dragged in accidentally.
+ c = Class.forName("javax.mail.SecuritySupport12");
+ Constructor cons = c.getConstructor(new Class[] { });
+ ss = (SecuritySupport)cons.newInstance(new Object[] { });
+ */
+ /*
+ * Unfortunately, we can't load the class using reflection
+ * because the class is package private. And the class has
+ * to be package private so the APIs aren't exposed to other
+ * code that could use them to circumvent security. Thus,
+ * we accept the risk that the direct reference might fail
+ * on some JDK 1.1 JVMs, even though we would never execute
+ * this code in such a case. Sigh...
+ */
+ ss = new SecuritySupport12();
+ } catch (Exception ex) {
+ // ignore it
+ } finally {
+ if (ss == null)
+ ss = new SecuritySupport();
+ securitySupport = ss;
+ }
+ }
+
+ /**
+ * Return an appropriate instance of this class, depending on whether
+ * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+ */
+ static SecuritySupport getInstance() {
+ return (SecuritySupport)securitySupport;
+ }
+
+ ClassLoader getContextClassLoader() {
+ return null;
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return null;
+ }
+
+ ClassLoader getParentClassLoader(ClassLoader cl) {
+ return null;
+ }
+
+ String getSystemProperty(String propName) {
+ return System.getProperty(propName);
+ }
+
+ FileInputStream getFileInputStream(File file)
+ throws FileNotFoundException
+ {
+ return new FileInputStream(file);
+ }
+
+ InputStream getResourceAsStream(ClassLoader cl, String name) {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+
+ boolean getFileExists(File f) {
+ return f.exists();
+ }
+
+ long getLastModified(File f) {
+ return f.lastModified();
+ }
+}
diff --git a/src/org/apache/xalan/xsltc/trax/SecuritySupport12.java b/src/org/apache/xalan/xsltc/trax/SecuritySupport12.java
new file mode 100755
index 0000000..c3f00db
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/trax/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.trax;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+ ClassLoader getContextClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = Thread.currentThread().getContextClassLoader();
+ } catch (SecurityException ex) { }
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = ClassLoader.getSystemClassLoader();
+ } catch (SecurityException ex) {}
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getParentClassLoader(final ClassLoader cl) {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader parent = null;
+ try {
+ parent = cl.getParent();
+ } catch (SecurityException ex) {}
+
+ // eliminate loops in case of the boot
+ // ClassLoader returning itself as a parent
+ return (parent == cl) ? null : parent;
+ }
+ });
+ }
+
+ String getSystemProperty(final String propName) {
+ return (String)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty(propName);
+ }
+ });
+ }
+
+ FileInputStream getFileInputStream(final File file)
+ throws FileNotFoundException
+ {
+ try {
+ return (FileInputStream)
+ AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws FileNotFoundException {
+ return new FileInputStream(file);
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ throw (FileNotFoundException)e.getException();
+ }
+ }
+
+ InputStream getResourceAsStream(final ClassLoader cl,
+ final String name)
+ {
+ return (InputStream)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+ });
+ }
+
+ boolean getFileExists(final File f) {
+ return ((Boolean)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Boolean(f.exists());
+ }
+ })).booleanValue();
+ }
+
+ long getLastModified(final File f) {
+ return ((Long)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Long(f.lastModified());
+ }
+ })).longValue();
+ }
+
+}
diff --git a/src/org/apache/xalan/xsltc/trax/SmartTransformerFactoryImpl.java b/src/org/apache/xalan/xsltc/trax/SmartTransformerFactoryImpl.java
index 03976e3..efaf3a6 100644
--- a/src/org/apache/xalan/xsltc/trax/SmartTransformerFactoryImpl.java
+++ b/src/org/apache/xalan/xsltc/trax/SmartTransformerFactoryImpl.java
@@ -80,7 +80,7 @@
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
-import org.apache.xml.utils.ObjectFactory;
+
import org.xml.sax.XMLFilter;
/**
diff --git a/src/org/apache/xalan/xsltc/trax/TemplatesImpl.java b/src/org/apache/xalan/xsltc/trax/TemplatesImpl.java
index 8bfd942..29933e3 100644
--- a/src/org/apache/xalan/xsltc/trax/TemplatesImpl.java
+++ b/src/org/apache/xalan/xsltc/trax/TemplatesImpl.java
@@ -83,7 +83,7 @@
import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
import org.apache.xalan.xsltc.runtime.AbstractTranslet;
import org.apache.xalan.xsltc.runtime.Hashtable;
-import org.apache.xml.utils.ObjectFactory;
+
public final class TemplatesImpl implements Templates, Serializable {
diff --git a/src/org/apache/xalan/xsltc/trax/TransformerFactoryImpl.java b/src/org/apache/xalan/xsltc/trax/TransformerFactoryImpl.java
index 9bceb21..08a84e3 100644
--- a/src/org/apache/xalan/xsltc/trax/TransformerFactoryImpl.java
+++ b/src/org/apache/xalan/xsltc/trax/TransformerFactoryImpl.java
@@ -108,7 +108,7 @@
import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
import org.apache.xalan.xsltc.dom.XSLTCDTMManager;
-import org.apache.xml.utils.ObjectFactory;
+
import org.xml.sax.InputSource;
import org.xml.sax.XMLFilter;
diff --git a/src/org/apache/xml/dtm/DTMManager.java b/src/org/apache/xml/dtm/DTMManager.java
index 0346b34..7cca8c8 100644
--- a/src/org/apache/xml/dtm/DTMManager.java
+++ b/src/org/apache/xml/dtm/DTMManager.java
@@ -58,7 +58,7 @@
import org.apache.xml.res.XMLErrorResources;
import org.apache.xml.res.XMLMessages;
-import org.apache.xml.utils.ObjectFactory;
+
import org.apache.xml.utils.PrefixResolver;
import org.apache.xml.utils.XMLStringFactory;
diff --git a/src/org/apache/xml/dtm/ObjectFactory.java b/src/org/apache/xml/dtm/ObjectFactory.java
new file mode 100755
index 0000000..4610a6e
--- /dev/null
+++ b/src/org/apache/xml/dtm/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xml.dtm;
+
+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;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+ //
+ // Constants
+ //
+
+ // name of default properties file to look for in JDK's jre/lib directory
+ private static final String DEFAULT_PROPERTIES_FILENAME =
+ "xalan.properties";
+
+ private static final String SERVICES_PATH = "META-INF/services";
+
+ /** Set to true for debugging */
+ private static final boolean DEBUG = false;
+
+ /** cache the contents of the xalan.properties file.
+ * Until an attempt has been made to read this file, this will
+ * be null; if the file does not exist or we encounter some other error
+ * during the read, this will be empty.
+ */
+ private static Properties fXalanProperties = null;
+
+ /***
+ * Cache the time stamp of the xalan.properties file so
+ * that we know if it's been modified and can invalidate
+ * the cache when necessary.
+ */
+ private static long fLastModified = -1;
+
+ //
+ // Public static methods
+ //
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance 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.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId, String fallbackClassName)
+ throws ConfigurationError {
+ return createObject(factoryId, null, fallbackClassName);
+ } // createObject(String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ Class factoryClass = lookUpFactoryClass(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+
+ if (factoryClass == null) {
+ throw new ConfigurationError(
+ "Provider for " + factoryId + " cannot be found", null);
+ }
+
+ try{
+ Object instance = factoryClass.newInstance();
+ debugPrintln("created new instance of factory " + factoryId);
+ return instance;
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider for factory " + factoryId
+ + " could not be instantiated: " + x, x);
+ }
+ } // createObject(String,String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId)
+ throws ConfigurationError
+ {
+ return lookUpFactoryClass(factoryId, null, null);
+ } // lookUpFactoryClass(String):Class
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ String factoryClassName = lookUpFactoryClassName(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+ ClassLoader cl = findClassLoader();
+
+ if (factoryClassName == null) {
+ factoryClassName = fallbackClassName;
+ }
+
+ // assert(className != null);
+ try{
+ Class providerClass = findProviderClass(factoryClassName,
+ cl,
+ true);
+ debugPrintln("created new instance of " + providerClass +
+ " using ClassLoader: " + cl);
+ return providerClass;
+ } catch (ClassNotFoundException x) {
+ throw new ConfigurationError(
+ "Provider " + factoryClassName + " not found", x);
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider "+factoryClassName+" could not be instantiated: "+x,
+ x);
+ }
+ } // lookUpFactoryClass(String,String,String):Class
+
+ /**
+ * Finds the name of the required implementation class in the specified
+ * order. The specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return name of class that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static String lookUpFactoryClassName(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Use the system property first
+ try {
+ String systemProp = ss.getSystemProperty(factoryId);
+ if (systemProp != null) {
+ debugPrintln("found system property, value=" + systemProp);
+ return systemProp;
+ }
+ } catch (SecurityException se) {
+ // Ignore and continue w/ next location
+ }
+
+ // Try to read from propertiesFilename, or
+ // $java.home/lib/xalan.properties
+ String factoryClassName = null;
+ // no properties file name specified; use
+ // $JAVA_HOME/lib/xalan.properties:
+ if (propertiesFilename == null) {
+ File propertiesFile = null;
+ boolean propertiesFileExists = false;
+ try {
+ String javah = ss.getSystemProperty("java.home");
+ propertiesFilename = javah + File.separator +
+ "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+ propertiesFile = new File(propertiesFilename);
+ propertiesFileExists = ss.getFileExists(propertiesFile);
+ } catch (SecurityException e) {
+ // try again...
+ fLastModified = -1;
+ fXalanProperties = null;
+ }
+
+ synchronized (ObjectFactory.class) {
+ boolean loadProperties = false;
+ try {
+ // file existed last time
+ if(fLastModified >= 0) {
+ if(propertiesFileExists &&
+ (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+ loadProperties = true;
+ } else {
+ // file has stopped existing...
+ if(!propertiesFileExists) {
+ fLastModified = -1;
+ fXalanProperties = null;
+ } // else, file wasn't modified!
+ }
+ } else {
+ // file has started to exist:
+ if(propertiesFileExists) {
+ loadProperties = true;
+ fLastModified = ss.getLastModified(propertiesFile);
+ } // else, nothing's changed
+ }
+ if(loadProperties) {
+ // must never have attempted to read xalan.properties
+ // before (or it's outdeated)
+ fXalanProperties = new Properties();
+ FileInputStream fis =
+ ss.getFileInputStream(propertiesFile);
+ fXalanProperties.load(fis);
+ fis.close();
+ }
+ } catch (Exception x) {
+ fXalanProperties = null;
+ fLastModified = -1;
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if(fXalanProperties != null) {
+ factoryClassName = fXalanProperties.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) {
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if (factoryClassName != null) {
+ debugPrintln("found in " + propertiesFilename + ", value="
+ + factoryClassName);
+ return factoryClassName;
+ }
+
+ // Try Jar Service Provider Mechanism
+ return findJarServiceProviderName(factoryId);
+ } // lookUpFactoryClass(String,String):String
+
+ //
+ // Private static methods
+ //
+
+ /** Prints a message to standard error if debugging is enabled. */
+ private static void debugPrintln(String msg) {
+ if (DEBUG) {
+ System.err.println("JAXP: " + msg);
+ }
+ } // debugPrintln(String)
+
+ /**
+ * Figure out which ClassLoader to use. For JDK 1.2 and later use
+ * the context ClassLoader.
+ */
+ static ClassLoader findClassLoader()
+ throws ConfigurationError
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Figure out which ClassLoader to use for loading the provider
+ // class. If there is a Context ClassLoader then use it.
+ ClassLoader context = ss.getContextClassLoader();
+ ClassLoader system = ss.getSystemClassLoader();
+
+ ClassLoader chain = system;
+ while (true) {
+ if (context == chain) {
+ // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+ // or any Context ClassLoader in chain of system classloader
+ // (including extension ClassLoader) so extend to widest
+ // ClassLoader (always look in system ClassLoader if Xalan
+ // is in boot/extension/system classpath and in current
+ // ClassLoader otherwise); normal classloaders delegate
+ // back to system ClassLoader first so this widening doesn't
+ // change the fact that context ClassLoader will be consulted
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+
+ chain = system;
+ while (true) {
+ if (current == chain) {
+ // Assert: Current ClassLoader in chain of
+ // boot/extension/system ClassLoaders
+ return system;
+ }
+ if (chain == null) {
+ break;
+ }
+ chain = ss.getParentClassLoader(chain);
+ }
+
+ // Assert: Current ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return current;
+ }
+
+ if (chain == null) {
+ // boot ClassLoader reached
+ break;
+ }
+
+ // Check for any extension ClassLoaders in chain up to
+ // boot ClassLoader
+ chain = ss.getParentClassLoader(chain);
+ };
+
+ // Assert: Context ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return context;
+ } // findClassLoader():ClassLoader
+
+ /**
+ * Create an instance of a class using the specified ClassLoader
+ */
+ static Object newInstance(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ConfigurationError
+ {
+ // assert(className != null);
+ 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);
+ }
+ }
+
+ /**
+ * Find a Class using the specified ClassLoader
+ */
+ static Class findProviderClass(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ClassNotFoundException, ConfigurationError
+ {
+
+ SecurityManager security = System.getSecurityManager();
+ try{
+ if (security != null)
+ security.checkPackageAccess(className);
+ }catch(SecurityException e){
+ throw e;
+ }
+
+ Class providerClass;
+ if (cl == null) {
+ // XXX Use the bootstrap ClassLoader. There is no way to
+ // load a class using the bootstrap ClassLoader that works
+ // in both JDK 1.1 and Java 2. However, this should still
+ // work b/c the following should be true:
+ //
+ // (cl == null) iff current ClassLoader == null
+ //
+ // Thus Class.forName(String) will use the current
+ // ClassLoader which will be the bootstrap ClassLoader.
+ providerClass = Class.forName(className);
+ } else {
+ try {
+ providerClass = cl.loadClass(className);
+ } catch (ClassNotFoundException x) {
+ if (doFallback) {
+ // Fall back to current classloader
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (current == null) {
+ providerClass = Class.forName(className);
+ } else if (cl != current) {
+ cl = current;
+ providerClass = cl.loadClass(className);
+ } else {
+ throw x;
+ }
+ } else {
+ throw x;
+ }
+ }
+ }
+
+ return providerClass;
+ }
+
+ /**
+ * Find the name of service provider using Jar Service Provider Mechanism
+ *
+ * @return instance of provider class if found or null
+ */
+ private static String findJarServiceProviderName(String factoryId)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+ String serviceId = SERVICES_PATH + factoryId;
+ InputStream is = null;
+
+ // First try the Context ClassLoader
+ ClassLoader cl = findClassLoader();
+
+ is = ss.getResourceAsStream(cl, serviceId);
+
+ // If no provider found then try the current ClassLoader
+ if (is == null) {
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (cl != current) {
+ cl = current;
+ is = ss.getResourceAsStream(cl, serviceId);
+ }
+ }
+
+ if (is == null) {
+ // No provider found
+ return null;
+ }
+
+ debugPrintln("found jar resource=" + serviceId +
+ " using ClassLoader: " + cl);
+
+ // Read the service provider name in UTF-8 as specified in
+ // the jar spec. Unfortunately this fails in Microsoft
+ // VJ++, which does not implement the UTF-8
+ // encoding. Theoretically, we should simply let it fail in
+ // that case, since the JVM is obviously broken if it
+ // doesn't support such a basic standard. But since there
+ // are still some users attempting to use VJ++ for
+ // development, we have dropped in a fallback which makes a
+ // second attempt using the platform's default encoding. In
+ // VJ++ this is apparently ASCII, which is a subset of
+ // UTF-8... and since the strings we'll be reading here are
+ // also primarily limited to the 7-bit ASCII range (at
+ // least, in English versions), this should work well
+ // enough to keep us on the air until we're ready to
+ // officially decommit from VJ++. [Edited comment from
+ // jkesselm]
+ BufferedReader rd;
+ try {
+ rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ } catch (java.io.UnsupportedEncodingException e) {
+ rd = new BufferedReader(new InputStreamReader(is));
+ }
+
+ String factoryClassName = null;
+ try {
+ // XXX Does not handle all possible input as specified by the
+ // Jar Service Provider specification
+ factoryClassName = rd.readLine();
+ rd.close();
+ } catch (IOException x) {
+ // No provider found
+ return null;
+ }
+
+ if (factoryClassName != null &&
+ ! "".equals(factoryClassName)) {
+ debugPrintln("found in resource, value="
+ + factoryClassName);
+
+ // Note: here we do not want to fall back to the current
+ // ClassLoader because we want to avoid the case where the
+ // resource file was found using one ClassLoader and the
+ // provider class was instantiated using a different one.
+ return factoryClassName;
+ }
+
+ // No provider found
+ return null;
+ }
+
+ //
+ // Classes
+ //
+
+ /**
+ * A configuration error.
+ */
+ static class ConfigurationError
+ extends Error {
+
+ //
+ // Data
+ //
+
+ /** Exception. */
+ private Exception exception;
+
+ //
+ // Constructors
+ //
+
+ /**
+ * Construct a new instance with the specified detail string and
+ * exception.
+ */
+ public ConfigurationError(String msg, Exception x) {
+ super(msg);
+ this.exception = x;
+ } // <init>(String,Exception)
+
+ //
+ // Public methods
+ //
+
+ /** Returns the exception associated to this error. */
+ public Exception getException() {
+ return exception;
+ } // getException():Exception
+
+ } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xml/dtm/SecuritySupport.java b/src/org/apache/xml/dtm/SecuritySupport.java
new file mode 100644
index 0000000..1dc4827
--- /dev/null
+++ b/src/org/apache/xml/dtm/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xml.dtm;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+ /*
+ * Make this of type Object so that the verifier won't try to
+ * prove its type, thus possibly trying to load the SecuritySupport12
+ * class.
+ */
+ private static final Object securitySupport;
+
+ static {
+ SecuritySupport ss = null;
+ try {
+ Class c = Class.forName("java.security.AccessController");
+ // if that worked, we're on 1.2.
+ /*
+ // don't reference the class explicitly so it doesn't
+ // get dragged in accidentally.
+ c = Class.forName("javax.mail.SecuritySupport12");
+ Constructor cons = c.getConstructor(new Class[] { });
+ ss = (SecuritySupport)cons.newInstance(new Object[] { });
+ */
+ /*
+ * Unfortunately, we can't load the class using reflection
+ * because the class is package private. And the class has
+ * to be package private so the APIs aren't exposed to other
+ * code that could use them to circumvent security. Thus,
+ * we accept the risk that the direct reference might fail
+ * on some JDK 1.1 JVMs, even though we would never execute
+ * this code in such a case. Sigh...
+ */
+ ss = new SecuritySupport12();
+ } catch (Exception ex) {
+ // ignore it
+ } finally {
+ if (ss == null)
+ ss = new SecuritySupport();
+ securitySupport = ss;
+ }
+ }
+
+ /**
+ * Return an appropriate instance of this class, depending on whether
+ * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+ */
+ static SecuritySupport getInstance() {
+ return (SecuritySupport)securitySupport;
+ }
+
+ ClassLoader getContextClassLoader() {
+ return null;
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return null;
+ }
+
+ ClassLoader getParentClassLoader(ClassLoader cl) {
+ return null;
+ }
+
+ String getSystemProperty(String propName) {
+ return System.getProperty(propName);
+ }
+
+ FileInputStream getFileInputStream(File file)
+ throws FileNotFoundException
+ {
+ return new FileInputStream(file);
+ }
+
+ InputStream getResourceAsStream(ClassLoader cl, String name) {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+
+ boolean getFileExists(File f) {
+ return f.exists();
+ }
+
+ long getLastModified(File f) {
+ return f.lastModified();
+ }
+}
diff --git a/src/org/apache/xml/dtm/SecuritySupport12.java b/src/org/apache/xml/dtm/SecuritySupport12.java
new file mode 100644
index 0000000..6b305ac
--- /dev/null
+++ b/src/org/apache/xml/dtm/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xml.dtm;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+ ClassLoader getContextClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = Thread.currentThread().getContextClassLoader();
+ } catch (SecurityException ex) { }
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = ClassLoader.getSystemClassLoader();
+ } catch (SecurityException ex) {}
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getParentClassLoader(final ClassLoader cl) {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader parent = null;
+ try {
+ parent = cl.getParent();
+ } catch (SecurityException ex) {}
+
+ // eliminate loops in case of the boot
+ // ClassLoader returning itself as a parent
+ return (parent == cl) ? null : parent;
+ }
+ });
+ }
+
+ String getSystemProperty(final String propName) {
+ return (String)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty(propName);
+ }
+ });
+ }
+
+ FileInputStream getFileInputStream(final File file)
+ throws FileNotFoundException
+ {
+ try {
+ return (FileInputStream)
+ AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws FileNotFoundException {
+ return new FileInputStream(file);
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ throw (FileNotFoundException)e.getException();
+ }
+ }
+
+ InputStream getResourceAsStream(final ClassLoader cl,
+ final String name)
+ {
+ return (InputStream)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+ });
+ }
+
+ boolean getFileExists(final File f) {
+ return ((Boolean)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Boolean(f.exists());
+ }
+ })).booleanValue();
+ }
+
+ long getLastModified(final File f) {
+ return ((Long)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Long(f.lastModified());
+ }
+ })).longValue();
+ }
+
+}
diff --git a/src/org/apache/xml/dtm/ref/IncrementalSAXSource_Xerces.java b/src/org/apache/xml/dtm/ref/IncrementalSAXSource_Xerces.java
index 7674268..8eaa137 100644
--- a/src/org/apache/xml/dtm/ref/IncrementalSAXSource_Xerces.java
+++ b/src/org/apache/xml/dtm/ref/IncrementalSAXSource_Xerces.java
@@ -64,7 +64,7 @@
import org.apache.xerces.parsers.SAXParser;
import org.apache.xml.res.XMLErrorResources;
import org.apache.xml.res.XMLMessages;
-import org.apache.xml.utils.ObjectFactory;
+
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
diff --git a/src/org/apache/xml/dtm/ref/ObjectFactory.java b/src/org/apache/xml/dtm/ref/ObjectFactory.java
new file mode 100755
index 0000000..8fb66f9
--- /dev/null
+++ b/src/org/apache/xml/dtm/ref/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xml.dtm.ref;
+
+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;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+ //
+ // Constants
+ //
+
+ // name of default properties file to look for in JDK's jre/lib directory
+ private static final String DEFAULT_PROPERTIES_FILENAME =
+ "xalan.properties";
+
+ private static final String SERVICES_PATH = "META-INF/services";
+
+ /** Set to true for debugging */
+ private static final boolean DEBUG = false;
+
+ /** cache the contents of the xalan.properties file.
+ * Until an attempt has been made to read this file, this will
+ * be null; if the file does not exist or we encounter some other error
+ * during the read, this will be empty.
+ */
+ private static Properties fXalanProperties = null;
+
+ /***
+ * Cache the time stamp of the xalan.properties file so
+ * that we know if it's been modified and can invalidate
+ * the cache when necessary.
+ */
+ private static long fLastModified = -1;
+
+ //
+ // Public static methods
+ //
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance 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.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId, String fallbackClassName)
+ throws ConfigurationError {
+ return createObject(factoryId, null, fallbackClassName);
+ } // createObject(String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ Class factoryClass = lookUpFactoryClass(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+
+ if (factoryClass == null) {
+ throw new ConfigurationError(
+ "Provider for " + factoryId + " cannot be found", null);
+ }
+
+ try{
+ Object instance = factoryClass.newInstance();
+ debugPrintln("created new instance of factory " + factoryId);
+ return instance;
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider for factory " + factoryId
+ + " could not be instantiated: " + x, x);
+ }
+ } // createObject(String,String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId)
+ throws ConfigurationError
+ {
+ return lookUpFactoryClass(factoryId, null, null);
+ } // lookUpFactoryClass(String):Class
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ String factoryClassName = lookUpFactoryClassName(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+ ClassLoader cl = findClassLoader();
+
+ if (factoryClassName == null) {
+ factoryClassName = fallbackClassName;
+ }
+
+ // assert(className != null);
+ try{
+ Class providerClass = findProviderClass(factoryClassName,
+ cl,
+ true);
+ debugPrintln("created new instance of " + providerClass +
+ " using ClassLoader: " + cl);
+ return providerClass;
+ } catch (ClassNotFoundException x) {
+ throw new ConfigurationError(
+ "Provider " + factoryClassName + " not found", x);
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider "+factoryClassName+" could not be instantiated: "+x,
+ x);
+ }
+ } // lookUpFactoryClass(String,String,String):Class
+
+ /**
+ * Finds the name of the required implementation class in the specified
+ * order. The specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return name of class that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static String lookUpFactoryClassName(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Use the system property first
+ try {
+ String systemProp = ss.getSystemProperty(factoryId);
+ if (systemProp != null) {
+ debugPrintln("found system property, value=" + systemProp);
+ return systemProp;
+ }
+ } catch (SecurityException se) {
+ // Ignore and continue w/ next location
+ }
+
+ // Try to read from propertiesFilename, or
+ // $java.home/lib/xalan.properties
+ String factoryClassName = null;
+ // no properties file name specified; use
+ // $JAVA_HOME/lib/xalan.properties:
+ if (propertiesFilename == null) {
+ File propertiesFile = null;
+ boolean propertiesFileExists = false;
+ try {
+ String javah = ss.getSystemProperty("java.home");
+ propertiesFilename = javah + File.separator +
+ "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+ propertiesFile = new File(propertiesFilename);
+ propertiesFileExists = ss.getFileExists(propertiesFile);
+ } catch (SecurityException e) {
+ // try again...
+ fLastModified = -1;
+ fXalanProperties = null;
+ }
+
+ synchronized (ObjectFactory.class) {
+ boolean loadProperties = false;
+ try {
+ // file existed last time
+ if(fLastModified >= 0) {
+ if(propertiesFileExists &&
+ (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+ loadProperties = true;
+ } else {
+ // file has stopped existing...
+ if(!propertiesFileExists) {
+ fLastModified = -1;
+ fXalanProperties = null;
+ } // else, file wasn't modified!
+ }
+ } else {
+ // file has started to exist:
+ if(propertiesFileExists) {
+ loadProperties = true;
+ fLastModified = ss.getLastModified(propertiesFile);
+ } // else, nothing's changed
+ }
+ if(loadProperties) {
+ // must never have attempted to read xalan.properties
+ // before (or it's outdeated)
+ fXalanProperties = new Properties();
+ FileInputStream fis =
+ ss.getFileInputStream(propertiesFile);
+ fXalanProperties.load(fis);
+ fis.close();
+ }
+ } catch (Exception x) {
+ fXalanProperties = null;
+ fLastModified = -1;
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if(fXalanProperties != null) {
+ factoryClassName = fXalanProperties.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) {
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if (factoryClassName != null) {
+ debugPrintln("found in " + propertiesFilename + ", value="
+ + factoryClassName);
+ return factoryClassName;
+ }
+
+ // Try Jar Service Provider Mechanism
+ return findJarServiceProviderName(factoryId);
+ } // lookUpFactoryClass(String,String):String
+
+ //
+ // Private static methods
+ //
+
+ /** Prints a message to standard error if debugging is enabled. */
+ private static void debugPrintln(String msg) {
+ if (DEBUG) {
+ System.err.println("JAXP: " + msg);
+ }
+ } // debugPrintln(String)
+
+ /**
+ * Figure out which ClassLoader to use. For JDK 1.2 and later use
+ * the context ClassLoader.
+ */
+ static ClassLoader findClassLoader()
+ throws ConfigurationError
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Figure out which ClassLoader to use for loading the provider
+ // class. If there is a Context ClassLoader then use it.
+ ClassLoader context = ss.getContextClassLoader();
+ ClassLoader system = ss.getSystemClassLoader();
+
+ ClassLoader chain = system;
+ while (true) {
+ if (context == chain) {
+ // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+ // or any Context ClassLoader in chain of system classloader
+ // (including extension ClassLoader) so extend to widest
+ // ClassLoader (always look in system ClassLoader if Xalan
+ // is in boot/extension/system classpath and in current
+ // ClassLoader otherwise); normal classloaders delegate
+ // back to system ClassLoader first so this widening doesn't
+ // change the fact that context ClassLoader will be consulted
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+
+ chain = system;
+ while (true) {
+ if (current == chain) {
+ // Assert: Current ClassLoader in chain of
+ // boot/extension/system ClassLoaders
+ return system;
+ }
+ if (chain == null) {
+ break;
+ }
+ chain = ss.getParentClassLoader(chain);
+ }
+
+ // Assert: Current ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return current;
+ }
+
+ if (chain == null) {
+ // boot ClassLoader reached
+ break;
+ }
+
+ // Check for any extension ClassLoaders in chain up to
+ // boot ClassLoader
+ chain = ss.getParentClassLoader(chain);
+ };
+
+ // Assert: Context ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return context;
+ } // findClassLoader():ClassLoader
+
+ /**
+ * Create an instance of a class using the specified ClassLoader
+ */
+ static Object newInstance(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ConfigurationError
+ {
+ // assert(className != null);
+ 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);
+ }
+ }
+
+ /**
+ * Find a Class using the specified ClassLoader
+ */
+ static Class findProviderClass(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ClassNotFoundException, ConfigurationError
+ {
+
+ SecurityManager security = System.getSecurityManager();
+ try{
+ if (security != null)
+ security.checkPackageAccess(className);
+ }catch(SecurityException e){
+ throw e;
+ }
+
+ Class providerClass;
+ if (cl == null) {
+ // XXX Use the bootstrap ClassLoader. There is no way to
+ // load a class using the bootstrap ClassLoader that works
+ // in both JDK 1.1 and Java 2. However, this should still
+ // work b/c the following should be true:
+ //
+ // (cl == null) iff current ClassLoader == null
+ //
+ // Thus Class.forName(String) will use the current
+ // ClassLoader which will be the bootstrap ClassLoader.
+ providerClass = Class.forName(className);
+ } else {
+ try {
+ providerClass = cl.loadClass(className);
+ } catch (ClassNotFoundException x) {
+ if (doFallback) {
+ // Fall back to current classloader
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (current == null) {
+ providerClass = Class.forName(className);
+ } else if (cl != current) {
+ cl = current;
+ providerClass = cl.loadClass(className);
+ } else {
+ throw x;
+ }
+ } else {
+ throw x;
+ }
+ }
+ }
+
+ return providerClass;
+ }
+
+ /**
+ * Find the name of service provider using Jar Service Provider Mechanism
+ *
+ * @return instance of provider class if found or null
+ */
+ private static String findJarServiceProviderName(String factoryId)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+ String serviceId = SERVICES_PATH + factoryId;
+ InputStream is = null;
+
+ // First try the Context ClassLoader
+ ClassLoader cl = findClassLoader();
+
+ is = ss.getResourceAsStream(cl, serviceId);
+
+ // If no provider found then try the current ClassLoader
+ if (is == null) {
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (cl != current) {
+ cl = current;
+ is = ss.getResourceAsStream(cl, serviceId);
+ }
+ }
+
+ if (is == null) {
+ // No provider found
+ return null;
+ }
+
+ debugPrintln("found jar resource=" + serviceId +
+ " using ClassLoader: " + cl);
+
+ // Read the service provider name in UTF-8 as specified in
+ // the jar spec. Unfortunately this fails in Microsoft
+ // VJ++, which does not implement the UTF-8
+ // encoding. Theoretically, we should simply let it fail in
+ // that case, since the JVM is obviously broken if it
+ // doesn't support such a basic standard. But since there
+ // are still some users attempting to use VJ++ for
+ // development, we have dropped in a fallback which makes a
+ // second attempt using the platform's default encoding. In
+ // VJ++ this is apparently ASCII, which is a subset of
+ // UTF-8... and since the strings we'll be reading here are
+ // also primarily limited to the 7-bit ASCII range (at
+ // least, in English versions), this should work well
+ // enough to keep us on the air until we're ready to
+ // officially decommit from VJ++. [Edited comment from
+ // jkesselm]
+ BufferedReader rd;
+ try {
+ rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ } catch (java.io.UnsupportedEncodingException e) {
+ rd = new BufferedReader(new InputStreamReader(is));
+ }
+
+ String factoryClassName = null;
+ try {
+ // XXX Does not handle all possible input as specified by the
+ // Jar Service Provider specification
+ factoryClassName = rd.readLine();
+ rd.close();
+ } catch (IOException x) {
+ // No provider found
+ return null;
+ }
+
+ if (factoryClassName != null &&
+ ! "".equals(factoryClassName)) {
+ debugPrintln("found in resource, value="
+ + factoryClassName);
+
+ // Note: here we do not want to fall back to the current
+ // ClassLoader because we want to avoid the case where the
+ // resource file was found using one ClassLoader and the
+ // provider class was instantiated using a different one.
+ return factoryClassName;
+ }
+
+ // No provider found
+ return null;
+ }
+
+ //
+ // Classes
+ //
+
+ /**
+ * A configuration error.
+ */
+ static class ConfigurationError
+ extends Error {
+
+ //
+ // Data
+ //
+
+ /** Exception. */
+ private Exception exception;
+
+ //
+ // Constructors
+ //
+
+ /**
+ * Construct a new instance with the specified detail string and
+ * exception.
+ */
+ public ConfigurationError(String msg, Exception x) {
+ super(msg);
+ this.exception = x;
+ } // <init>(String,Exception)
+
+ //
+ // Public methods
+ //
+
+ /** Returns the exception associated to this error. */
+ public Exception getException() {
+ return exception;
+ } // getException():Exception
+
+ } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xml/dtm/ref/SecuritySupport.java b/src/org/apache/xml/dtm/ref/SecuritySupport.java
new file mode 100755
index 0000000..38eb82a
--- /dev/null
+++ b/src/org/apache/xml/dtm/ref/SecuritySupport.java
@@ -0,0 +1,160 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xml.dtm.ref;
+
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+ /*
+ * Make this of type Object so that the verifier won't try to
+ * prove its type, thus possibly trying to load the SecuritySupport12
+ * class.
+ */
+ private static final Object securitySupport;
+
+ static {
+ SecuritySupport ss = null;
+ try {
+ Class c = Class.forName("java.security.AccessController");
+ // if that worked, we're on 1.2.
+ /*
+ // don't reference the class explicitly so it doesn't
+ // get dragged in accidentally.
+ c = Class.forName("javax.mail.SecuritySupport12");
+ Constructor cons = c.getConstructor(new Class[] { });
+ ss = (SecuritySupport)cons.newInstance(new Object[] { });
+ */
+ /*
+ * Unfortunately, we can't load the class using reflection
+ * because the class is package private. And the class has
+ * to be package private so the APIs aren't exposed to other
+ * code that could use them to circumvent security. Thus,
+ * we accept the risk that the direct reference might fail
+ * on some JDK 1.1 JVMs, even though we would never execute
+ * this code in such a case. Sigh...
+ */
+ ss = new SecuritySupport12();
+ } catch (Exception ex) {
+ // ignore it
+ } finally {
+ if (ss == null)
+ ss = new SecuritySupport();
+ securitySupport = ss;
+ }
+ }
+
+ /**
+ * Return an appropriate instance of this class, depending on whether
+ * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+ */
+ static SecuritySupport getInstance() {
+ return (SecuritySupport)securitySupport;
+ }
+
+ ClassLoader getContextClassLoader() {
+ return null;
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return null;
+ }
+
+ ClassLoader getParentClassLoader(ClassLoader cl) {
+ return null;
+ }
+
+ String getSystemProperty(String propName) {
+ return System.getProperty(propName);
+ }
+
+ FileInputStream getFileInputStream(File file)
+ throws FileNotFoundException
+ {
+ return new FileInputStream(file);
+ }
+
+ InputStream getResourceAsStream(ClassLoader cl, String name) {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+
+ boolean getFileExists(File f) {
+ return f.exists();
+ }
+
+ long getLastModified(File f) {
+ return f.lastModified();
+ }
+}
diff --git a/src/org/apache/xml/dtm/ref/SecuritySupport12.java b/src/org/apache/xml/dtm/ref/SecuritySupport12.java
new file mode 100755
index 0000000..72534d3
--- /dev/null
+++ b/src/org/apache/xml/dtm/ref/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xml.dtm.ref;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+ ClassLoader getContextClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = Thread.currentThread().getContextClassLoader();
+ } catch (SecurityException ex) { }
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = ClassLoader.getSystemClassLoader();
+ } catch (SecurityException ex) {}
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getParentClassLoader(final ClassLoader cl) {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader parent = null;
+ try {
+ parent = cl.getParent();
+ } catch (SecurityException ex) {}
+
+ // eliminate loops in case of the boot
+ // ClassLoader returning itself as a parent
+ return (parent == cl) ? null : parent;
+ }
+ });
+ }
+
+ String getSystemProperty(final String propName) {
+ return (String)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty(propName);
+ }
+ });
+ }
+
+ FileInputStream getFileInputStream(final File file)
+ throws FileNotFoundException
+ {
+ try {
+ return (FileInputStream)
+ AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws FileNotFoundException {
+ return new FileInputStream(file);
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ throw (FileNotFoundException)e.getException();
+ }
+ }
+
+ InputStream getResourceAsStream(final ClassLoader cl,
+ final String name)
+ {
+ return (InputStream)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+ });
+ }
+
+ boolean getFileExists(final File f) {
+ return ((Boolean)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Boolean(f.exists());
+ }
+ })).booleanValue();
+ }
+
+ long getLastModified(final File f) {
+ return ((Long)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Long(f.lastModified());
+ }
+ })).longValue();
+ }
+
+}
diff --git a/src/org/apache/xml/serializer/CharInfo.java b/src/org/apache/xml/serializer/CharInfo.java
index 3aa68fa..9e70679 100644
--- a/src/org/apache/xml/serializer/CharInfo.java
+++ b/src/org/apache/xml/serializer/CharInfo.java
@@ -71,7 +71,7 @@
import org.apache.xml.res.XMLErrorResources;
import org.apache.xml.res.XMLMessages;
import org.apache.xml.utils.CharKey;
-import org.apache.xml.utils.ObjectFactory;
+
import org.apache.xml.utils.SystemIDResolver;
import org.apache.xml.utils.WrappedRuntimeException;
diff --git a/src/org/apache/xml/serializer/Encodings.java b/src/org/apache/xml/serializer/Encodings.java
index 6f36b22..d7da8e7 100644
--- a/src/org/apache/xml/serializer/Encodings.java
+++ b/src/org/apache/xml/serializer/Encodings.java
@@ -70,7 +70,7 @@
import java.security.PrivilegedAction;
import java.security.AccessController;
-import org.apache.xml.utils.ObjectFactory;
+
/**
* Provides information about encodings. Depends on the Java runtime
diff --git a/src/org/apache/xml/serializer/ObjectFactory.java b/src/org/apache/xml/serializer/ObjectFactory.java
new file mode 100755
index 0000000..2c79ad4
--- /dev/null
+++ b/src/org/apache/xml/serializer/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xml.serializer;
+
+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;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+ //
+ // Constants
+ //
+
+ // name of default properties file to look for in JDK's jre/lib directory
+ private static final String DEFAULT_PROPERTIES_FILENAME =
+ "xalan.properties";
+
+ private static final String SERVICES_PATH = "META-INF/services";
+
+ /** Set to true for debugging */
+ private static final boolean DEBUG = false;
+
+ /** cache the contents of the xalan.properties file.
+ * Until an attempt has been made to read this file, this will
+ * be null; if the file does not exist or we encounter some other error
+ * during the read, this will be empty.
+ */
+ private static Properties fXalanProperties = null;
+
+ /***
+ * Cache the time stamp of the xalan.properties file so
+ * that we know if it's been modified and can invalidate
+ * the cache when necessary.
+ */
+ private static long fLastModified = -1;
+
+ //
+ // Public static methods
+ //
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance 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.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId, String fallbackClassName)
+ throws ConfigurationError {
+ return createObject(factoryId, null, fallbackClassName);
+ } // createObject(String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ Class factoryClass = lookUpFactoryClass(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+
+ if (factoryClass == null) {
+ throw new ConfigurationError(
+ "Provider for " + factoryId + " cannot be found", null);
+ }
+
+ try{
+ Object instance = factoryClass.newInstance();
+ debugPrintln("created new instance of factory " + factoryId);
+ return instance;
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider for factory " + factoryId
+ + " could not be instantiated: " + x, x);
+ }
+ } // createObject(String,String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId)
+ throws ConfigurationError
+ {
+ return lookUpFactoryClass(factoryId, null, null);
+ } // lookUpFactoryClass(String):Class
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ String factoryClassName = lookUpFactoryClassName(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+ ClassLoader cl = findClassLoader();
+
+ if (factoryClassName == null) {
+ factoryClassName = fallbackClassName;
+ }
+
+ // assert(className != null);
+ try{
+ Class providerClass = findProviderClass(factoryClassName,
+ cl,
+ true);
+ debugPrintln("created new instance of " + providerClass +
+ " using ClassLoader: " + cl);
+ return providerClass;
+ } catch (ClassNotFoundException x) {
+ throw new ConfigurationError(
+ "Provider " + factoryClassName + " not found", x);
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider "+factoryClassName+" could not be instantiated: "+x,
+ x);
+ }
+ } // lookUpFactoryClass(String,String,String):Class
+
+ /**
+ * Finds the name of the required implementation class in the specified
+ * order. The specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return name of class that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static String lookUpFactoryClassName(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Use the system property first
+ try {
+ String systemProp = ss.getSystemProperty(factoryId);
+ if (systemProp != null) {
+ debugPrintln("found system property, value=" + systemProp);
+ return systemProp;
+ }
+ } catch (SecurityException se) {
+ // Ignore and continue w/ next location
+ }
+
+ // Try to read from propertiesFilename, or
+ // $java.home/lib/xalan.properties
+ String factoryClassName = null;
+ // no properties file name specified; use
+ // $JAVA_HOME/lib/xalan.properties:
+ if (propertiesFilename == null) {
+ File propertiesFile = null;
+ boolean propertiesFileExists = false;
+ try {
+ String javah = ss.getSystemProperty("java.home");
+ propertiesFilename = javah + File.separator +
+ "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+ propertiesFile = new File(propertiesFilename);
+ propertiesFileExists = ss.getFileExists(propertiesFile);
+ } catch (SecurityException e) {
+ // try again...
+ fLastModified = -1;
+ fXalanProperties = null;
+ }
+
+ synchronized (ObjectFactory.class) {
+ boolean loadProperties = false;
+ try {
+ // file existed last time
+ if(fLastModified >= 0) {
+ if(propertiesFileExists &&
+ (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+ loadProperties = true;
+ } else {
+ // file has stopped existing...
+ if(!propertiesFileExists) {
+ fLastModified = -1;
+ fXalanProperties = null;
+ } // else, file wasn't modified!
+ }
+ } else {
+ // file has started to exist:
+ if(propertiesFileExists) {
+ loadProperties = true;
+ fLastModified = ss.getLastModified(propertiesFile);
+ } // else, nothing's changed
+ }
+ if(loadProperties) {
+ // must never have attempted to read xalan.properties
+ // before (or it's outdeated)
+ fXalanProperties = new Properties();
+ FileInputStream fis =
+ ss.getFileInputStream(propertiesFile);
+ fXalanProperties.load(fis);
+ fis.close();
+ }
+ } catch (Exception x) {
+ fXalanProperties = null;
+ fLastModified = -1;
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if(fXalanProperties != null) {
+ factoryClassName = fXalanProperties.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) {
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if (factoryClassName != null) {
+ debugPrintln("found in " + propertiesFilename + ", value="
+ + factoryClassName);
+ return factoryClassName;
+ }
+
+ // Try Jar Service Provider Mechanism
+ return findJarServiceProviderName(factoryId);
+ } // lookUpFactoryClass(String,String):String
+
+ //
+ // Private static methods
+ //
+
+ /** Prints a message to standard error if debugging is enabled. */
+ private static void debugPrintln(String msg) {
+ if (DEBUG) {
+ System.err.println("JAXP: " + msg);
+ }
+ } // debugPrintln(String)
+
+ /**
+ * Figure out which ClassLoader to use. For JDK 1.2 and later use
+ * the context ClassLoader.
+ */
+ static ClassLoader findClassLoader()
+ throws ConfigurationError
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Figure out which ClassLoader to use for loading the provider
+ // class. If there is a Context ClassLoader then use it.
+ ClassLoader context = ss.getContextClassLoader();
+ ClassLoader system = ss.getSystemClassLoader();
+
+ ClassLoader chain = system;
+ while (true) {
+ if (context == chain) {
+ // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+ // or any Context ClassLoader in chain of system classloader
+ // (including extension ClassLoader) so extend to widest
+ // ClassLoader (always look in system ClassLoader if Xalan
+ // is in boot/extension/system classpath and in current
+ // ClassLoader otherwise); normal classloaders delegate
+ // back to system ClassLoader first so this widening doesn't
+ // change the fact that context ClassLoader will be consulted
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+
+ chain = system;
+ while (true) {
+ if (current == chain) {
+ // Assert: Current ClassLoader in chain of
+ // boot/extension/system ClassLoaders
+ return system;
+ }
+ if (chain == null) {
+ break;
+ }
+ chain = ss.getParentClassLoader(chain);
+ }
+
+ // Assert: Current ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return current;
+ }
+
+ if (chain == null) {
+ // boot ClassLoader reached
+ break;
+ }
+
+ // Check for any extension ClassLoaders in chain up to
+ // boot ClassLoader
+ chain = ss.getParentClassLoader(chain);
+ };
+
+ // Assert: Context ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return context;
+ } // findClassLoader():ClassLoader
+
+ /**
+ * Create an instance of a class using the specified ClassLoader
+ */
+ static Object newInstance(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ConfigurationError
+ {
+ // assert(className != null);
+ 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);
+ }
+ }
+
+ /**
+ * Find a Class using the specified ClassLoader
+ */
+ static Class findProviderClass(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ClassNotFoundException, ConfigurationError
+ {
+
+ SecurityManager security = System.getSecurityManager();
+ try{
+ if (security != null)
+ security.checkPackageAccess(className);
+ }catch(SecurityException e){
+ throw e;
+ }
+
+ Class providerClass;
+ if (cl == null) {
+ // XXX Use the bootstrap ClassLoader. There is no way to
+ // load a class using the bootstrap ClassLoader that works
+ // in both JDK 1.1 and Java 2. However, this should still
+ // work b/c the following should be true:
+ //
+ // (cl == null) iff current ClassLoader == null
+ //
+ // Thus Class.forName(String) will use the current
+ // ClassLoader which will be the bootstrap ClassLoader.
+ providerClass = Class.forName(className);
+ } else {
+ try {
+ providerClass = cl.loadClass(className);
+ } catch (ClassNotFoundException x) {
+ if (doFallback) {
+ // Fall back to current classloader
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (current == null) {
+ providerClass = Class.forName(className);
+ } else if (cl != current) {
+ cl = current;
+ providerClass = cl.loadClass(className);
+ } else {
+ throw x;
+ }
+ } else {
+ throw x;
+ }
+ }
+ }
+
+ return providerClass;
+ }
+
+ /**
+ * Find the name of service provider using Jar Service Provider Mechanism
+ *
+ * @return instance of provider class if found or null
+ */
+ private static String findJarServiceProviderName(String factoryId)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+ String serviceId = SERVICES_PATH + factoryId;
+ InputStream is = null;
+
+ // First try the Context ClassLoader
+ ClassLoader cl = findClassLoader();
+
+ is = ss.getResourceAsStream(cl, serviceId);
+
+ // If no provider found then try the current ClassLoader
+ if (is == null) {
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (cl != current) {
+ cl = current;
+ is = ss.getResourceAsStream(cl, serviceId);
+ }
+ }
+
+ if (is == null) {
+ // No provider found
+ return null;
+ }
+
+ debugPrintln("found jar resource=" + serviceId +
+ " using ClassLoader: " + cl);
+
+ // Read the service provider name in UTF-8 as specified in
+ // the jar spec. Unfortunately this fails in Microsoft
+ // VJ++, which does not implement the UTF-8
+ // encoding. Theoretically, we should simply let it fail in
+ // that case, since the JVM is obviously broken if it
+ // doesn't support such a basic standard. But since there
+ // are still some users attempting to use VJ++ for
+ // development, we have dropped in a fallback which makes a
+ // second attempt using the platform's default encoding. In
+ // VJ++ this is apparently ASCII, which is a subset of
+ // UTF-8... and since the strings we'll be reading here are
+ // also primarily limited to the 7-bit ASCII range (at
+ // least, in English versions), this should work well
+ // enough to keep us on the air until we're ready to
+ // officially decommit from VJ++. [Edited comment from
+ // jkesselm]
+ BufferedReader rd;
+ try {
+ rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ } catch (java.io.UnsupportedEncodingException e) {
+ rd = new BufferedReader(new InputStreamReader(is));
+ }
+
+ String factoryClassName = null;
+ try {
+ // XXX Does not handle all possible input as specified by the
+ // Jar Service Provider specification
+ factoryClassName = rd.readLine();
+ rd.close();
+ } catch (IOException x) {
+ // No provider found
+ return null;
+ }
+
+ if (factoryClassName != null &&
+ ! "".equals(factoryClassName)) {
+ debugPrintln("found in resource, value="
+ + factoryClassName);
+
+ // Note: here we do not want to fall back to the current
+ // ClassLoader because we want to avoid the case where the
+ // resource file was found using one ClassLoader and the
+ // provider class was instantiated using a different one.
+ return factoryClassName;
+ }
+
+ // No provider found
+ return null;
+ }
+
+ //
+ // Classes
+ //
+
+ /**
+ * A configuration error.
+ */
+ static class ConfigurationError
+ extends Error {
+
+ //
+ // Data
+ //
+
+ /** Exception. */
+ private Exception exception;
+
+ //
+ // Constructors
+ //
+
+ /**
+ * Construct a new instance with the specified detail string and
+ * exception.
+ */
+ public ConfigurationError(String msg, Exception x) {
+ super(msg);
+ this.exception = x;
+ } // <init>(String,Exception)
+
+ //
+ // Public methods
+ //
+
+ /** Returns the exception associated to this error. */
+ public Exception getException() {
+ return exception;
+ } // getException():Exception
+
+ } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xml/serializer/SecuritySupport.java b/src/org/apache/xml/serializer/SecuritySupport.java
index cf69b16..ec0c910 100644
--- a/src/org/apache/xml/serializer/SecuritySupport.java
+++ b/src/org/apache/xml/serializer/SecuritySupport.java
@@ -113,33 +113,33 @@
* Return an appropriate instance of this class, depending on whether
* we're on a JDK 1.1 or J2SE 1.2 (or later) system.
*/
- public static SecuritySupport getInstance() {
+ static SecuritySupport getInstance() {
return (SecuritySupport)securitySupport;
}
- public ClassLoader getContextClassLoader() {
+ ClassLoader getContextClassLoader() {
return null;
}
- public ClassLoader getSystemClassLoader() {
+ ClassLoader getSystemClassLoader() {
return null;
}
- public ClassLoader getParentClassLoader(ClassLoader cl) {
+ ClassLoader getParentClassLoader(ClassLoader cl) {
return null;
}
- public String getSystemProperty(String propName) {
+ String getSystemProperty(String propName) {
return System.getProperty(propName);
}
- public FileInputStream getFileInputStream(File file)
+ FileInputStream getFileInputStream(File file)
throws FileNotFoundException
{
return new FileInputStream(file);
}
- public InputStream getResourceAsStream(ClassLoader cl, String name) {
+ InputStream getResourceAsStream(ClassLoader cl, String name) {
InputStream ris;
if (cl == null) {
ris = ClassLoader.getSystemResourceAsStream(name);
@@ -149,11 +149,11 @@
return ris;
}
- public boolean getFileExists(File f) {
+ boolean getFileExists(File f) {
return f.exists();
}
- public long getLastModified(File f) {
+ long getLastModified(File f) {
return f.lastModified();
}
}
diff --git a/src/org/apache/xml/serializer/SecuritySupport12.java b/src/org/apache/xml/serializer/SecuritySupport12.java
index 8c4713e..a338fb4 100644
--- a/src/org/apache/xml/serializer/SecuritySupport12.java
+++ b/src/org/apache/xml/serializer/SecuritySupport12.java
@@ -76,7 +76,7 @@
*/
class SecuritySupport12 extends SecuritySupport {
- public ClassLoader getContextClassLoader() {
+ ClassLoader getContextClassLoader() {
return (ClassLoader)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
@@ -89,7 +89,7 @@
});
}
- public ClassLoader getSystemClassLoader() {
+ ClassLoader getSystemClassLoader() {
return (ClassLoader)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
@@ -102,7 +102,7 @@
});
}
- public ClassLoader getParentClassLoader(final ClassLoader cl) {
+ ClassLoader getParentClassLoader(final ClassLoader cl) {
return (ClassLoader)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
@@ -118,7 +118,7 @@
});
}
- public String getSystemProperty(final String propName) {
+ String getSystemProperty(final String propName) {
return (String)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
@@ -127,7 +127,7 @@
});
}
- public FileInputStream getFileInputStream(final File file)
+ FileInputStream getFileInputStream(final File file)
throws FileNotFoundException
{
try {
@@ -142,7 +142,7 @@
}
}
- public InputStream getResourceAsStream(final ClassLoader cl,
+ InputStream getResourceAsStream(final ClassLoader cl,
final String name)
{
return (InputStream)
@@ -159,7 +159,7 @@
});
}
- public boolean getFileExists(final File f) {
+ boolean getFileExists(final File f) {
return ((Boolean)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
@@ -168,7 +168,7 @@
})).booleanValue();
}
- public long getLastModified(final File f) {
+ long getLastModified(final File f) {
return ((Long)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
diff --git a/src/org/apache/xml/serializer/SerializerFactory.java b/src/org/apache/xml/serializer/SerializerFactory.java
index e63a66b..88f8941 100644
--- a/src/org/apache/xml/serializer/SerializerFactory.java
+++ b/src/org/apache/xml/serializer/SerializerFactory.java
@@ -63,7 +63,7 @@
import org.apache.xml.res.XMLErrorResources;
import org.apache.xml.res.XMLMessages;
-import org.apache.xml.utils.ObjectFactory;
+
import org.xml.sax.ContentHandler;
/**
diff --git a/src/org/apache/xpath/compiler/FuncLoader.java b/src/org/apache/xpath/compiler/FuncLoader.java
index b31e1c6..367fa83 100644
--- a/src/org/apache/xpath/compiler/FuncLoader.java
+++ b/src/org/apache/xpath/compiler/FuncLoader.java
@@ -58,7 +58,7 @@
import javax.xml.transform.TransformerException;
-import org.apache.xml.utils.ObjectFactory;
+
import org.apache.xpath.functions.Function;
/**
diff --git a/src/org/apache/xpath/compiler/ObjectFactory.java b/src/org/apache/xpath/compiler/ObjectFactory.java
new file mode 100755
index 0000000..09e9cd8
--- /dev/null
+++ b/src/org/apache/xpath/compiler/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xpath.compiler;
+
+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;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+ //
+ // Constants
+ //
+
+ // name of default properties file to look for in JDK's jre/lib directory
+ private static final String DEFAULT_PROPERTIES_FILENAME =
+ "xalan.properties";
+
+ private static final String SERVICES_PATH = "META-INF/services";
+
+ /** Set to true for debugging */
+ private static final boolean DEBUG = false;
+
+ /** cache the contents of the xalan.properties file.
+ * Until an attempt has been made to read this file, this will
+ * be null; if the file does not exist or we encounter some other error
+ * during the read, this will be empty.
+ */
+ private static Properties fXalanProperties = null;
+
+ /***
+ * Cache the time stamp of the xalan.properties file so
+ * that we know if it's been modified and can invalidate
+ * the cache when necessary.
+ */
+ private static long fLastModified = -1;
+
+ //
+ // Public static methods
+ //
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance 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.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId, String fallbackClassName)
+ throws ConfigurationError {
+ return createObject(factoryId, null, fallbackClassName);
+ } // createObject(String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ Class factoryClass = lookUpFactoryClass(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+
+ if (factoryClass == null) {
+ throw new ConfigurationError(
+ "Provider for " + factoryId + " cannot be found", null);
+ }
+
+ try{
+ Object instance = factoryClass.newInstance();
+ debugPrintln("created new instance of factory " + factoryId);
+ return instance;
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider for factory " + factoryId
+ + " could not be instantiated: " + x, x);
+ }
+ } // createObject(String,String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId)
+ throws ConfigurationError
+ {
+ return lookUpFactoryClass(factoryId, null, null);
+ } // lookUpFactoryClass(String):Class
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ String factoryClassName = lookUpFactoryClassName(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+ ClassLoader cl = findClassLoader();
+
+ if (factoryClassName == null) {
+ factoryClassName = fallbackClassName;
+ }
+
+ // assert(className != null);
+ try{
+ Class providerClass = findProviderClass(factoryClassName,
+ cl,
+ true);
+ debugPrintln("created new instance of " + providerClass +
+ " using ClassLoader: " + cl);
+ return providerClass;
+ } catch (ClassNotFoundException x) {
+ throw new ConfigurationError(
+ "Provider " + factoryClassName + " not found", x);
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider "+factoryClassName+" could not be instantiated: "+x,
+ x);
+ }
+ } // lookUpFactoryClass(String,String,String):Class
+
+ /**
+ * Finds the name of the required implementation class in the specified
+ * order. The specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return name of class that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static String lookUpFactoryClassName(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Use the system property first
+ try {
+ String systemProp = ss.getSystemProperty(factoryId);
+ if (systemProp != null) {
+ debugPrintln("found system property, value=" + systemProp);
+ return systemProp;
+ }
+ } catch (SecurityException se) {
+ // Ignore and continue w/ next location
+ }
+
+ // Try to read from propertiesFilename, or
+ // $java.home/lib/xalan.properties
+ String factoryClassName = null;
+ // no properties file name specified; use
+ // $JAVA_HOME/lib/xalan.properties:
+ if (propertiesFilename == null) {
+ File propertiesFile = null;
+ boolean propertiesFileExists = false;
+ try {
+ String javah = ss.getSystemProperty("java.home");
+ propertiesFilename = javah + File.separator +
+ "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+ propertiesFile = new File(propertiesFilename);
+ propertiesFileExists = ss.getFileExists(propertiesFile);
+ } catch (SecurityException e) {
+ // try again...
+ fLastModified = -1;
+ fXalanProperties = null;
+ }
+
+ synchronized (ObjectFactory.class) {
+ boolean loadProperties = false;
+ try {
+ // file existed last time
+ if(fLastModified >= 0) {
+ if(propertiesFileExists &&
+ (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+ loadProperties = true;
+ } else {
+ // file has stopped existing...
+ if(!propertiesFileExists) {
+ fLastModified = -1;
+ fXalanProperties = null;
+ } // else, file wasn't modified!
+ }
+ } else {
+ // file has started to exist:
+ if(propertiesFileExists) {
+ loadProperties = true;
+ fLastModified = ss.getLastModified(propertiesFile);
+ } // else, nothing's changed
+ }
+ if(loadProperties) {
+ // must never have attempted to read xalan.properties
+ // before (or it's outdeated)
+ fXalanProperties = new Properties();
+ FileInputStream fis =
+ ss.getFileInputStream(propertiesFile);
+ fXalanProperties.load(fis);
+ fis.close();
+ }
+ } catch (Exception x) {
+ fXalanProperties = null;
+ fLastModified = -1;
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if(fXalanProperties != null) {
+ factoryClassName = fXalanProperties.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) {
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if (factoryClassName != null) {
+ debugPrintln("found in " + propertiesFilename + ", value="
+ + factoryClassName);
+ return factoryClassName;
+ }
+
+ // Try Jar Service Provider Mechanism
+ return findJarServiceProviderName(factoryId);
+ } // lookUpFactoryClass(String,String):String
+
+ //
+ // Private static methods
+ //
+
+ /** Prints a message to standard error if debugging is enabled. */
+ private static void debugPrintln(String msg) {
+ if (DEBUG) {
+ System.err.println("JAXP: " + msg);
+ }
+ } // debugPrintln(String)
+
+ /**
+ * Figure out which ClassLoader to use. For JDK 1.2 and later use
+ * the context ClassLoader.
+ */
+ static ClassLoader findClassLoader()
+ throws ConfigurationError
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Figure out which ClassLoader to use for loading the provider
+ // class. If there is a Context ClassLoader then use it.
+ ClassLoader context = ss.getContextClassLoader();
+ ClassLoader system = ss.getSystemClassLoader();
+
+ ClassLoader chain = system;
+ while (true) {
+ if (context == chain) {
+ // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+ // or any Context ClassLoader in chain of system classloader
+ // (including extension ClassLoader) so extend to widest
+ // ClassLoader (always look in system ClassLoader if Xalan
+ // is in boot/extension/system classpath and in current
+ // ClassLoader otherwise); normal classloaders delegate
+ // back to system ClassLoader first so this widening doesn't
+ // change the fact that context ClassLoader will be consulted
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+
+ chain = system;
+ while (true) {
+ if (current == chain) {
+ // Assert: Current ClassLoader in chain of
+ // boot/extension/system ClassLoaders
+ return system;
+ }
+ if (chain == null) {
+ break;
+ }
+ chain = ss.getParentClassLoader(chain);
+ }
+
+ // Assert: Current ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return current;
+ }
+
+ if (chain == null) {
+ // boot ClassLoader reached
+ break;
+ }
+
+ // Check for any extension ClassLoaders in chain up to
+ // boot ClassLoader
+ chain = ss.getParentClassLoader(chain);
+ };
+
+ // Assert: Context ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return context;
+ } // findClassLoader():ClassLoader
+
+ /**
+ * Create an instance of a class using the specified ClassLoader
+ */
+ static Object newInstance(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ConfigurationError
+ {
+ // assert(className != null);
+ 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);
+ }
+ }
+
+ /**
+ * Find a Class using the specified ClassLoader
+ */
+ static Class findProviderClass(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ClassNotFoundException, ConfigurationError
+ {
+
+ SecurityManager security = System.getSecurityManager();
+ try{
+ if (security != null)
+ security.checkPackageAccess(className);
+ }catch(SecurityException e){
+ throw e;
+ }
+
+ Class providerClass;
+ if (cl == null) {
+ // XXX Use the bootstrap ClassLoader. There is no way to
+ // load a class using the bootstrap ClassLoader that works
+ // in both JDK 1.1 and Java 2. However, this should still
+ // work b/c the following should be true:
+ //
+ // (cl == null) iff current ClassLoader == null
+ //
+ // Thus Class.forName(String) will use the current
+ // ClassLoader which will be the bootstrap ClassLoader.
+ providerClass = Class.forName(className);
+ } else {
+ try {
+ providerClass = cl.loadClass(className);
+ } catch (ClassNotFoundException x) {
+ if (doFallback) {
+ // Fall back to current classloader
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (current == null) {
+ providerClass = Class.forName(className);
+ } else if (cl != current) {
+ cl = current;
+ providerClass = cl.loadClass(className);
+ } else {
+ throw x;
+ }
+ } else {
+ throw x;
+ }
+ }
+ }
+
+ return providerClass;
+ }
+
+ /**
+ * Find the name of service provider using Jar Service Provider Mechanism
+ *
+ * @return instance of provider class if found or null
+ */
+ private static String findJarServiceProviderName(String factoryId)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+ String serviceId = SERVICES_PATH + factoryId;
+ InputStream is = null;
+
+ // First try the Context ClassLoader
+ ClassLoader cl = findClassLoader();
+
+ is = ss.getResourceAsStream(cl, serviceId);
+
+ // If no provider found then try the current ClassLoader
+ if (is == null) {
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (cl != current) {
+ cl = current;
+ is = ss.getResourceAsStream(cl, serviceId);
+ }
+ }
+
+ if (is == null) {
+ // No provider found
+ return null;
+ }
+
+ debugPrintln("found jar resource=" + serviceId +
+ " using ClassLoader: " + cl);
+
+ // Read the service provider name in UTF-8 as specified in
+ // the jar spec. Unfortunately this fails in Microsoft
+ // VJ++, which does not implement the UTF-8
+ // encoding. Theoretically, we should simply let it fail in
+ // that case, since the JVM is obviously broken if it
+ // doesn't support such a basic standard. But since there
+ // are still some users attempting to use VJ++ for
+ // development, we have dropped in a fallback which makes a
+ // second attempt using the platform's default encoding. In
+ // VJ++ this is apparently ASCII, which is a subset of
+ // UTF-8... and since the strings we'll be reading here are
+ // also primarily limited to the 7-bit ASCII range (at
+ // least, in English versions), this should work well
+ // enough to keep us on the air until we're ready to
+ // officially decommit from VJ++. [Edited comment from
+ // jkesselm]
+ BufferedReader rd;
+ try {
+ rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ } catch (java.io.UnsupportedEncodingException e) {
+ rd = new BufferedReader(new InputStreamReader(is));
+ }
+
+ String factoryClassName = null;
+ try {
+ // XXX Does not handle all possible input as specified by the
+ // Jar Service Provider specification
+ factoryClassName = rd.readLine();
+ rd.close();
+ } catch (IOException x) {
+ // No provider found
+ return null;
+ }
+
+ if (factoryClassName != null &&
+ ! "".equals(factoryClassName)) {
+ debugPrintln("found in resource, value="
+ + factoryClassName);
+
+ // Note: here we do not want to fall back to the current
+ // ClassLoader because we want to avoid the case where the
+ // resource file was found using one ClassLoader and the
+ // provider class was instantiated using a different one.
+ return factoryClassName;
+ }
+
+ // No provider found
+ return null;
+ }
+
+ //
+ // Classes
+ //
+
+ /**
+ * A configuration error.
+ */
+ static class ConfigurationError
+ extends Error {
+
+ //
+ // Data
+ //
+
+ /** Exception. */
+ private Exception exception;
+
+ //
+ // Constructors
+ //
+
+ /**
+ * Construct a new instance with the specified detail string and
+ * exception.
+ */
+ public ConfigurationError(String msg, Exception x) {
+ super(msg);
+ this.exception = x;
+ } // <init>(String,Exception)
+
+ //
+ // Public methods
+ //
+
+ /** Returns the exception associated to this error. */
+ public Exception getException() {
+ return exception;
+ } // getException():Exception
+
+ } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xpath/compiler/SecuritySupport.java b/src/org/apache/xpath/compiler/SecuritySupport.java
new file mode 100755
index 0000000..dc60e95
--- /dev/null
+++ b/src/org/apache/xpath/compiler/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xpath.compiler;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+ /*
+ * Make this of type Object so that the verifier won't try to
+ * prove its type, thus possibly trying to load the SecuritySupport12
+ * class.
+ */
+ private static final Object securitySupport;
+
+ static {
+ SecuritySupport ss = null;
+ try {
+ Class c = Class.forName("java.security.AccessController");
+ // if that worked, we're on 1.2.
+ /*
+ // don't reference the class explicitly so it doesn't
+ // get dragged in accidentally.
+ c = Class.forName("javax.mail.SecuritySupport12");
+ Constructor cons = c.getConstructor(new Class[] { });
+ ss = (SecuritySupport)cons.newInstance(new Object[] { });
+ */
+ /*
+ * Unfortunately, we can't load the class using reflection
+ * because the class is package private. And the class has
+ * to be package private so the APIs aren't exposed to other
+ * code that could use them to circumvent security. Thus,
+ * we accept the risk that the direct reference might fail
+ * on some JDK 1.1 JVMs, even though we would never execute
+ * this code in such a case. Sigh...
+ */
+ ss = new SecuritySupport12();
+ } catch (Exception ex) {
+ // ignore it
+ } finally {
+ if (ss == null)
+ ss = new SecuritySupport();
+ securitySupport = ss;
+ }
+ }
+
+ /**
+ * Return an appropriate instance of this class, depending on whether
+ * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+ */
+ static SecuritySupport getInstance() {
+ return (SecuritySupport)securitySupport;
+ }
+
+ ClassLoader getContextClassLoader() {
+ return null;
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return null;
+ }
+
+ ClassLoader getParentClassLoader(ClassLoader cl) {
+ return null;
+ }
+
+ String getSystemProperty(String propName) {
+ return System.getProperty(propName);
+ }
+
+ FileInputStream getFileInputStream(File file)
+ throws FileNotFoundException
+ {
+ return new FileInputStream(file);
+ }
+
+ InputStream getResourceAsStream(ClassLoader cl, String name) {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+
+ boolean getFileExists(File f) {
+ return f.exists();
+ }
+
+ long getLastModified(File f) {
+ return f.lastModified();
+ }
+}
diff --git a/src/org/apache/xpath/compiler/SecuritySupport12.java b/src/org/apache/xpath/compiler/SecuritySupport12.java
new file mode 100755
index 0000000..21dc0a5
--- /dev/null
+++ b/src/org/apache/xpath/compiler/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xpath.compiler;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+ ClassLoader getContextClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = Thread.currentThread().getContextClassLoader();
+ } catch (SecurityException ex) { }
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getSystemClassLoader() {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader cl = null;
+ try {
+ cl = ClassLoader.getSystemClassLoader();
+ } catch (SecurityException ex) {}
+ return cl;
+ }
+ });
+ }
+
+ ClassLoader getParentClassLoader(final ClassLoader cl) {
+ return (ClassLoader)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader parent = null;
+ try {
+ parent = cl.getParent();
+ } catch (SecurityException ex) {}
+
+ // eliminate loops in case of the boot
+ // ClassLoader returning itself as a parent
+ return (parent == cl) ? null : parent;
+ }
+ });
+ }
+
+ String getSystemProperty(final String propName) {
+ return (String)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty(propName);
+ }
+ });
+ }
+
+ FileInputStream getFileInputStream(final File file)
+ throws FileNotFoundException
+ {
+ try {
+ return (FileInputStream)
+ AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws FileNotFoundException {
+ return new FileInputStream(file);
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ throw (FileNotFoundException)e.getException();
+ }
+ }
+
+ InputStream getResourceAsStream(final ClassLoader cl,
+ final String name)
+ {
+ return (InputStream)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ InputStream ris;
+ if (cl == null) {
+ ris = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ ris = cl.getResourceAsStream(name);
+ }
+ return ris;
+ }
+ });
+ }
+
+ boolean getFileExists(final File f) {
+ return ((Boolean)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Boolean(f.exists());
+ }
+ })).booleanValue();
+ }
+
+ long getLastModified(final File f) {
+ return ((Long)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new Long(f.lastModified());
+ }
+ })).longValue();
+ }
+
+}
diff --git a/src/org/apache/xpath/functions/FuncSystemProperty.java b/src/org/apache/xpath/functions/FuncSystemProperty.java
index 45422e2..019a05d 100644
--- a/src/org/apache/xpath/functions/FuncSystemProperty.java
+++ b/src/org/apache/xpath/functions/FuncSystemProperty.java
@@ -60,7 +60,7 @@
import java.io.InputStream;
import java.util.Properties;
-import org.apache.xml.utils.ObjectFactory;
+
import org.apache.xpath.XPathContext;
import org.apache.xpath.objects.XNumber;
diff --git a/src/org/apache/xpath/functions/ObjectFactory.java b/src/org/apache/xpath/functions/ObjectFactory.java
new file mode 100755
index 0000000..687e8e2
--- /dev/null
+++ b/src/org/apache/xpath/functions/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ * promote products derived from this software without prior written
+ * permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com. For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xpath.functions;
+
+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;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+ //
+ // Constants
+ //
+
+ // name of default properties file to look for in JDK's jre/lib directory
+ private static final String DEFAULT_PROPERTIES_FILENAME =
+ "xalan.properties";
+
+ private static final String SERVICES_PATH = "META-INF/services";
+
+ /** Set to true for debugging */
+ private static final boolean DEBUG = false;
+
+ /** cache the contents of the xalan.properties file.
+ * Until an attempt has been made to read this file, this will
+ * be null; if the file does not exist or we encounter some other error
+ * during the read, this will be empty.
+ */
+ private static Properties fXalanProperties = null;
+
+ /***
+ * Cache the time stamp of the xalan.properties file so
+ * that we know if it's been modified and can invalidate
+ * the cache when necessary.
+ */
+ private static long fLastModified = -1;
+
+ //
+ // Public static methods
+ //
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance 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.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId, String fallbackClassName)
+ throws ConfigurationError {
+ return createObject(factoryId, null, fallbackClassName);
+ } // createObject(String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return instance of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Object createObject(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ Class factoryClass = lookUpFactoryClass(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+
+ if (factoryClass == null) {
+ throw new ConfigurationError(
+ "Provider for " + factoryId + " cannot be found", null);
+ }
+
+ try{
+ Object instance = factoryClass.newInstance();
+ debugPrintln("created new instance of factory " + factoryId);
+ return instance;
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider for factory " + factoryId
+ + " could not be instantiated: " + x, x);
+ }
+ } // createObject(String,String,String):Object
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object of factory, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId)
+ throws ConfigurationError
+ {
+ return lookUpFactoryClass(factoryId, null, null);
+ } // lookUpFactoryClass(String):Class
+
+ /**
+ * Finds the implementation Class object in the specified order. The
+ * specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return Class object that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static Class lookUpFactoryClass(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ throws ConfigurationError
+ {
+ String factoryClassName = lookUpFactoryClassName(factoryId,
+ propertiesFilename,
+ fallbackClassName);
+ ClassLoader cl = findClassLoader();
+
+ if (factoryClassName == null) {
+ factoryClassName = fallbackClassName;
+ }
+
+ // assert(className != null);
+ try{
+ Class providerClass = findProviderClass(factoryClassName,
+ cl,
+ true);
+ debugPrintln("created new instance of " + providerClass +
+ " using ClassLoader: " + cl);
+ return providerClass;
+ } catch (ClassNotFoundException x) {
+ throw new ConfigurationError(
+ "Provider " + factoryClassName + " not found", x);
+ } catch (Exception x) {
+ throw new ConfigurationError(
+ "Provider "+factoryClassName+" could not be instantiated: "+x,
+ x);
+ }
+ } // lookUpFactoryClass(String,String,String):Class
+
+ /**
+ * Finds the name of the required implementation class in the specified
+ * order. The specified order is the following:
+ * <ol>
+ * <li>query the system property using <code>System.getProperty</code>
+ * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+ * <li>read <code>META-INF/services/<i>factoryId</i></code> file
+ * <li>use fallback classname
+ * </ol>
+ *
+ * @return name of class that provides factory service, never null
+ *
+ * @param factoryId Name of the factory to find, same as
+ * a property name
+ * @param propertiesFilename The filename in the $java.home/lib directory
+ * of the properties file. If none specified,
+ * ${java.home}/lib/xalan.properties will be used.
+ * @param fallbackClassName Implementation class name, if nothing else
+ * is found. Use null to mean no fallback.
+ *
+ * @exception ObjectFactory.ConfigurationError
+ */
+ static String lookUpFactoryClassName(String factoryId,
+ String propertiesFilename,
+ String fallbackClassName)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Use the system property first
+ try {
+ String systemProp = ss.getSystemProperty(factoryId);
+ if (systemProp != null) {
+ debugPrintln("found system property, value=" + systemProp);
+ return systemProp;
+ }
+ } catch (SecurityException se) {
+ // Ignore and continue w/ next location
+ }
+
+ // Try to read from propertiesFilename, or
+ // $java.home/lib/xalan.properties
+ String factoryClassName = null;
+ // no properties file name specified; use
+ // $JAVA_HOME/lib/xalan.properties:
+ if (propertiesFilename == null) {
+ File propertiesFile = null;
+ boolean propertiesFileExists = false;
+ try {
+ String javah = ss.getSystemProperty("java.home");
+ propertiesFilename = javah + File.separator +
+ "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+ propertiesFile = new File(propertiesFilename);
+ propertiesFileExists = ss.getFileExists(propertiesFile);
+ } catch (SecurityException e) {
+ // try again...
+ fLastModified = -1;
+ fXalanProperties = null;
+ }
+
+ synchronized (ObjectFactory.class) {
+ boolean loadProperties = false;
+ try {
+ // file existed last time
+ if(fLastModified >= 0) {
+ if(propertiesFileExists &&
+ (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+ loadProperties = true;
+ } else {
+ // file has stopped existing...
+ if(!propertiesFileExists) {
+ fLastModified = -1;
+ fXalanProperties = null;
+ } // else, file wasn't modified!
+ }
+ } else {
+ // file has started to exist:
+ if(propertiesFileExists) {
+ loadProperties = true;
+ fLastModified = ss.getLastModified(propertiesFile);
+ } // else, nothing's changed
+ }
+ if(loadProperties) {
+ // must never have attempted to read xalan.properties
+ // before (or it's outdeated)
+ fXalanProperties = new Properties();
+ FileInputStream fis =
+ ss.getFileInputStream(propertiesFile);
+ fXalanProperties.load(fis);
+ fis.close();
+ }
+ } catch (Exception x) {
+ fXalanProperties = null;
+ fLastModified = -1;
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if(fXalanProperties != null) {
+ factoryClassName = fXalanProperties.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) {
+ // assert(x instanceof FileNotFoundException
+ // || x instanceof SecurityException)
+ // In both cases, ignore and continue w/ next location
+ }
+ }
+ if (factoryClassName != null) {
+ debugPrintln("found in " + propertiesFilename + ", value="
+ + factoryClassName);
+ return factoryClassName;
+ }
+
+ // Try Jar Service Provider Mechanism
+ return findJarServiceProviderName(factoryId);
+ } // lookUpFactoryClass(String,String):String
+
+ //
+ // Private static methods
+ //
+
+ /** Prints a message to standard error if debugging is enabled. */
+ private static void debugPrintln(String msg) {
+ if (DEBUG) {
+ System.err.println("JAXP: " + msg);
+ }
+ } // debugPrintln(String)
+
+ /**
+ * Figure out which ClassLoader to use. For JDK 1.2 and later use
+ * the context ClassLoader.
+ */
+ static ClassLoader findClassLoader()
+ throws ConfigurationError
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+
+ // Figure out which ClassLoader to use for loading the provider
+ // class. If there is a Context ClassLoader then use it.
+ ClassLoader context = ss.getContextClassLoader();
+ ClassLoader system = ss.getSystemClassLoader();
+
+ ClassLoader chain = system;
+ while (true) {
+ if (context == chain) {
+ // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+ // or any Context ClassLoader in chain of system classloader
+ // (including extension ClassLoader) so extend to widest
+ // ClassLoader (always look in system ClassLoader if Xalan
+ // is in boot/extension/system classpath and in current
+ // ClassLoader otherwise); normal classloaders delegate
+ // back to system ClassLoader first so this widening doesn't
+ // change the fact that context ClassLoader will be consulted
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+
+ chain = system;
+ while (true) {
+ if (current == chain) {
+ // Assert: Current ClassLoader in chain of
+ // boot/extension/system ClassLoaders
+ return system;
+ }
+ if (chain == null) {
+ break;
+ }
+ chain = ss.getParentClassLoader(chain);
+ }
+
+ // Assert: Current ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return current;
+ }
+
+ if (chain == null) {
+ // boot ClassLoader reached
+ break;
+ }
+
+ // Check for any extension ClassLoaders in chain up to
+ // boot ClassLoader
+ chain = ss.getParentClassLoader(chain);
+ };
+
+ // Assert: Context ClassLoader not in chain of
+ // boot/extension/system ClassLoaders
+ return context;
+ } // findClassLoader():ClassLoader
+
+ /**
+ * Create an instance of a class using the specified ClassLoader
+ */
+ static Object newInstance(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ConfigurationError
+ {
+ // assert(className != null);
+ 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);
+ }
+ }
+
+ /**
+ * Find a Class using the specified ClassLoader
+ */
+ static Class findProviderClass(String className, ClassLoader cl,
+ boolean doFallback)
+ throws ClassNotFoundException, ConfigurationError
+ {
+
+ SecurityManager security = System.getSecurityManager();
+ try{
+ if (security != null)
+ security.checkPackageAccess(className);
+ }catch(SecurityException e){
+ throw e;
+ }
+
+ Class providerClass;
+ if (cl == null) {
+ // XXX Use the bootstrap ClassLoader. There is no way to
+ // load a class using the bootstrap ClassLoader that works
+ // in both JDK 1.1 and Java 2. However, this should still
+ // work b/c the following should be true:
+ //
+ // (cl == null) iff current ClassLoader == null
+ //
+ // Thus Class.forName(String) will use the current
+ // ClassLoader which will be the bootstrap ClassLoader.
+ providerClass = Class.forName(className);
+ } else {
+ try {
+ providerClass = cl.loadClass(className);
+ } catch (ClassNotFoundException x) {
+ if (doFallback) {
+ // Fall back to current classloader
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (current == null) {
+ providerClass = Class.forName(className);
+ } else if (cl != current) {
+ cl = current;
+ providerClass = cl.loadClass(className);
+ } else {
+ throw x;
+ }
+ } else {
+ throw x;
+ }
+ }
+ }
+
+ return providerClass;
+ }
+
+ /**
+ * Find the name of service provider using Jar Service Provider Mechanism
+ *
+ * @return instance of provider class if found or null
+ */
+ private static String findJarServiceProviderName(String factoryId)
+ {
+ SecuritySupport ss = SecuritySupport.getInstance();
+ String serviceId = SERVICES_PATH + factoryId;
+ InputStream is = null;
+
+ // First try the Context ClassLoader
+ ClassLoader cl = findClassLoader();
+
+ is = ss.getResourceAsStream(cl, serviceId);
+
+ // If no provider found then try the current ClassLoader
+ if (is == null) {
+ ClassLoader current = ObjectFactory.class.getClassLoader();
+ if (cl != current) {
+ cl = current;
+ is = ss.getResourceAsStream(cl, serviceId);
+ }
+ }
+
+ if (is == null) {
+ // No provider found
+ return null;
+ }
+
+ debugPrintln("found jar resource=" + serviceId +
+ " using ClassLoader: " + cl);
+
+ // Read the service provider name in UTF-8 as specified in
+ // the jar spec. Unfortunately this fails in Microsoft
+ // VJ++, which does not implement the UTF-8
+ // encoding. Theoretically, we should simply let it fail in
+ // that case, since the JVM is obviously broken if it
+ // doesn't support such a basic standard. But since there
+ // are still some users attempting to use VJ++ for
+ // development, we have dropped in a fallback which makes a
+ // second attempt using the platform's default encoding. In
+ // VJ++ this is apparently ASCII, which is a subset of
+ // UTF-8... and since the strings we'll be reading here are
+ // also primarily limited to the 7-bit ASCII range (at
+ // least, in English versions), this should work well
+ // enough to keep us on the air until we're ready to
+ // officially decommit from VJ++. [Edited comment from
+ // jkesselm]
+ BufferedReader rd;
+ try {
+ rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ } catch (java.io.UnsupportedEncodingException e) {
+ rd = new BufferedReader(new InputStreamReader(is));
+ }
+
+ String factoryClassName = null;
+ try {
+ // XXX Does not handle all possible input as specified by the
+ // Jar Service Provider specification
+ factoryClassName = rd.readLine();
+ rd.close();
+ } catch (IOException x) {
+ // No provider found
+ return null;
+ }
+
+ if (factoryClassName != null &&
+ ! "".equals(factoryClassName)) {
+ debugPrintln("found in resource, value="
+ + factoryClassName);
+
+ // Note: here we do not want to fall back to the current
+ // ClassLoader because we want to avoid the case where the
+ // resource file was found using one ClassLoader and the
+ // provider class was instantiated using a different one.
+ return factoryClassName;
+ }
+
+ // No provider found
+ return null;
+ }
+
+ //
+ // Classes
+ //
+
+ /**
+ * A configuration error.
+ */
+ static class ConfigurationError
+ extends Error {
+
+ //
+ // Data
+ //
+
+ /** Exception. */
+ private Exception exception;
+
+ //
+ // Constructors
+ //
+
+ /**
+ * Construct a new instance with the specified detail string and
+ * exception.
+ */
+ public ConfigurationError(String msg, Exception x) {
+ super(msg);
+ this.exception = x;
+ } // <init>(String,Exception)
+
+ //
+ // Public methods
+ //
+
+ /** Returns the exception associated to this error. */
+ public Exception getException() {
+ return exception;
+ } // getException():Exception
+
+ } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xpath/functions/SecuritySupport.java b/src/org/apache/xpath/functions/SecuritySupport.java
index 9b72c62..31ddf0f 100644
--- a/src/org/apache/xpath/functions/SecuritySupport.java
+++ b/src/org/apache/xpath/functions/SecuritySupport.java
@@ -113,33 +113,33 @@
* Return an appropriate instance of this class, depending on whether
* we're on a JDK 1.1 or J2SE 1.2 (or later) system.
*/
- public static SecuritySupport getInstance() {
+ static SecuritySupport getInstance() {
return (SecuritySupport)securitySupport;
}
- public ClassLoader getContextClassLoader() {
+ ClassLoader getContextClassLoader() {
return null;
}
- public ClassLoader getSystemClassLoader() {
+ ClassLoader getSystemClassLoader() {
return null;
}
- public ClassLoader getParentClassLoader(ClassLoader cl) {
+ ClassLoader getParentClassLoader(ClassLoader cl) {
return null;
}
- public String getSystemProperty(String propName) {
+ String getSystemProperty(String propName) {
return System.getProperty(propName);
}
- public FileInputStream getFileInputStream(File file)
+ FileInputStream getFileInputStream(File file)
throws FileNotFoundException
{
return new FileInputStream(file);
}
- public InputStream getResourceAsStream(ClassLoader cl, String name) {
+ InputStream getResourceAsStream(ClassLoader cl, String name) {
InputStream ris;
if (cl == null) {
ris = ClassLoader.getSystemResourceAsStream(name);
@@ -149,11 +149,11 @@
return ris;
}
- public boolean getFileExists(File f) {
+ boolean getFileExists(File f) {
return f.exists();
}
- public long getLastModified(File f) {
+ long getLastModified(File f) {
return f.lastModified();
}
}
diff --git