/* DriverManager.java -- Manage JDBC drivers
   Copyright (C) 1999, 2000, 2001, 2003, 2004, 2006
   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 java.sql;

import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Vector;

/**
  * This class manages the JDBC drivers in the system. It maintains a
  * registry of drivers and locates the appropriate driver to handle a
  * JDBC database URL.
  * <p>
  * On startup, <code>DriverManager</code> loads all the managers specified
  * by the system property <code>jdbc.drivers</code>.  The value of this
  * property should be a colon separated list of fully qualified driver
  * class names.  Additional drivers can be loaded at any time by
  * simply loading the driver class with <code>class.forName(String)</code>.
  * The driver should automatically register itself in a static 
  * initializer.
  * <p>
  * The methods in this class are all <code>static</code>. This class
  * cannot be instantiated.
  *
  * @author Aaron M. Renn (arenn@urbanophile.com)
  */
public class DriverManager 
{
  /**
   * This is the log stream for JDBC drivers.
   */
  private static PrintStream log_stream;

  /**
   * This is the log writer for JDBC drivers.
   */
  private static PrintWriter log_writer;

  /**
   * This is the login timeout used by JDBC drivers.
   */
  private static int login_timeout;

  /**
   * This is the list of JDBC drivers that are loaded.
   */
  private static Vector drivers;
   // Hmm, seems like we might want to do a Hashtable and lookup by something,
   // but what would it be?

  // Load all drivers on startup
  static
  {
    drivers = new Vector();

    String driver_string = System.getProperty("jdbc.drivers");
    if (driver_string != null)
      {
	StringTokenizer st = new StringTokenizer(driver_string);
	while (st.hasMoreTokens())
          {
            String driver_classname = st.nextToken();

            try
              {
        	Class.forName(driver_classname); // The driver registers itself
              }
            catch (Exception e)
	      {
		// Ignore not founds
	      }
          }
      }

  }

  /** Can't be instantiated. */
  private DriverManager()
  {
  }

  /**
   * This method returns the log writer being used by all JDBC drivers.
   * This method should be used in place of the deprecated
   * <code>getLogStream</code> method.
   *
   * @return The log writer in use by JDBC drivers.
   */
  public static PrintWriter getLogWriter()
  {
    return log_writer;
  }
  
  /**
   * This method sets the log writer being used by JDBC drivers.  This is a
   * system-wide parameter that affects all drivers.  Note that since there
   * is no way to retrieve a <code>PrintStream</code> from a 
   * <code>PrintWriter</code>, this method cannot set the log stream in
   * use by JDBC.  Thus any older drivers may not see this setting.
   *
   * @param out The new log writer for JDBC.
   */
  public static void setLogWriter(PrintWriter out)
  {
    DriverManager.log_writer = out;
  }

/**
  * This method attempts to return a connection to the specified
  * JDBC URL string using the specified connection properties.
  *
  * @param url The JDBC URL string to connect to.
  * @param properties The connection properties.
  *
  * @return A <code>Connection</code> to that URL.
  *
  * @exception SQLException If an error occurs.
  */
  public static Connection getConnection(String url, Properties properties)
    throws SQLException
  {
    Driver d = getDriver(url);
    if (d == null)
      throw new SQLException("Driver not found for URL: " + url);

    return d.connect(url, properties);
  }


  /**
   * This method attempts to return a connection to the specified
   * JDBC URL string using the specified username and password.
   *
   * @param url The JDBC URL string to connect to.
   * @param user The username to connect with.
   * @param password The password to connect with.
   * @return A <code>Connection</code> to that URL.
   * @exception SQLException If an error occurs.
   */
  public static Connection getConnection(String url, String user,
    String password) throws SQLException
  {
    Properties p = new Properties();

    if (user != null)
      p.setProperty("user", user);
    if (password != null)
      p.setProperty("password", password);

    return getConnection(url, p);
  }

