/*******************************************************************************
 * Copyright (c) 2007 Standards for Technology in Automotive Retail
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     David Carver - STAR - bug 224197 - initial API and implementation
 *                    based on work from Apache Xalan 2.7.0
 *******************************************************************************/

/*
 * Copyright 2001-2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id: ObjectFactory.java,v 1.2 2008/03/28 02:38:18 dacarver Exp $
 */

package org.eclipse.wst.xsl.core.internal.compiler.xslt10.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: ObjectFactory.java,v 1.2 2008/03/28 02:38:18 dacarver Exp $
 */
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;
				FileInputStream fis = null;
				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();
						fis = ss.getFileInputStream(propertiesFile);
						fXalanProperties.load(fis);
					}
				} catch (Exception x) {
					fXalanProperties = null;
					fLastModified = -1;
					// assert(x instanceof FileNotFoundException
					// || x instanceof SecurityException)
					// In both cases, ignore and continue w/ next location
				} finally {
					// try to close the input stream if one was opened.
					if (fis != null) {
						try {
							fis.close();
						}
						// Ignore the exception.
						catch (IOException exc) {
						}
					}
				}
			}
			if (fXalanProperties != null) {
				factoryClassName = fXalanProperties.getProperty(factoryId);
			}
		} else {
			FileInputStream fis = null;
			try {
				fis = ss.getFileInputStream(new File(propertiesFilename));
				Properties props = new Properties();
				props.load(fis);
				factoryClassName = props.getProperty(factoryId);
			} catch (Exception x) {
				// assert(x instanceof FileNotFoundException
				// || x instanceof SecurityException)
				// In both cases, ignore and continue w/ next location
			} finally {
				// try to close the input stream if one was opened.
				if (fis != null) {
					try {
						fis.close();
					}
					// Ignore the exception.
					catch (IOException exc) {
					}
				}
			}
		}
		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 {
		// throw security exception if the calling thread is not allowed to
		// access the
		// class. Restrict the access to the package classes as specified in
		// java.security policy.
		SecurityManager security = System.getSecurityManager();
		try {
			if (security != null) {
				final int lastDot = className.lastIndexOf(".");
				String packageName = className;
				if (lastDot != -1)
					packageName = className.substring(0, lastDot);
				security.checkPackageAccess(packageName);
			}
		} 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();
		} catch (IOException x) {
			// No provider found
			return null;
		} finally {
			try {
				// try to close the reader.
				rd.close();
			}
			// Ignore the exception.
			catch (IOException exc) {
			}
		}

		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 {
		static final long serialVersionUID = 8564305128443551853L;
		//
		// Data
		//

		/** Exception. */
		private Exception exception;

		//
		// Constructors
		//

		/**
		 * Construct a new instance with the specified detail string and
		 * exception.
		 */
		ConfigurationError(String msg, Exception x) {
			super(msg);
			this.exception = x;
		} // <init>(String,Exception)

		//
		// Public methods
		//

		/** Returns the exception associated to this error. */
		Exception getException() {
			return exception;
		} // getException():Exception

	} // class ConfigurationError

} // class ObjectFactory
