/*
THIS IS AN OLD VERSION OF JXPathContextFactory.java THAT ASSUMES THAT IN ORDER
TO RUN, JXPath NEEDS AN EXTERNAL XSLT ENGINE.  SINCE THAT IS NO LONGER THE CASE,
THIS CLASS HAS BEEN SIMPLIFIED.
*/



/*
 * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//jxpath/src/java/org/apache/commons/jxpath/Attic/JXPathContextFactory.xalan.readme.txt,v 1.1 2001/08/23 00:46:58 dmitri Exp $
 * $Revision: 1.1 $
 * $Date: 2001/08/23 00:46:58 $
 *
 * ====================================================================
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2001 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 acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Commons", and "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 names without prior written
 *    permission of the Apache Group.
 *
 * 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) 2001, Plotnix, Inc,
 * <http://www.plotnix.com/>.
 * For more information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package org.apache.commons.jxpath;

import java.util.*;
import java.io.*;
import javax.xml.transform.TransformerFactory;

/**
 * Defines a factory API that enables applications to obtain a
 * JXPathContext instance.  To acquire a JXPathContext, first call the
 * static <code>newInstance()</code> method of JXPathContextFactory.
 * This method returns a concrete JXPathContextFactory.
 * Then call <code>newContext()</code> on that instance.  You will rarely
 * need to perform these steps explicitly: usually you can call one of the
 * <code>JXPathContex.newContext</code> methods, which will perform these steps
 * for you.
 *
 * @see JXPathContext#newContext(Object)
 * @see JXPathContext#newContext(JXPathContext,Object)
 * @see JXPathContext#newContext(Object,Variables)
 * @see JXPathContext#newContext(JXPathContext,Object,Variables)
 *
 * @author Dmitri Plotnikov
 * @version $Revision: 1.1 $ $Date: 2001/08/23 00:46:58 $
 */
public abstract class JXPathContextFactory {

    /** The default property */
    private static final String defaultProp =
        "org.apache.commons.jxpath.JXPathContextFactory";

    /** The default property prefix */
    private static final String defaultPropPrefix =
        "org.apache.commons.jxpath.JXPathContextFactory.";

    private static final Map defaultClasses = new HashMap();
    static {
        defaultClasses.put(
            defaultPropPrefix + "org.apache.xalan.processor.TransformerFactoryImpl",
            "org.apache.commons.jxpath.xalan.JXPathContextFactoryXalanImpl");
    }

    protected JXPathContextFactory () {

    }

    /**
     * Obtain a new instance of a <code>JXPathContextFactory</code>.
     * This static method creates a new factory instance.
     * This method uses the following ordered lookup procedure to determine
     * the <code>JXPathContextFactory</code> implementation class to load:
     * <ul>
     * <li>
     * Use the <code>org.apache.commons.jxpath.JXPathContextFactory</code> system
     * property.
     * </li>
     * <li>
     * Construct a Factory ID:
     * <ul>
     * <li>
     * Allocate a <code>TransformerFactory</code> using the
     * <code>TransformerFactory.newInstance()</code> method.
     * </li>
     * <li>
     * Concatenate <code>org.apache.commons.jxpath.JXPathContextFactory.</code>
     * and the name of the TransformerFactory's class.
     * </li>
     * </ul>
     * For example, if the current implementation of XSLT is Xalan,
     * the Factory ID will be
     * <code>org.apache.commons.jxpath.JXPathContextFactory.org.apache.xalan.processor.TransformerFactoryImpl</code>.
     * Use this Factory ID as a system property.
     * </li>
     * <li>
     * Use the JAVA_HOME(the parent directory where jdk is
     * installed)/lib/jxpath.properties for a property file that contains the
     * name of the implementation class keyed on
     * <code>org.apache.commons.jxpath.JXPathContextFactory</code>.
     * </li>
     * <li>
     * Use the JAVA_HOME(the parent directory where jdk is
     * installed)/lib/jxpath.properties for a property file that contains the
     * name of the implementation class keyed on the Factory ID.
     * </li>
     * <li>
     * 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
     * <code>META-INF/services/<i>Factory ID</i></code>
     * in jars available to the runtime.
     * </li>
     * <li>
     * Platform default <code>JXPathContextFactory</code> instance for the Factory ID.
     * </li>
     * </ul>
     *
     * Once an application has obtained a reference to a
     * <code>JXPathContextFactory</code> it can use the factory to
     * obtain JXPathContext instances.
     *
     * @exception JXPathFactoryConfigurationError if the implementation is not
     * available or cannot be instantiated.
     */