  /**
   * This method attempts to return a connection to the specified
   * JDBC URL string.
   *
   * @param url The JDBC URL string to connect to.
   *
   * @return A <code>Connection</code> to that URL.
   *
   * @exception SQLException If an error occurs.
   */
  public static Connection getConnection(String url) throws SQLException
  {
    return getConnection(url, new Properties());
  }

  /**
   * This method returns a driver that can connect to the specified
   * JDBC URL string.  This will be selected from among drivers loaded
   * at initialization time and those drivers manually loaded by the
   * same class loader as the caller.
   *
   * @param url The JDBC URL string to find a driver for.
   *
   * @return A <code>Driver</code> that can connect to the specified
   * URL.
   *
   * @exception SQLException If an error occurs, or no suitable driver can be found.
   */
  public static Driver getDriver(String url) throws SQLException
  {
    // FIXME: Limit driver search to the appropriate subset of loaded drivers.
    Enumeration e = drivers.elements();
    while(e.hasMoreElements())
      {
	Driver d = (Driver)e.nextElement();
	if (d.acceptsURL(url))
          return d;
      }

    throw new SQLException("No driver found for " + url);
  }

  /**
   * This method registers a new driver with the manager.  This is normally
   * called by the driver itself in a static initializer.
   *
   * @param driver The new <code>Driver</code> to add.
   *
   * @exception SQLException If an error occurs.
   */
  public static void registerDriver(Driver driver) throws SQLException
  {
    if (! drivers.contains(driver))
      drivers.addElement(driver);  
  }

/**
  * This method de-registers a driver from the manager.
  *
  * @param driver The <code>Driver</code> to unregister.
  *
  * @exception SQLException If an error occurs.
  */
  public static void deregisterDriver(Driver driver) throws SQLException
  {
    if (drivers.contains(driver))
      drivers.removeElement(driver);
  }

  /**
   * This method returns a list of all the currently registered JDBC drivers
   * that were loaded by the current <code>ClassLoader</code>.
   *
   * @return An <code>Enumeration</code> of all currently loaded JDBC drivers.
   */
  public static Enumeration getDrivers()
  {
    Vector v = new Vector();
    Enumeration e = drivers.elements();

    // Is this right?
    ClassLoader cl = Thread.currentThread().getContextClassLoader();

    while(e.hasMoreElements())
      {
	Object obj = e.nextElement();

	ClassLoader loader = obj.getClass().getClassLoader();

	if (loader == null)
	  loader = ClassLoader.getSystemClassLoader();
	if (! loader.equals(cl))
	  continue;

	v.addElement(obj);
      } 

    return v.elements();
  }

  /**
   * This method set the login timeout used by JDBC drivers.  This is a
   * system-wide parameter that applies to all drivers.
   *
   * @param seconds The new login timeout value.
   */
  public static void setLoginTimeout(int seconds)
  {
    DriverManager.login_timeout = seconds;  
  }

  /**
   * This method returns the login timeout in use by JDBC drivers systemwide.
   *
   * @return The login timeout.
   */
  public static int getLoginTimeout()
  {
    return login_timeout;
  }

  /**
   * This method sets the log stream in use by JDBC.
   *
   * @param stream The log stream in use by JDBC.
   * @deprecated Use <code>setLogWriter</code> instead.
   */
  public static void setLogStream(PrintStream stream)
  {
    DriverManager.log_stream = stream;
  }

  /**
   * This method returns the log stream in use by JDBC.
   *
   * @return The log stream in use by JDBC.
   * @deprecated Use <code>getLogWriter()</code> instead.
   */
  public static PrintStream getLogStream()
  {
    return log_stream;
  }

  /**
   * This method prints the specified line to the log stream.
   *
   * @param message The string to write to the log stream.
   */
  public static void println(String message)
  {
    if (log_stream != null) // Watch for user not using logging
      log_stream.println(message);
  }
}
