/* XPathFactory.java --
   Copyright (C) 2004, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package javax.xml.xpath;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Properties;

/**
 * Factory for creating XPath environments.
 *
 * @author (a href='mailto:dog@gnu.org'>Chris Burdess</a)
 * @since 1.3
 */
public abstract class XPathFactory
{

  /**
   * The default property name according to the JAXP specification.
   */
  public static final String DEFAULT_PROPERTY_NAME =
                "javax.xml.xpath.XPathFactory";

  /**
   * The default object model URI.
   */
  public static final String DEFAULT_OBJECT_MODEL_URI =
    XPathConstants.DOM_OBJECT_MODEL;

  protected XPathFactory()
  {
  }

  /**
   * Returns a new factory for the default (DOM) object model.
   */
  public static final XPathFactory newInstance()
  {
    try
      {
        return newInstance(DEFAULT_OBJECT_MODEL_URI);
      }
    catch (XPathFactoryConfigurationException e)
      {
        throw new RuntimeException(e.getMessage());
      }
  }

  /**
   * Returns a new factory for the given object model URI.
   * The implementation class to load is the first found in the following
   * locations that advertises support for the given model URI:
   * <ol>
   * <li>the <code>javax.xml.xpath.XPathFactory</code> system property</li>
   * <li>the above named property value in the
   * <code><i>$JAVA_HOME</i>/lib/jaxp.properties</code> file</li>
   * <li>the class name specified in the
   * <code>META-INF/services/javax.xml.xpath.XPathFactory</code> system
   * resource</li>
   * <li>the default factory class</li>
   * </ol>
   * @param uri the object model URI
   */
  public static final XPathFactory newInstance(String uri)
    throws XPathFactoryConfigurationException
  {
    ClassLoader loader = Thread.currentThread().getContextClassLoader();
    if (loader == null)
      {
        loader = XPathFactory.class.getClassLoader();
      }
    String className = null;
    int count = 0;
    do
      {
        className = getFactoryClassName(loader, count++);
        if (className != null)
          {
            try
              {
                Class<?> t = (loader != null) ? loader.loadClass(className) :
                  Class.forName(className);
                XPathFactory ret = (XPathFactory) t.newInstance();
                if (ret.isObjectModelSupported(uri))
                  {
                    return ret;
                  }
                className = null;
              }
            catch (ClassNotFoundException e)
              {
                className = null;
              }
            catch (Exception e)
              {
                throw new XPathFactoryConfigurationException(e);
              }
          }
      }
    while (className == null && count < 4);
    String msg = "no factories with support for " + uri;
    throw new XPathFactoryConfigurationException(msg);
  }

  private static String getFactoryClassName(ClassLoader loader, int attempt)
  {
    final String propertyName = DEFAULT_PROPERTY_NAME;
    switch (attempt)
      {
        case 0:
          return System.getProperty(propertyName);
        case 1:
          try
            {
              File file = new File(System.getProperty("java.home"));
              file = new File(file, "lib");
              file = new File(file, "jaxp.properties");
              InputStream in = new FileInputStream(file);
              Properties props = new Properties();
              props.load(in);
              in.close();
              return props.getProperty(propertyName);
            }
          catch (IOException e)
            {
              return null;
            }
        case 2:
          try
            {
              String serviceKey = "/META-INF/services/" + propertyName;
              InputStream in = (loader != null) ?
                loader.getResourceAsStream(serviceKey) :
                XPathFactory.class.getResourceAsStream(serviceKey);
              if (in != null)
                {
                  BufferedReader r =
                    new BufferedReader(new InputStreamReader(in));
                  String ret = r.readLine();
                  r.close();
                  return ret;
                }
            }
          catch (IOException e)
            {
            }
          return null;
        case 3:
          return "gnu.xml.xpath.XPathFactoryImpl";
        default:
          return null;
      }
  }

  /**
   * Indicates whether the specified object model URI is supported by
   * this factory.
   */
  public abstract boolean isObjectModelSupported(String objectModel);

  /**
   * Sets the state of the named feature.
   */
  public abstract void setFeature(String name, boolean value)
    throws XPathFactoryConfigurationException;

  /**
   * Returns the state of the named feature.
   */
  public abstract boolean getFeature(String name)
    throws XPathFactoryConfigurationException;

  /**
   * Sets the XPath variable resolver calback.
   */
  public abstract void setXPathVariableResolver(XPathVariableResolver resolver);

  /**
   * Sets the XPath extension function resolver calback.
   */
  public abstract void setXPathFunctionResolver(XPathFunctionResolver resolver);

  /**
   * Returns a new XPath evaluation environment.
   */
  public abstract XPath newXPath();

}