    public static JXPathContextFactory newInstance() {
        String name = TransformerFactory.newInstance().getClass().getName();
        String factoryId = defaultPropPrefix + name;

        // the default can be removed after services are tested well enough
        String defaultFactoryImplName = (String)defaultClasses.get(factoryId);
        String factoryImplName = findFactory(defaultProp, factoryId, defaultFactoryImplName);

        if (factoryImplName == null) {
            throw new JXPathContextFactoryConfigurationError(
                "No default implementation found");
        }

        JXPathContextFactory factoryImpl;
        try {
            Class clazz = Class.forName(factoryImplName);
            factoryImpl = (JXPathContextFactory)clazz.newInstance();
        } catch  (ClassNotFoundException cnfe) {
            throw new JXPathContextFactoryConfigurationError(cnfe);
        } catch (IllegalAccessException iae) {
            throw new JXPathContextFactoryConfigurationError(iae);
        } catch (InstantiationException ie) {
            throw new JXPathContextFactoryConfigurationError(ie);
        }
        return factoryImpl;
    }

    /**
     * Creates a new instance of a JXPathContext using the
     * currently configured parameters.
     *
     * @exception JXPathContextFactoryConfigurationError if a JXPathContext
     * cannot be created which satisfies the configuration requested
     */

    public abstract JXPathContext newContext(JXPathContext parentContext, Object contextBean, Variables vars)
        throws JXPathContextFactoryConfigurationError;

    // -------------------- private methods --------------------
    // This code is duplicated in all factories.
    // Keep it in sync or move it to a common place
    // Because it's small probably it's easier to keep it here
    /** Avoid reading all the files when the findFactory
        method is called the second time ( cache the result of
        finding the default impl )
    */
    private static String foundFactory=null;

    /** Temp debug code - this will be removed after we test everything
     */
    private static boolean debug=false;
    static {
    try {
        debug=System.getProperty( "jxpath.debug" ) != null;
    } catch(SecurityException se ) {}
    }

    /** Private implementation method - will find the implementation
        class in the specified order.
        @param property    Property name
        @param factoryId   Qualified property name
        @param defaultFactory Default implementation, if nothing else is found
    */
    private static String findFactory(String property,
                                      String factoryId,
                                      String defaultFactory)
    {
        // Use the system property first
        try {
            String systemProp = System.getProperty( property );
            if( systemProp!=null) {
                if( debug )
                    System.err.println("JXPath: found system property" +
                                       systemProp );
                return systemProp;
            }

        }catch (SecurityException se) {
        }

        if( foundFactory!=null)
            return foundFactory;

        // Use the factory ID system property first
        try {
            String systemProp =
                System.getProperty( factoryId );
            if( systemProp!=null) {
                if( debug )
                    System.err.println("JXPath: found system property" +
                                       systemProp );
                return systemProp;
            }

        }catch (SecurityException se) {
        }

        // try to read from $java.home/lib/xml.properties
        try {
            String javah=System.getProperty( "java.home" );
            String configFile = javah + File.separator +
                "lib" + File.separator + "jxpath.properties";
            File f=new File( configFile );
            if( f.exists()) {
                Properties props=new Properties();
                props.load( new FileInputStream(f));
                foundFactory=props.getProperty( property );
                if( debug )
                    System.err.println("JXPath: found java.home property " +
                                       foundFactory );
                if(foundFactory!=null )
                    return foundFactory;

                foundFactory=props.getProperty( factoryId );
                if( debug )
                    System.err.println("JXPath: found java.home property " +
                                       foundFactory );
                if(foundFactory!=null )
                    return foundFactory;
            }
        } catch(Exception ex ) {
            if( debug ) ex.printStackTrace();
        }

        String serviceId = "META-INF/services/" + factoryId;
        // try to find services in CLASSPATH
        try {
            ClassLoader cl=JXPathContextFactory.class.getClassLoader();
            InputStream is=null;
            if( cl == null ) {
                is=ClassLoader.getSystemResourceAsStream( serviceId );
            } else {
                is=cl.getResourceAsStream( serviceId );
            }

            if( is!=null ) {
                if( debug )
                    System.err.println("JXPath: found  " +
                                       serviceId);
                BufferedReader rd=new BufferedReader( new
                    InputStreamReader(is));

                foundFactory=rd.readLine();
                rd.close();

                if( debug )
                    System.err.println("JXPath: loaded from services: " +
                                       foundFactory );
                if( foundFactory != null &&
                    !  "".equals( foundFactory) ) {
                    return foundFactory;
                }
            }
        } catch( Exception ex ) {
            if( debug ) ex.printStackTrace();
        }

        return defaultFactory;
    }
}