/*
 **
 ** Licensed to the Apache Software Foundation (ASF) under one
 ** or more contributor license agreements.  See the NOTICE file
 ** distributed with this work for additional information
 ** regarding copyright ownership.  The ASF licenses this file
 ** to you 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.
 */
package javax.xml.stream;

import java.io.InputStream;
import java.io.File;
import java.io.FileInputStream;

import java.util.Properties;
import java.io.BufferedReader;
import java.io.InputStreamReader;

import org.apache.geronimo.osgi.locator.ProviderLocator;

/*
 * Here is the beef on the finding the Factory Class
 *
 * 1. Use the javax.xml.stream.XMLInputFactory system property. 2. Use the
 * properties file "lib/stax.properties" in the JRE directory. This
 * configuration file is in standard java.util.Properties format and contains
 * the fully qualified name of the implementation class with the key being the
 * system property defined above. 3. Use the Services API (as detailed in the
 * JAR specification), if available, to determine the classname. The Services
 * API will look for a classname in the file
 * META-INF/services/javax.xml.stream.XMLInputFactory in jars available to the
 * runtime. Platform default XMLInputFactory instance.
 *
 * If the user provided a classloader we'll use that...if not, we'll assume the
 * classloader of this class.
 */

class FactoryLocator {
	static Object locate(String factoryId) throws FactoryConfigurationError {
		return locate(factoryId, null);
	}

	static Object locate(String factoryId, String altClassName)
			throws FactoryConfigurationError {
		return locate(factoryId, altClassName,
                              Thread.currentThread().getContextClassLoader());
	}

	static Object locate(String factoryId, String altClassName,
			ClassLoader classLoader) throws FactoryConfigurationError {
        // NOTE:  The stax spec uses the following lookup order, which is the reverse from what is specified
        // most of the APIs:
        // 1. Use the javax.xml.stream.XMLInputFactory system property.
        // 2. Use the properties file lib/xml.stream.properties in the JRE directory. This configuration
        // file is in standard java.util.Properties format and contains the fully qualified name of the
        // implementation class with the key being the system property defined in step 1.
        // 3. Use the Services API (as detailed in the JAR specification), if available, to determine the
        // classname. The Services API looks for a classname in the file META-INF/services/
        // javax.xml.stream.XMLInputFactory in jars available to the runtime.
        // 4. Platform default XMLInputFactory instance.


        // Use the system property first
        try {
            String systemProp = System.getProperty(factoryId);
            if (systemProp != null) {
                return newInstance(systemProp, classLoader);
            }
        } catch (SecurityException se) {
        }

        try {
            // NOTE:  The StAX spec gives this property file name as xml.stream.properties, but the javadoc and the maintenance release
            // state this is stax.properties.
            String factoryClassName =  ProviderLocator.lookupByJREPropertyFile("lib" + File.separator + "stax.properties", factoryId);
            if (factoryClassName != null) {
                return newInstance(factoryClassName, classLoader);
            }
        } catch (Exception ex) {
        }

        try {
            // check the META-INF/services definitions, and return it if
            // we find something.
            Object service = ProviderLocator.getService(factoryId, FactoryLocator.class, classLoader);
            if (service != null) {
                return service;
            }
        } catch (Exception ex) {
        }

		if (altClassName == null) {
			throw new FactoryConfigurationError("Unable to locate factory for "
					+ factoryId + ".", null);
		}
		return newInstance(altClassName, classLoader);
	}

	private static Object newInstance(String className, ClassLoader classLoader)
			throws FactoryConfigurationError {
		try {
			return ProviderLocator.loadClass(className, FactoryLocator.class, classLoader).newInstance();
		} catch (ClassNotFoundException x) {
  			throw new FactoryConfigurationError("Requested factory "
  					+ className + " cannot be located.  Classloader ="
  					+ classLoader.toString(), x);
		} catch (Exception x) {
			throw new FactoryConfigurationError("Requested factory "
					+ className + " could not be instantiated: " + x, x);
		}
	}
}
