You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by sb...@apache.org on 2001/01/04 11:10:10 UTC

cvs commit: xml-xalan/java/src/org/apache/xalan/lib/sql ConnectionPool.java DefaultConnectionPool.java ExtensionError.java PooledConnection.java QueryParameter.java SQLExtensionError.java XConnectionPoolManager.java ColumnAttribute.java XConnection.java XStatement.java package.html

sboag       01/01/04 02:10:09

  Modified:    java/src/org/apache/xalan/lib/sql ColumnAttribute.java
                        XConnection.java XStatement.java package.html
  Added:       java/src/org/apache/xalan/lib/sql ConnectionPool.java
                        DefaultConnectionPool.java ExtensionError.java
                        PooledConnection.java QueryParameter.java
                        SQLExtensionError.java XConnectionPoolManager.java
  Log:
  John Gentilin <johnglinux@eyecatching.com> work.  From note
  that John sent:
  
  Accomplished so far:
  Connection Pools,
  
  The way I implemented Connection Pools was to provide
  a controller that contains a list of named pools. This list is
  static, so as long as someone has an instance of the controller,
  the pools will  remain intact.  The Connection Pool is defined
  as a minimal interface. If you want to use you own  connection
  pool all you have to do is create an adapter class that implements
  the interface and register it with the controller. All of the original
  functionality was left intact to hold backward compatibility. There
  is a default connection pool that is implemented as part of the
  extension so the code will work without any external pool.
  I plan to  implement a wrapper around Apache Turbine pools
  as a sample.
  
  There are several examples. I used a database that I am currently
  working on. Is there a way to distribute samples that work stand alone.
  i.e. Do you know of a small DBMS implemented as a JAR that we can
  distribute in the lib dir ??
  
  As a helper function, I added a constructor that allows a single xpath
  statement to point to the DB connection Info. Its value is questionable,
  
  I was unaware that a function could take multiple xpath statements
  as arguments until Gary pointed it out. I thought you had to create
  several variables and pass them in separately which seemed messy.
  
  I still need to do the documentation, I have a design spec in a format
  that
  I am using internally but I need to reformat it for the apache code.
  I took a quick stab at it in the samples dir but it is know where
  complete.
  
  Parameterized Queries,
  
  You can set your query to contain the "?" that are used in
  PreparedStatements. Then pass in the matching parameters
  using data from the source document. The type information
  can either be passed in as a comma separated string as a
  second parameter of the pquery statement or as part of the
  data. You will have to look at the code comments for this one
  as I have not even touched the docs on this one.
  
  Error handling through XML formatted responses.
  
  This is experimental code, I just wanted to see how it works.
  The information in the XML document is minimal, if we decide
  that this is a valid approach, the implementation need quite a bit
  of clean up.
  
  Revision  Changes    Path
  1.6       +1 -1      xml-xalan/java/src/org/apache/xalan/lib/sql/ColumnAttribute.java
  
  Index: ColumnAttribute.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/lib/sql/ColumnAttribute.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ColumnAttribute.java	2001/01/02 03:36:38	1.5
  +++ ColumnAttribute.java	2001/01/04 10:10:09	1.6
  @@ -92,7 +92,7 @@
    *   <li>writable</li>
    *   <li>searchable</li>
    * </ul>
  - * @see org.apache.xalan.lib.sql.ColumnHeader
  + * @see org.apache.xalan.lib.sql.ColumnHeader.
    */
   public class ColumnAttribute extends StreamableNode implements Attr
   {
  
  
  
  1.6       +538 -113  xml-xalan/java/src/org/apache/xalan/lib/sql/XConnection.java
  
  Index: XConnection.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/lib/sql/XConnection.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- XConnection.java	2000/12/14 19:06:08	1.5
  +++ XConnection.java	2001/01/04 10:10:09	1.6
  @@ -2,7 +2,7 @@
    * The Apache Software License, Version 1.1
    *
    *
  - * Copyright (c) 1999 The Apache Software Foundation.  All rights 
  + * Copyright (c) 1999 The Apache Software Foundation.  All rights
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -10,7 +10,7 @@
    * are met:
    *
    * 1. Redistributions of source code must retain the above copyright
  - *    notice, this list of conditions and the following disclaimer. 
  + *    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
  @@ -18,7 +18,7 @@
    *    distribution.
    *
    * 3. The end-user documentation included with the redistribution,
  - *    if any, must include the following acknowledgment:  
  + *    if any, must include the following acknowledgment:
    *       "This product includes software developed by the
    *        Apache Software Foundation (http://www.apache.org/)."
    *    Alternately, this acknowledgment may appear in the software itself,
  @@ -26,7 +26,7 @@
    *
    * 4. The names "Xalan" and "Apache Software Foundation" must
    *    not be used to endorse or promote products derived from this
  - *    software without prior written permission. For written 
  + *    software without prior written permission. For written
    *    permission, please contact apache@apache.org.
    *
    * 5. Products derived from this software may not be called "Apache",
  @@ -62,13 +62,18 @@
   import java.sql.SQLException;
   
   import java.util.Properties;
  +import java.util.Vector;
  +import java.util.StringTokenizer;
   
  -import org.xml.sax.AttributeList;
   
   import org.w3c.dom.Element;
   import org.w3c.dom.NamedNodeMap;
   import org.w3c.dom.traversal.NodeIterator;
  +import org.w3c.dom.NodeList;
  +import org.w3c.dom.Node;
   
  +import org.apache.xalan.stree.ElementImpl;
  +
   /**
    * An XSLT extension that allows a stylesheet to
    * access JDBC data. From the stylesheet perspective,
  @@ -85,54 +90,152 @@
   public class XConnection
   {
   
  -  /** Flag for DEBUG mode          */
  -  private static final boolean DEBUG = false;
  -
     /**
  -   * A JDBC driver of the form "foo.bar.Driver".
  +   * Flag for DEBUG mode
      */
  -  public String m_driver;
  +  private static final boolean DEBUG = false;
   
  -  /**
  -   * A database URL of the form jdbc:subprotocol:subname.
  -   */
  -  public String m_dbURL;
   
     /**
  -   * A user ID.
  +   * The JDBC connection.
      */
  -  public String m_user;
  +  public Connection m_connection = null;
   
     /**
  -   * A password.
  +   * Reference to the ConnectionPool used
      */
  -  public String m_password;
  +  public ConnectionPool m_ConnectionPool;
   
  +
     /**
  -   * A list of arbitrary string tag/value pairs as connection
  -   * arguments; normally at least a "user" and "password"
  -   * property should be included.
  +   * For PreparedStatements, we need a place to
  +   * to store the parameters in a vector.
      */
  -  public Properties m_protocol;
  +   public Vector        m_ParameterList = new Vector();
  +
  +
  +  // The original constructors will be kept around for backwards
  +  // compatibility. Future Stylesheets should use the approaite
  +  // connect method to receive full error information.
  +  //
  +  public XConnection (String ConnPoolName)
  +  {
  +    connect(ConnPoolName);
  +  }
   
  +  public XConnection(String driver, String dbURL)
  +  {
  +    connect(driver, dbURL);
  +  }
  +
  +  public XConnection(NodeList list)
  +  {
  +    connect(list);
  +  }
  +
  +  public XConnection(String driver, String dbURL, String user,
  +                     String password)
  +  {
  +    connect(driver, dbURL, user, password);
  +  }
  +
  +  public XConnection(String driver, String dbURL, Element protocolElem)
  +  {
  +    connect(driver, dbURL, protocolElem);
  +  }
  +
     /**
  -   * The JDBC connection.
  +   *
  +   * Create an XConnection using the name of an existing Connection Pool
  +   * @param <code>String poolName</code>, name of the existing pool
  +   * to pull connections from.
  +   *
      */
  -  public Connection m_connection = null;
  +  public NodeIterator connect(String ConnPoolName)
  +  {
  +    try
  +    {
  +      XConnectionPoolManager mgr = new XConnectionPoolManager();
  +      m_ConnectionPool = mgr.getPool(ConnPoolName);
  +      m_connection = m_ConnectionPool.getConnection();
  +    }
  +    catch(SQLException e)
  +    {
  +      SQLExtensionError err = new SQLExtensionError(e);
  +      return err;
  +    }
   
  +    return null;
  +  }
  +
     /**
      * Create an XConnection object with just a driver and database URL.
      * @param driver JDBC driver of the form foo.bar.Driver.
      * @param dbURL database URL of the form jdbc:subprotocol:subname.
      */
  -  public XConnection(String driver, String dbURL)
  +
  +  public NodeIterator connect(String driver, String dbURL)
     {
  +    try
  +    {
  +      init(driver, dbURL, new Properties() );
  +    }
  +    catch(SQLException e)
  +    {
  +      SQLExtensionError err = new SQLExtensionError(e);
  +      return err;
  +    }
  +    catch (Exception e)
  +    {
  +      ExtensionError err = new ExtensionError(e);
  +      return err;
  +    }
   
  -    super();
  +    return null;
   
  -    init(driver, dbURL, null, null, null, 1);
     }
   
  +  public NodeIterator connect(Element protocolElem)
  +  {
  +    try
  +    {
  +      initFromElement(protocolElem);
  +    }
  +    catch(SQLException e)
  +    {
  +      SQLExtensionError err = new SQLExtensionError(e);
  +      return err;
  +    }
  +    catch (Exception e)
  +    {
  +      ExtensionError err = new ExtensionError(e);
  +      return err;
  +    }
  +
  +    return null;
  +
  +  }
  +
  +  public NodeIterator connect(NodeList list)
  +  {
  +    try
  +    {
  +      initFromElement( (Element) list.item(0) );
  +    }
  +    catch(SQLException e)
  +    {
  +      SQLExtensionError err = new SQLExtensionError(e);
  +      return err;
  +    }
  +    catch (Exception e)
  +    {
  +      ExtensionError err = new ExtensionError(e);
  +      return err;
  +    }
  +
  +    return null;
  +  }
  +
     /**
      * Create an XConnection object with user ID and password.
      * @param driver JDBC driver of the form foo.bar.Driver.
  @@ -140,15 +243,32 @@
      * @param user user ID.
      * @param password connection password.
      */
  -  public XConnection(String driver, String dbURL, String user,
  +  public NodeIterator connect(String driver, String dbURL, String user,
                        String password)
     {
  +    try
  +    {
  +      Properties prop = new Properties();
  +      prop.setProperty("user", user);
  +      prop.setProperty("password", password);
   
  -    super();
  +      init(driver, dbURL, prop);
  +    }
  +    catch(SQLException e)
  +    {
  +      SQLExtensionError err = new SQLExtensionError(e);
  +      return err;
  +    }
  +    catch (Exception e)
  +    {
  +      ExtensionError err = new ExtensionError(e);
  +      return err;
  +    }
   
  -    init(driver, dbURL, user, password, null, 3);
  +    return null;
     }
   
  +
     /**
      * Create an XConnection object with a connection protocol
      * @param driver JDBC driver of the form foo.bar.Driver.
  @@ -156,131 +276,420 @@
      * @param protocolElem list of string tag/value connection arguments,
      * normally including at least "user" and "password".
      */
  -  public XConnection(String driver, String dbURL, Element protocolElem)
  +  public NodeIterator connect(String driver, String dbURL, Element protocolElem)
     {
  +    try
  +    {
  +      Properties prop = new Properties();
  +
  +      NamedNodeMap atts = protocolElem.getAttributes();
  +
  +      for (int i = 0; i < atts.getLength(); i++)
  +      {
  +        prop.put(atts.item(i).getNodeName(), atts.item(i).getNodeValue());
  +      }
   
  -    super();
  +      init(driver, dbURL, prop);
  +    }
  +    catch(SQLException e)
  +    {
  +      SQLExtensionError err = new SQLExtensionError(e);
  +      return err;
  +    }
  +    catch (Exception e)
  +    {
  +      ExtensionError err = new ExtensionError(e);
  +      return err;
  +    }
   
  -    init(driver, dbURL, null, null, protocolElem, 2);
  +    return null;
     }
   
  +
     /**
  -   * Initialize.
      *
  -   * @param driver JDBC driver of the form foo.bar.Driver.
  -   * @param dbURL database URL of the form jdbc:subprotocol:subname.
  -   * @param user user ID
  -   * @param password connection password.
  -   * @param protocolElem list of string tag/value connection arguments,
  -   * normally including at least "user" and "password".
  -   * @param getConnectionArgs Connection arguments
  +   * Allow the database connection information to be sepcified in
  +   * the XML tree. The connection information could also be
  +   * externally originated and passed in as an XSL Parameter.
  +   *
  +   * The required XML Format is as follows.
  +   *
  +   * // A document fragment is needed to specify the connection information
  +   * // the top tag name is not specific for this code, we are only interested
  +   * // in the tags inside.
  +   * <DBINFO-TAG>
  +   *
  +   * // Specify the driver name for this connection pool
  +   *  <dbdriver>drivername</dbdriver>
  +   *
  +   * // Specify the URL for the driver in this connection pool
  +   *  <dburl>url</dburl>
  +   *
  +   * // Specify the password for this connection pool
  +   *  <password>password</password>
  +   *
  +   * // Specify the username for this connection pool
  +   *  <user>username</user>
  +   *
  +   *  // You can add extra protocol items including the User Name & Password
  +   *  // with the protocol tag. For each extra protocol item, add a new element
  +   *  // where the name of the item is specified as the name attribute and
  +   *  // and its value as the elements value.
  +   *  <protocol name="name of value">value</protocol>
  +   *
  +   * </DBINFO-TAG>
  +   *
      */
  -  private void init(String driver, String dbURL, String user,
  -                    String password, Element protocolElem,
  -                    int getConnectionArgs)
  +  private void initFromElement(Element e)
  +    throws SQLException
     {
   
  -    m_driver = driver;
  -    m_dbURL = dbURL;
  -    m_user = user;
  -    m_password = password;
  +    Properties prop = new Properties();
  +    String driver = "";
  +    String dbURL = "";
  +    Node n = e.getFirstChild();
   
  -    if (protocolElem == null)
  -      m_protocol = null;
  -    else
  +    if (null == n) return; // really need to throw an error
  +
  +    do
       {
  -      m_protocol = new Properties();
  +      String nName = n.getNodeName();
   
  -      NamedNodeMap atts = protocolElem.getAttributes();
  +      if (nName.equalsIgnoreCase("dbdriver"))
  +      {
  +        driver = "";
  +        Node n1 = n.getFirstChild();
  +        if (null != n1)
  +        {
  +          driver = n1.getNodeValue();
  +        }
  +      }
   
  -      for (int i = 0; i < atts.getLength(); i++)
  +      if (nName.equalsIgnoreCase("dburl"))
         {
  -        m_protocol.put(atts.item(i).getNodeName(),
  -                       atts.item(i).getNodeValue());
  +        dbURL = "";
  +        Node n1 = n.getFirstChild();
  +        if (null != n1)
  +        {
  +          dbURL = n1.getNodeValue();
  +        }
         }
  -    }
  +
  +      if (nName.equalsIgnoreCase("password"))
  +      {
  +        String s = "";
  +        Node n1 = n.getFirstChild();
  +        if (null != n1)
  +        {
  +          s = n1.getNodeValue();
  +        }
  +        prop.setProperty("password", s);
  +      }
   
  -    connect(driver, dbURL, user, password, m_protocol, getConnectionArgs);
  +      if (nName.equalsIgnoreCase("user"))
  +      {
  +        String s = "";
  +        Node n1 = n.getFirstChild();
  +        if (null != n1)
  +        {
  +          s = n1.getNodeValue();
  +        }
  +        prop.setProperty("user", s);
  +      }
  +
  +      if (nName.equalsIgnoreCase("protocol"))
  +      {
  +        String Name = "";
  +
  +        NamedNodeMap attrs = n.getAttributes();
  +        Node n1 = attrs.getNamedItem("name");
  +        if (null != n1)
  +        {
  +          String s = "";
  +          Name = n1.getNodeValue();
  +
  +          Node n2 = n.getFirstChild();
  +          if (null != n2) s = n2.getNodeValue();
  +
  +          prop.setProperty(Name, s);
  +        }
  +      }
  +
  +    } while ( (n = n.getNextSibling()) != null);
  +
  +    init(driver, dbURL, prop);
     }
   
  +
  +
     /**
  -   * Connect to the JDBC database.
  -   * @param driver Database url of the form jdbc:subprotocol:subname .
  +   * Initilize is being called because we did not have an
  +   * existing Connection Pool, so let's see if we created one
  +   * already or lets create one ourselves.
  +   *
  +   * @param driver JDBC driver of the form foo.bar.Driver.
      * @param dbURL database URL of the form jdbc:subprotocol:subname.
  -   * @param user user ID
  -   * @param password connection password.
  -   * @param protocol List of arbitrary string tag/value pairs as
  -   * connection arguments; normally at least a "user" and "password"
  -   * property should be included.
  +   * @param Properties list of string tag/value connection arguments,
  +   * normally including at least "user" and "password".
      * @param getConnectionArgs Connection arguments
      */
  -  public void connect(String driver, String dbURL, String user,
  -                      String password, Properties protocol,
  -                      int getConnectionArgs)
  +  private void init(String driver, String dbURL, Properties prop)
  +    throws SQLException
     {
  +    String user = prop.getProperty("user");
  +    if (user == null) user = "";
   
  -    try
  +    String passwd = prop.getProperty("password");
  +    if (passwd == null) passwd = "";
  +
  +    String poolName = driver + dbURL + user + passwd;
  +
  +    XConnectionPoolManager mgr = new XConnectionPoolManager();
  +
  +    m_ConnectionPool = mgr.getPool(poolName);
  +    if (m_ConnectionPool == null)
       {
  +      DefaultConnectionPool defpool = new DefaultConnectionPool();
  +      defpool.setDriver(driver);
  +      defpool.setURL(dbURL);
  +      defpool.setProtocol(prop);
  +      defpool.setActive(true);
   
  -      // The driver is installed by loading its class.
  -      Class.forName(driver).newInstance();
  +      mgr.registerPool(poolName, defpool);
   
  -      // Use the appropriate getConnection() method.
  -      switch (getConnectionArgs)
  -      {
  -      case 1 :
  -        m_connection = DriverManager.getConnection(dbURL);
  -        break;
  -      case 2 :
  -        m_connection = DriverManager.getConnection(dbURL, protocol);
  -        break;
  -      case 3 :
  -        m_connection = DriverManager.getConnection(dbURL, user, password);
  -      }
  +      m_ConnectionPool = defpool;
  +    }
   
  -      /*
  -      We could also turn autocommit off by putting
  -      ;autocommit=false on the URL.
  -      */
  -      try
  -      {
  -        m_connection.setAutoCommit(false);
  -      }
  -      catch(java.sql.SQLException se)
  -      {
  -        // Some drivers do not support transactions
  -      }
   
  -      DatabaseMetaData dma = m_connection.getMetaData();
  +    m_connection = m_ConnectionPool.getConnection();
  +  }
   
  -      if (DEBUG)
  -      {
  -        System.out.println("\nConnected to " + dma.getURL());
  -        System.out.println("Driver   " + dma.getDriverName());
  -        System.out.println("Version  " + dma.getDriverVersion());
  -        System.out.println("");
  -      }
  +
  +  /**
  +   * Execute a query statement by instantiating an
  +   * {@link org.apache.xalan.lib.sql.XStatement XStatement}
  +   * object. The XStatement executes the query, and uses the result set
  +   * to create a {@link org.apache.xalan.lib.sql.RowSet RowSet},
  +   * a row-set element.
  +   *
  +   * @param queryString the SQL query.
  +   * @return XStatement implements NodeIterator.
  +   *
  +   * @throws SQLException
  +   */
  +  public NodeIterator query(String queryString)
  +  {
  +    try
  +    {
  +      return new XStatement(this, queryString);
  +    }
  +    catch(SQLException e)
  +    {
  +      SQLExtensionError err = new SQLExtensionError(e);
  +      return err;
  +    }
  +    catch (Exception e)
  +    {
  +      ExtensionError err = new ExtensionError(e);
  +      return err;
  +    }
  +
  +  }
  +
  +  /**
  +   * Execute a parameterized query statement by instantiating an
  +   * {@link org.apache.xalan.lib.sql.XStatement XStatement}
  +   * object. The XStatement executes the query, and uses the result set
  +   * to create a {@link org.apache.xalan.lib.sql.RowSet RowSet},
  +   * a row-set element.
  +   *
  +   * @param queryString the SQL query.
  +   * @return XStatement implements NodeIterator.
  +   *
  +   * @throws SQLException
  +   */
  +  public NodeIterator pquery(String queryString)
  +  {
  +    try
  +    {
  +      return new XStatement(this, queryString, m_ParameterList);
  +    }
  +    catch(SQLException e)
  +    {
  +      SQLExtensionError err = new SQLExtensionError(e);
  +      return err;
       }
  -    catch (Throwable e)
  +    catch (Exception e)
       {
  -      e.printStackTrace();
  +      ExtensionError err = new ExtensionError(e);
  +      return err;
       }
  +
  +
     }
   
  +
     /**
  -   * Execute a query statement by instantiating an {@link org.apache.xalan.lib.sql.XStatement XStatement}
  -   * object. The XStatement executes the query, and uses the result set to create a
  -   * {@link org.apache.xalan.lib.sql.RowSet RowSet}, a row-set element.
  +   * Execute a parameterized query statement by instantiating an
  +   * {@link org.apache.xalan.lib.sql.XStatement XStatement}
  +   * object. The XStatement executes the query, and uses the result set
  +   * to create a {@link org.apache.xalan.lib.sql.RowSet RowSet},
  +   * a row-set element.
  +   * This method allows for the user to pass in a comma seperated
  +   * String that represents a list of parameter types. If supplied
  +   * the parameter types will be used to overload the current types
  +   * in the current parameter list.
  +   *
      * @param queryString the SQL query.
      * @return XStatement implements NodeIterator.
      *
      * @throws SQLException
  +   */
  +  public NodeIterator pquery(String queryString, String typeInfo)
  +  {
  +    try
  +    {
  +      int indx = 0;
  +      QueryParameter param = null;
  +
  +      // Parse up the parameter types that were defined
  +      // with the query
  +      StringTokenizer plist = new StringTokenizer(typeInfo);
  +
  +      // Override the existing type that is stored in the
  +      // parameter list. If there are more types than parameters
  +      // ignore for now, a more meaningfull error should occur
  +      // when the actual query is executed.
  +      while (plist.hasMoreTokens())
  +      {
  +        String value = plist.nextToken();
  +        param = (QueryParameter) m_ParameterList.elementAt(indx);
  +        if ( null != param )
  +        {
  +          param.setType(value);
  +        }
  +      }
  +
  +      return new XStatement(this, queryString, m_ParameterList);
  +    }
  +    catch(SQLException e)
  +    {
  +      SQLExtensionError err = new SQLExtensionError(e);
  +      return err;
  +    }
  +    catch (Exception e)
  +    {
  +      ExtensionError err = new ExtensionError(e);
  +      return err;
  +    }
  +
  +
  +  }
  +
  +  /**
  +   * Add an untyped value to the parameter list.
  +   */
  +  public void addParameter(String value)
  +  {
  +    addParameterWithType(value, null);
  +  }
  +
  +  /**
  +   * Add a typed parameter to the parameter list.
  +   */
  +  public void addParameterWithType(String value, String Type)
  +  {
  +    m_ParameterList.add( new QueryParameter(value, Type) );
  +  }
  +
  +
  +  /**
  +   * Add a single parameter to the parameter list
  +   * formatted as an Element
      */
  -  public NodeIterator query(String queryString) throws SQLException
  +  public void addParameterFromElement(Element e)
  +  {
  +    NamedNodeMap attrs = e.getAttributes();
  +    Node Type = attrs.getNamedItem("type");
  +    Node n1  = e.getFirstChild();
  +    if (null != n1)
  +    {
  +      String value = n1.getNodeValue();
  +      if (value == null) value = "";
  +      m_ParameterList.add( new QueryParameter(value, Type.getNodeValue()) );
  +    }
  +  }
  +
  +
  +  /**
  +   * Add a section of parameters to the Parameter List
  +   * Do each element from the list
  +   */
  +  public void addParameterFromElement(NodeList nl)
  +  {
  +    //
  +    // Each child of the NodeList represents a node
  +    // match from the select= statment. Process each
  +    // of them as a seperate list.
  +    // The XML Format is as follows
  +    //
  +    // <START-TAG>
  +    //   <TAG1 type="int">value</TAG1>
  +    //   <TAGA type="int">value</TAGA>
  +    //   <TAG2 type="string">value</TAG2>
  +    // </START-TAG>
  +    //
  +    // The XSL to process this is formatted as follows
  +    // <xsl:param name="plist" select="//START-TAG" />
  +    // <sql:addParameter( $plist );
  +    //
  +    int count = nl.getLength();
  +    for (int x=0; x<count; x++)
  +    {
  +      addParameters( (Element) nl.item(x));
  +    }
  +  }
  +
  +  private void addParameters(Element elem)
     {
  +    //
  +    // Process all of the Child Elements
  +    // The format is as follows
  +    //
  +    //<TAG type ="typeid">value</TAG>
  +    //<TAG1 type ="typeid">value</TAG1>
  +    //<TAGA type ="typeid">value</TAGA>
  +    //
  +    // The name of the Node is not important just is value
  +    // and if it contains a type attribute
  +
  +    Node n = elem.getFirstChild();
  +
  +    if (null == n) return;
   
  -    // TODO: These need to be pooled.
  -    return new XStatement(this, queryString);
  +    do
  +    {
  +      if (n.getNodeType() == Node.ELEMENT_NODE)
  +      {
  +        NamedNodeMap attrs = n.getAttributes();
  +        Node Type = attrs.getNamedItem("type");
  +        String TypeStr;
  +
  +        if (Type == null) TypeStr = "string";
  +        else TypeStr = Type.getNodeValue();
  +
  +        Node n1  = n.getFirstChild();
  +        if (null != n1)
  +        {
  +          String value = n1.getNodeValue();
  +          if (value == null) value = "";
  +
  +
  +          m_ParameterList.add(
  +            new QueryParameter(value, TypeStr) );
  +        }
  +      }
  +    } while ( (n = n.getNextSibling()) != null);
     }
   
     /**
  @@ -297,12 +706,28 @@
   
       if (null != m_connection)
       {
  -      m_connection.close();
  +      if (null != m_ConnectionPool)
  +      {
  +        m_ConnectionPool.releaseConnection(m_connection);
   
  -      m_connection = null;
  +      }
  +      else
  +      {
  +        // something is wrong here, we have a connection
  +        // but no controlling pool, close it anyway the
  +        // error will show up as an excpeion elsewhere
  +        m_connection.close();
  +      }
       }
   
  +    m_connection = null;
  +
       if (DEBUG)
         System.out.println("Exiting XConnection.close");
  +  }
  +
  +  protected void finalize()
  +  {
  +    if (DEBUG) System.out.println("In XConnection, finalize");
     }
   }
  
  
  
  1.7       +159 -24   xml-xalan/java/src/org/apache/xalan/lib/sql/XStatement.java
  
  Index: XStatement.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/lib/sql/XStatement.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- XStatement.java	2000/12/14 19:06:08	1.6
  +++ XStatement.java	2001/01/04 10:10:09	1.7
  @@ -2,7 +2,7 @@
    * The Apache Software License, Version 1.1
    *
    *
  - * Copyright (c) 1999 The Apache Software Foundation.  All rights 
  + * Copyright (c) 1999 The Apache Software Foundation.  All rights
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -10,7 +10,7 @@
    * are met:
    *
    * 1. Redistributions of source code must retain the above copyright
  - *    notice, this list of conditions and the following disclaimer. 
  + *    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
  @@ -18,7 +18,7 @@
    *    distribution.
    *
    * 3. The end-user documentation included with the redistribution,
  - *    if any, must include the following acknowledgment:  
  + *    if any, must include the following acknowledgment:
    *       "This product includes software developed by the
    *        Apache Software Foundation (http://www.apache.org/)."
    *    Alternately, this acknowledgment may appear in the software itself,
  @@ -26,7 +26,7 @@
    *
    * 4. The names "Xalan" and "Apache Software Foundation" must
    *    not be used to endorse or promote products derived from this
  - *    software without prior written permission. For written 
  + *    software without prior written permission. For written
    *    permission, please contact apache@apache.org.
    *
    * 5. Products derived from this software may not be called "Apache",
  @@ -63,9 +63,23 @@
   import org.w3c.dom.DOMException;
   
   import java.sql.Statement;
  +import java.sql.PreparedStatement;
   import java.sql.SQLException;
   import java.sql.ResultSet;
   
  +import java.util.Vector;
  +import java.util.Iterator;
  +
  +import java.math.BigDecimal;
  +import java.math.BigInteger;
  +
  +import java.sql.Timestamp;
  +import java.sql.Time;
  +import java.sql.Date;
  +
  +import java.lang.Integer;
  +import java.lang.Double;
  +
   import org.apache.xpath.axes.ContextNodeList;
   import org.apache.xalan.res.XSLTErrorResources;
   
  @@ -81,14 +95,20 @@
     /** Flag for DEBUG mode          */
     private static final boolean DEBUG = false;
   
  -  /** JDBC Query statement          */
  -  private Statement m_statement;
  +  /**
  +   * Ths JDBC Statement that is used for the query.
  +   * It is allocated as a prepared statement but may
  +   * only be use as a regular statemwnt.
  +   *
  +   */
  +  private Statement         m_statement;
  +  private PreparedStatement m_pstatement;
   
     /** Node counter          */
     private int m_nodeCounter = 0;
   
     /**
  -   * Get And Increment Node Counter 
  +   * Get And Increment Node Counter
      *
      *
      * @return Node counter
  @@ -118,7 +138,7 @@
     ResultSet m_resultSet;
   
     /**
  -   * Get the ResultSet from executing the query string 
  +   * Get the ResultSet from executing the query string
      *
      *
      * @return ResultSet instance
  @@ -175,8 +195,11 @@
   
       // The SQL statement which lets us execute commands against the connection.
       m_xconnection = connection;
  +
       m_statement = m_xconnection.m_connection.createStatement();
  +
       m_queryString = queryString;
  +
       m_resultSet = m_statement.executeQuery(m_queryString);
       m_rowset = new RowSet(this);
   
  @@ -184,11 +207,123 @@
         System.out.println("Exiting XStatement constructor");
     }
   
  +  public XStatement(XConnection connection, String queryString, Vector pList)
  +          throws SQLException
  +  {
  +
  +    super(null);
  +
  +    if (DEBUG)
  +      System.out.println("In XStatement constructor for pquery");
  +
  +    // The SQL statement which lets us execute commands against the connection.
  +    m_xconnection = connection;
  +    m_queryString = queryString;
  +
  +    if (DEBUG)
  +    {
  +      System.out.println("Executing PQuery: " + m_queryString);
  +    }
  +    m_pstatement = m_xconnection.m_connection.prepareStatement(m_queryString);
  +    Iterator iter = pList.iterator();
  +    int indx = 1;
  +    while (iter.hasNext())
  +    {
  +      QueryParameter param = (QueryParameter) iter.next();
  +      setParameter(indx, m_pstatement, param);
  +      indx++;
  +    }
  +
  +    m_resultSet = m_pstatement.executeQuery();
  +    m_rowset = new RowSet(this);
  +
  +    //
  +    // Make a copy of the statement for external access
  +    m_statement = m_pstatement;
  +
  +    if (DEBUG)
  +      System.out.println("Exiting XStatement constructor");
  +  }
  +
  +
  +  /**
  +   * Set the parameter for a Prepared Statement
  +   *
  +   */
  +  public void setParameter(int pos, PreparedStatement stmt, QueryParameter p)
  +    throws SQLException
  +  {
  +    String type = p.getType();
  +    if (type.equalsIgnoreCase("string"))
  +    {
  +      stmt.setString(pos, p.getValue());
  +    }
  +
  +    if (type.equalsIgnoreCase("bigdecimal"))
  +    {
  +      stmt.setBigDecimal(pos, new BigDecimal(p.getValue()));
  +    }
  +
  +    if (type.equalsIgnoreCase("boolean"))
  +    {
  +      Integer i = new Integer( p.getValue() );
  +      boolean b = ((i.intValue() != 0) ? false : true);
  +      stmt.setBoolean(pos, b);
  +    }
  +
  +    if (type.equalsIgnoreCase("bytes"))
  +    {
  +      stmt.setBytes(pos, p.getValue().getBytes());
  +    }
  +
  +    if (type.equalsIgnoreCase("date"))
  +    {
  +      stmt.setDate(pos, Date.valueOf(p.getValue()));
  +    }
  +
  +    if (type.equalsIgnoreCase("double"))
  +    {
  +      Double d = new Double(p.getValue());
  +      stmt.setDouble(pos, d.doubleValue() );
  +    }
  +
  +    if (type.equalsIgnoreCase("float"))
  +    {
  +      Float f = new Float(p.getValue());
  +      stmt.setFloat(pos, f.floatValue());
  +    }
  +
  +    if (type.equalsIgnoreCase("long"))
  +    {
  +      Long l = new Long(p.getValue());
  +      stmt.setLong(pos, l.longValue());
  +    }
  +
  +    if (type.equalsIgnoreCase("short"))
  +    {
  +      Short s = new Short(p.getValue());
  +      stmt.setShort(pos, s.shortValue());
  +    }
  +
  +    if (type.equalsIgnoreCase("time"))
  +    {
  +      stmt.setTime(pos, Time.valueOf(p.getValue()) );
  +    }
  +
  +    if (type.equalsIgnoreCase("timestamp"))
  +    {
  +
  +      stmt.setTimestamp(pos, Timestamp.valueOf(p.getValue()) );
  +    }
  +
  +  }
  +
  +
     /**
  -   * Get the representation of the JDBC Query statement 
  +   * Get the representation of the JDBC Query statement
      *
      *
  -   * @return the representation of the JDBC Query statement, this 
  +   * @return the representation of the JDBC Query statement, this
      */
     public XStatement getXStatement()
     {
  @@ -215,7 +350,7 @@
      * iterator. The available set of constants is defined in the
      * <code>NodeFilter</code> interface.
      *
  -   * @return which node types are to be presented 
  +   * @return which node types are to be presented
      */
     public int getWhatToShow()
     {
  @@ -445,7 +580,7 @@
     // ===== ContextNodeList implementation =====
   
     /**
  -   * The current node is the RowSet  
  +   * The current node is the RowSet
      *
      *
      * @return The row-set
  @@ -479,7 +614,7 @@
      * Set whether nodes should be cached - not implemented
      *
      *
  -   * @param b Flag indicating whether nodes should be cached 
  +   * @param b Flag indicating whether nodes should be cached
      */
     public void setShouldCacheNodes(boolean b)
     {
  @@ -500,7 +635,7 @@
     }
   
     /**
  -   * Not implemented 
  +   * Not implemented
      *
      *
      * @param i
  @@ -512,7 +647,7 @@
     }
   
     /**
  -   * Return size 
  +   * Return size
      *
      *
      * @return 1
  @@ -534,7 +669,7 @@
     }
   
     /**
  -   * Overide cloneWithReset method 
  +   * Overide cloneWithReset method
      *
      *
      * @return A clone of this which has been reset
  @@ -555,7 +690,7 @@
      * Clone this object
      *
      *
  -   * @return A clone of this object 
  +   * @return A clone of this object
      *
      * @throws CloneNotSupportedException
      */
  @@ -566,26 +701,26 @@
   
       return clone;
     }
  -  
  +
     /** Index of Last node found by this iterator   */
     private int m_last = 0;
  -  
  +
     /**
  -   * Get index of the last found node 
  +   * Get index of the last found node
      *
      *
  -   * @return index of last found node 
  +   * @return index of last found node
      */
     public int getLast()
     {
       return m_last;
     }
  -  
  +
     /**
  -   * Set the index of the last found node 
  +   * Set the index of the last found node
      *
      *
  -   * @aram index of last found node 
  +   * @aram index of last found node
      */
     public void setLast(int last)
     {
  
  
  
  1.3       +4 -0      xml-xalan/java/src/org/apache/xalan/lib/sql/package.html
  
  Index: package.html
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/lib/sql/package.html,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- package.html	2001/01/02 03:36:39	1.2
  +++ package.html	2001/01/04 10:10:09	1.3
  @@ -68,5 +68,9 @@
   
   &lt;/xsl:stylesheet&gt;
   </pre>    
  +    <dl>
  +      <dt><b>Version: </b></dt><dd>Alpha, 2.0.0, September 23, 2000</dd>
  +      <dt><b>Author: </b></dt><dd><a href="mailto:scott_boag@lotus.com">Scott Boag</a></dd>
  +    </dl>
    </body>
   </html>
  
  
  
  1.1                  xml-xalan/java/src/org/apache/xalan/lib/sql/ConnectionPool.java
  
  Index: ConnectionPool.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 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 acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" 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 name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * 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) 1999, Lotus
   * Development Corporation., http://www.lotus.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.xalan.lib.sql;
  
  import java.util.Properties;
  import java.lang.String;
  
  import java.sql.Connection;
  import java.sql.SQLException;
  
  /**
   *
   * An interface used to build wrapper classes around existing
   * Connection Pool libraries.
   *
   * Title:     ConnectionPool<p>
   * @author    John Gentilin
   * @version   1.0
   *
   */
  
  
  public interface ConnectionPool
  {
    /**
     * The Active Flag determines if the ConnectionPool is usable
     * If the Connection Pool is inactive, as connections are released
     * they will also be closed, so the min number of connections will
     * slowly be diminised.
     */
    public void     setActive(boolean flag);
    public boolean  getActive();
  
    /**
     * The Driver and URL are the only required parmeters.
     */
    public void     setDriver(String d);
    public void     setURL(String url);
  
    /**
     * Start downsizeing the pool, this usally happens right after the
     * pool has been marked as Inactive and we are removing connections
     * that are not currently inuse.
     */
    public void     freeUnused();
  
  
    /**
     * Provide an indicator to the PoolManager when the Pool can be removed
     * from the Pool Table.
     */
    public boolean  hasActiveConnections();
  
    /**
     * The rest of the protocol parameters can eiter be passed in as
     * just Username and Password or as a property collection. If the
     * property collection is used, then the sperate username and password
     * may be ignored, it is up to the wrapper implementation to handle
     * the situation. If the connection information changes while after the
     * pool has been established, the wrapper implementation should ignore
     * the change and throw an error.
     *
     */
    public void     setPassword(String p);
    public void     setUser(String u);
    public void     setProtocol(Properties p);
  
    /**
     * Set tne minimum number of connections that are to be maintained in the
     * pool.
     */
    public void     setMinConnections(int n);
  
    /**
     * Test to see if the connection info is valid to make a real connection
     * to the database. This method may cause the pool to be crated and filled
     * with min connections.
     *
     */
    public boolean  testConnection();
  
    /**
     * Retrive a database connection from the pool
     *
     */
     public Connection getConnection() throws SQLException;
  
     /**
      * Return a connection to the pool, the connection may be closed if the
      * pool is inactive or has exceeded the max number of free connections
      *
      */
    public void releaseConnection(Connection con) throws SQLException;
  
  }
  
  
  1.1                  xml-xalan/java/src/org/apache/xalan/lib/sql/DefaultConnectionPool.java
  
  Index: DefaultConnectionPool.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 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 acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" 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 name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * 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) 1999, Lotus
   * Development Corporation., http://www.lotus.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.xalan.lib.sql;
  
  import java.util.Properties;
  import java.util.Vector;
  import java.util.Set;
  import java.util.Iterator;
  
  import java.lang.String;
  
  import java.sql.Connection;
  import java.sql.SQLException;
  import java.sql.DatabaseMetaData;
  import java.sql.DriverManager;
  
  public class DefaultConnectionPool implements ConnectionPool
  {
    private final static boolean DEBUG = false;
  
    /**
     * The basic information to make a JDBC Connection
     */
    private String      m_driver = new String("");
    private String      m_url = new String("");
  
  
    /**
     * The mimimum size of the connection pool, if the
     * number of available connections falls below this
     * mark, min connections will be allocated. The Connection
     * Pool will always be somewhere between MinSize and MinSize*2
     *
     */
    private int         m_PoolMinSize = 1;
  
  
    /**
     * Always implement the properties mechinism, if the Password
     * or Username is set seperatly then we will add them to the
     * property manually.
     *
     */
    private Properties  m_ConnectionProtocol = new Properties();
  
    /**
     * Storage for the PooledConnections
     */
    private Vector      m_pool = null;
  
    /**
     * Are we active ??
     */
    private boolean     m_IsActive = false;
  
    public DefaultConnectionPool() {}
  
    /**
     * Are we active, if not then released connections will be
     * closed on release and new connections will be refused.
     *
     * @param <code>boolean flag</code>, Set the active flag.
     */
    public void setActive(boolean flag)
    {
      m_IsActive = flag;
    }
  
    /**
     * Return our current Active state
     */
    public boolean getActive()
    {
      return m_IsActive;
    }
  
    /**
     * Set the driver call to be used to create connections
     */
    public void setDriver(String d)
    {
      m_driver = d;
    }
  
    /**
     * Set the url used to connect to the database
     */
    public void setURL(String url)
    {
      m_url = url;
    }
  
    /**
     * Go through the connection pool and release any connections
     * that are not InUse;
     *
     */
    public void freeUnused()
    {
      // Iterate over the entire pool closing the
      // JDBC Connections.
      for ( int x = 0; x < m_pool.size(); x++ )
      {
  
  
        PooledConnection pcon =
          (PooledConnection) m_pool.elementAt(x);
  
        // If the PooledConnection is not in use, close it
        if ( pcon.inUse() == false )
        {
          if (DEBUG)
          {
            System.err.println("Closing JDBC Connection " + x);
          }
  
          pcon.close();
        }
      }
  
    }
  
    /**
     * Is our ConnectionPool have any connections that are still in Use ??
     */
    public boolean hasActiveConnections()
    {
      return (m_pool.size() > 0);
    }
  
  
    /**
     * Set the password in the property set.
     */
    public void setPassword(String p)
    {
      m_ConnectionProtocol.setProperty("password", p);
    }
  
    /**
     * Set the user name in the property set
     */
    public void setUser(String u)
    {
      m_ConnectionProtocol.setProperty("user", u);
    }
  
    /**
     * Copy the properties from the source to our properties
     */
    public void setProtocol(Properties p)
    {
      Set s = p.keySet();
      Iterator i = s.iterator();
  
      while (i.hasNext())
      {
        String key = (String) i.next();
        m_ConnectionProtocol.setProperty(key, p.getProperty(key));
      }
  
    }
  
    /**
     * Override the current number of connections to keep in the pool. This
     * setting will only have effect on a new pool or when a new connection
     * is requested and there is less connections that this setting.
     */
    public void setMinConnections(int n)
    {
      m_PoolMinSize = n;
    }
  
    /**
     * Try to aquire a new connection, if it succeeds then return
     * true, else return false.
     * Note: This method will cause the connection pool to be built.
     *
     */
    public boolean testConnection()
    {
      try
      {
        Connection conn = getConnection();
  
        if (DEBUG)
        {
          DatabaseMetaData dma = conn.getMetaData();
  
          System.out.println("\nConnected to " + dma.getURL());
          System.out.println("Driver   " + dma.getDriverName());
          System.out.println("Version  " + dma.getDriverVersion());
          System.out.println("");
        }
  
        if (conn == null) return false;
  
        releaseConnection(conn);
  
        return true;
      }
      catch(Exception e)
      {
        return false;
      }
  
    }
  
  
    // Find an available connection
    public synchronized Connection getConnection()
      throws IllegalArgumentException, SQLException
    {
  
      PooledConnection pcon = null;
  
      if (m_pool == null) { initializePool(); }
  
      // find a connection not in use
      for ( int x = 0; x < m_pool.size(); x++ )
      {
  
        pcon = (PooledConnection) m_pool.elementAt(x);
  
        // Check to see if the Connection is in use
        if ( pcon.inUse() == false )
        {
          // Mark it as in use
          pcon.setInUse(true);
          // return the JDBC Connection stored in the
          // PooledConnection object
          return pcon.getConnection();
        }
      }
  
      // Could not find a free connection,
      // create and add a new one
  
      // Create a new JDBC Connection
      Connection con = createConnection();
  
      // Create a new PooledConnection, passing it the JDBC
      // Connection
      pcon = new PooledConnection(con);
  
      // Mark the connection as in use
      pcon.setInUse(true);
  
      // Add the new PooledConnection object to the pool
      m_pool.addElement(pcon);
  
      // return the new Connection
      return pcon.getConnection();
    }
  
    public synchronized void releaseConnection(Connection con)
      throws SQLException
    {
  
      // find the PooledConnection Object
      for ( int x = 0; x < m_pool.size(); x++ )
      {
  
        PooledConnection pcon =
          (PooledConnection) m_pool.elementAt(x);
  
        // Check for correct Connection
        if ( pcon.getConnection() == con )
        {
          if (DEBUG)
          {
            System.out.println("Releasing Connection " + x);
          }
  
          if (getActive() == false)
          {
            con.close();
            m_pool.remove(x);
            if (DEBUG)
            {
              System.out.println("-->Inactive Pool, Closing connection");
            }
  
          }
          else
          {
            // Set it's inuse attribute to false, which
            // releases it for use
            pcon.setInUse(false);
          }
  
          break;
        }
      }
    }
  
  
  
    private Connection createConnection()
      throws SQLException
    {
      Connection con = null;
  
      // Create a Connection
      con = DriverManager.getConnection( m_url, m_ConnectionProtocol );
  
      return con;
    }
  
    // Initialize the pool
    public synchronized void initializePool()
      throws IllegalArgumentException, SQLException
    {
       // Check our initial values
       if ( m_driver == null )
       {
         throw new IllegalArgumentException("No Driver Name Specified!");
       }
  
       if ( m_url == null )
       {
         throw new IllegalArgumentException("No URL Specified!");
       }
  
       if ( m_PoolMinSize < 1 )
       {
         throw new IllegalArgumentException("Pool size is less than 1!");
       }
  
       // Create the Connections
       // Load the Driver class file
  
       try
       {
         Class.forName( m_driver );
       }
       catch(ClassNotFoundException e)
       {
         throw new IllegalArgumentException("Invalid Driver Name Specified!");
       }
  
  
      // Create Connections based on the size member
      for ( int x = 0; x < m_PoolMinSize; x++ )
      {
  
        Connection con = createConnection();
  
        if ( con != null )
        {
  
          // Create a PooledConnection to encapsulate the
          // real JDBC Connection
          PooledConnection pcon = new PooledConnection(con);
  
          // Add the Connection the pool.
          addConnection(pcon);
  
          if (DEBUG) System.out.println("Adding DB Connection to the Pool");
        }
      }
    }
  
    // Adds the PooledConnection to the pool
    private void addConnection(PooledConnection value)
    {
  
      // If the pool is null, create a new vector
      // with the initial size of "size"
      if ( m_pool == null )
      {
        m_pool = new Vector( m_PoolMinSize);
      }
  
      // Add the PooledConnection Object to the vector
      m_pool.addElement(value);
    }
  
  
    protected void finalize()
      throws Throwable
    {
      if (DEBUG)
      {
        System.out.println("In Default Connection Pool, Finalize");
      }
  
      // Iterate over the entire pool closing the
      // JDBC Connections.
      for ( int x = 0; x < m_pool.size(); x++ )
      {
  
        if (DEBUG)
        {
          System.out.println("Closing JDBC Connection " + x);
        }
  
        PooledConnection pcon =
          (PooledConnection) m_pool.elementAt(x);
  
        // If the PooledConnection is not in use, close it
        if ( pcon.inUse() == false ) { pcon.close();  }
        else
        {
          if (DEBUG)
          {
            System.out.println("--> Force close");
          }
  
          // If it still in use, sleep for 30 seconds and
          // force close.
          try
          {
            java.lang.Thread.sleep(30000);
            pcon.close();
          }
          catch (InterruptedException ie)
          {
            if (DEBUG) System.err.println(ie.getMessage());
          }
        }
      }
  
      if (DEBUG)
      {
        System.out.println("Exit Default Connection Pool, Finalize");
      }
  
      super.finalize();
    }
  }
  
  
  
  1.1                  xml-xalan/java/src/org/apache/xalan/lib/sql/ExtensionError.java
  
  Index: ExtensionError.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 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 acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" 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 name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * 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) 1999, Lotus
   * Development Corporation., http://www.lotus.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.xalan.lib.sql;
  
  import org.w3c.dom.Node;
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  import org.w3c.dom.Text;
  import org.w3c.dom.CDATASection;
  
  import org.w3c.dom.NamedNodeMap;
  import org.w3c.dom.DOMException;
  
  import javax.xml.parsers.DocumentBuilder;
  import javax.xml.parsers.DocumentBuilderFactory;
  import javax.xml.parsers.ParserConfigurationException;
  
  import org.apache.xalan.stree.DocumentImpl;
  import org.w3c.dom.traversal.NodeFilter;
  import org.w3c.dom.traversal.NodeIterator;
  
  // Imported Serializer classes
  import org.apache.xml.serialize.OutputFormat;
  import org.apache.xml.serialize.Serializer;
  import org.apache.xml.serialize.XMLSerializer;
  import java.io.StringWriter;
  
  import java.io.ByteArrayOutputStream;
  import java.io.PrintStream;
  import org.apache.xpath.axes.ContextNodeList;
  
  /**
   *
   * A base class that will convert an exception into an XML stream
   * that can be returned in place of the standard result. The XML
   * format returned is a follows.
   *
   * <ext-error>
   *  <exception-info>
   *    <message> Message from the Exception thrown </message>
   *    <stack> Current stack information as CData </stack>
   *  <exception-info>
   *
   *  If another class subclasses this class, there will be an
   *  oppurtitny to add specific information here. Each Extension
   *  class should implement their own specific Extension Error
   *  class.
   * <ext-error>
   *
   * @author  John Gentilin
   * @version 1.0
   *
   */
  
  
  public class ExtensionError
    implements NodeIterator, ContextNodeList, Cloneable
  {
    private static final boolean DEBUG = false;
  
    private boolean   m_FirstTime = true;
    private Document  m_doc = null;
  
    public ExtensionError()
    {
    }
  
    public ExtensionError(Exception err)
    {
      processBaseError(err);
      // dump();
    }
  
    protected void processBaseError(Exception err)
    {
      try
      {
        DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
  
        m_doc = docBuilder.newDocument();
  
        Element etmp = null;
        Text text = null;
        CDATASection cdata = null;
  
        Element root = m_doc.createElement("ext-error");
        m_doc.appendChild(root);
  
  
        Element info = m_doc.createElement("exception-info");
        root.appendChild(info);
  
        etmp = m_doc.createElement("message");
        info.appendChild(etmp);
        text = m_doc.createTextNode(err.getMessage());
        etmp.appendChild(text);
  
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(bos);
        err.printStackTrace(ps);
        String stack = bos.toString();
  
        // System.out.println(stack);
  
        etmp = m_doc.createElement("stack");
        info.appendChild(etmp);
        cdata = m_doc.createCDATASection(stack);
        etmp.appendChild(text);
  
        populateSpecificData(m_doc, root);
  
      }
      catch(Exception e)
      {
        e.printStackTrace();
  
        m_doc = null;
      }
    }
  
    /**
     * Other classes that extend this class will overrid this mehood to
     * add any specific information.
     *
     */
  
    protected void populateSpecificData(Document doc, Node node)
    {
    }
  
    public Node getRoot()
    {
      return m_doc;
    }
  
    /**
     *  This attribute determines which node types are presented via the
     * iterator. The available set of constants is defined in the
     * <code>NodeFilter</code> interface.
     *
     * @return which node types are to be presented
     */
    public int getWhatToShow()
    {
  
      if (DEBUG)
        System.out.println("In ExtensionError.getWhatToShow");
  
      // TODO: ??
      return NodeFilter.SHOW_ALL & ~NodeFilter.SHOW_ENTITY_REFERENCE;
    }
  
    /**
     *  The filter used to screen nodes.
     * @return null.
     */
    public NodeFilter getFilter()
    {
  
      if (DEBUG)
        System.out.println("In ExtensionError.getFilter");
  
      return null;
    }
  
    /**
     *  The value of this flag determines whether the children of entity
     * reference nodes are visible to the iterator. If false, they will be
     * skipped over.
     * <br> To produce a view of the document that has entity references
     * expanded and does not expose the entity reference node itself, use the
     * whatToShow flags to hide the entity reference node and set
     * expandEntityReferences to true when creating the iterator. To produce
     * a view of the document that has entity reference nodes but no entity
     * expansion, use the whatToShow flags to show the entity reference node
     * and set expandEntityReferences to false.
     * @return true.
     */
    public boolean getExpandEntityReferences()
    {
  
      if (DEBUG)
        System.out.println("In ExtensionError.getExpandEntityReferences");
  
      return true;
    }
  
    /**
     * Return the #Document node (one role the XStatement plays) the first time called;
     * return null thereafter.
     * @return this or null.
     *
     * @throws DOMException
     */
  
    public Node nextNode() throws DOMException
    {
  
      if (DEBUG)
        System.out.println("In Extension Error: next node");
  
      if (! m_FirstTime) return null;
  
      m_FirstTime = false;
      return m_doc;
    }
  
    public Node previousNode()
      throws DOMException
    {
      return null;
    }
  
    public void detach()
    {
    }
  
    public void dump()
    {
  
      try
      {
        //Serialize DOM
        OutputFormat		format  = new OutputFormat();
        //Writer will be a String
        StringWriter		stringOut = new StringWriter();
  
        XMLSerializer		serial = new XMLSerializer( stringOut, format );
  
        // As a DOM Serializer
        serial.asDOMSerializer();
  
        Element e = m_doc.getDocumentElement();
        serial.serialize(e);
        System.out.println("Extension Error:");
        String display = stringOut.toString();
        System.out.println( display );
      }
      catch(Exception e)
      {
        // Empty
      }
  
    }
  
    public Node getCurrentNode()
    {
      return m_doc;
    }
  
    public int getCurrentPos()
    {
      return 0;
    }
  
    public void reset()
    {
      m_FirstTime = true;
    }
  
    public void setShouldCacheNodes(boolean b)
    {
      //TODO: Implement this org.apache.xpath.axes.ContextNodeList method
    }
  
    public void runTo(int index)
    {
      //TODO: Implement this org.apache.xpath.axes.ContextNodeList method
    }
  
    public void setCurrentPos(int i)
    {
      //TODO: Implement this org.apache.xpath.axes.ContextNodeList method
    }
  
    public int size()
    {
      return 1;
    }
  
    public boolean isFresh()
    {
      return m_FirstTime;
    }
  
    public NodeIterator cloneWithReset() throws CloneNotSupportedException
    {
      ExtensionError clone = (ExtensionError) super.clone();
      clone.reset();
      return clone;
    }
  
    public Object clone() throws CloneNotSupportedException
    {
      ExtensionError clone = (ExtensionError) super.clone();
      return clone;
    }
  
    public int getLast()
    {
      return 0;
    }
  
    public void setLast(int last)
    {
    }
  }
  
  
  1.1                  xml-xalan/java/src/org/apache/xalan/lib/sql/PooledConnection.java
  
  Index: PooledConnection.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 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 acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" 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 name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * 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) 1999, Lotus
   * Development Corporation., http://www.lotus.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.xalan.lib.sql;
  
  import java.sql.*;
  
  public class PooledConnection
  {
  
    // Real JDBC Connection
    private Connection connection = null;
    // boolean flag used to determine if connection is in use
    private boolean inuse = false;
  
    // Constructor that takes the passed in JDBC Connection
    // and stores it in the connection attribute.
    public PooledConnection(Connection value)
    {
      if ( value != null ) { connection = value; }
    }
  
    // Returns a reference to the JDBC Connection
    public Connection getConnection()
    {
      // get the JDBC Connection
      return connection;
    }
  
    // Set the status of the PooledConnection.
    public void setInUse(boolean value)
    {
      inuse = value;
    }
  
    // Returns the current status of the PooledConnection.
    public boolean inUse() { return inuse; }
  
    // Close the real JDBC Connection
    public void close()
    {
      try
      {
        connection.close();
      }
      catch (SQLException sqle)
      {
        System.err.println(sqle.getMessage());
      }
    }
  }
  
  
  
  1.1                  xml-xalan/java/src/org/apache/xalan/lib/sql/QueryParameter.java
  
  Index: QueryParameter.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 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 acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" 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 name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * 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) 1999, Lotus
   * Development Corporation., http://www.lotus.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.xalan.lib.sql;
  
  /**
   * Title:        <p>
   * Description:  <p>
   * Copyright:    Copyright (c) <p>
   * Company:      <p>
   * @author
   * @version 1.0
   */
  
  public class QueryParameter
  {
  
    private String value;
    private String type;
  
    public QueryParameter(String v, String t)
    {
      value = v;
      type = t;
    }
  
    public String getValue() {
      return value;
    }
  
    public void setValue(String newValue) {
      value = newValue;
    }
  
    public void setType(String newType) {
      type = newType;
    }
  
    public String getType() {
      return type;
    }
  }
  
  
  1.1                  xml-xalan/java/src/org/apache/xalan/lib/sql/SQLExtensionError.java
  
  Index: SQLExtensionError.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 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 acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" 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 name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * 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) 1999, Lotus
   * Development Corporation., http://www.lotus.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  
  
  package org.apache.xalan.lib.sql;
  
  import org.w3c.dom.Node;
  import java.sql.SQLException;
  
  import java.lang.Integer;
  
  import org.w3c.dom.Node;
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  import org.w3c.dom.Text;
  import org.w3c.dom.CDATASection;
  
  /**
   * Title:        <p>
   * Description:  <p>
   * Copyright:    Copyright (c) <p>
   * Company:      <p>
   * @author
   * @version 1.0
   */
  
  public class SQLExtensionError extends ExtensionError {
  
    private SQLException m_sql_ex = null;
  
    public SQLExtensionError(SQLException e)
    {
      m_sql_ex = e;
      super.processBaseError(e);
      // dump();
    }
  
    protected void populateSpecificData(Document doc, Node n)
    {
      Element etmp = null;
      Text text = null;
      CDATASection cdata = null;
  
      Element root = doc.createElement("sql-error");
      n.appendChild(root);
  
  
      Element code = doc.createElement("error_code");
      root.appendChild(code);
  
      int ecode = m_sql_ex.getErrorCode();
      Integer i = new Integer(ecode);
  
      text = doc.createTextNode(i.toString());
      code.appendChild(text);
  
      Element state = doc.createElement("state");
      root.appendChild(state);
      text = doc.createTextNode(m_sql_ex.getSQLState());
      state.appendChild(text);
  
      m_sql_ex = m_sql_ex.getNextException();
      if ( null != m_sql_ex ) populateSpecificData(doc, n);
    }
  
  }
  
  
  1.1                  xml-xalan/java/src/org/apache/xalan/lib/sql/XConnectionPoolManager.java
  
  Index: XConnectionPoolManager.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 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 acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" 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 name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * 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) 1999, Lotus
   * Development Corporation., http://www.lotus.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  
   package org.apache.xalan.lib.sql;
  
  /**
   * <P>
   * Provides a mechinism where a shared collection of connection
   * pools can exist. Connection Pools are referenced by name.
   * <P><HR>
   *
   * Title:        PoolManager<p>
   * @author       John Gentilin
   * @version      1.0
   *
   */
  
  import java.util.Hashtable;
  import java.lang.IllegalArgumentException;
  
  public class XConnectionPoolManager
  {
    static Hashtable  m_poolTable = null;
    static boolean    m_isInit  = false;
  
    public XConnectionPoolManager()
    {
      init();
    }
  
    /**
     * Initialize the internal structures of the Pool Manager
     *
     */
    public synchronized void init()
    {
      // Only do this process once
      if (m_isInit == true) return;
  
  
      //
      // Initialize the pool table
      //
      m_poolTable = new Hashtable();
  
      m_isInit = true;
    }
  
    /**
     * Register a nuew connection pool to the global pool table.
     * If a pool by that name currently exists, then throw an
     * IllegalArgumentException stating that the pool already
     * exist.
     *
     * @param <code>String name</code>, the name of the pool to
     * add to the list.
     *
     * @param <code>ConnectionPool</code> the Connection Pool to
     * be added, this pool must already be set up to accept connections.
     * see {@link org.apache.xalan.lib.sql.ConnectionPool}
     *
     * @throws <code>IllegalArgumentException</code>, throw this exception
     * if a pool with the same name currently exists.
     *
     */
    public void registerPool(String name, ConnectionPool pool)
    {
      if ( m_poolTable.containsKey(name) )
      {
        throw new IllegalArgumentException("Pool already exists");
      }
  
      m_poolTable.put(name, pool);
    }
  
    /**
     * Remove a pool from the global table. If the pool still has
     * active connections, then only mark this pool as inactive and
     * leave it around until all the existing connections are closed.
     *
     * @param <code>String name</code> name of the pool to remove.
     *
     */
    public void removePool(String name)
    {
      ConnectionPool pool = getPool(name);
  
      if (null != pool)
      {
        //
        // Disable future use of this pool under the Xalan
        // extension only. This flag should only exist in the
        // wrapper and not in the actual pool implementation.
        pool.setActive(false);
  
        //
        // Let's trim down the number of connections that are in use
        pool.freeUnused();
  
        //
        // Remove the pool from the Hashtable if we don'd have
        // any active connections.
        //
        if ( ! pool.hasActiveConnections() ) m_poolTable.remove(name);
      }
  
    }
  
  
    /**
     * Return the connection pool referenced by the name
     *
     * @param <code>String name</code>, name of the pool to be returned.
     *
     * @returns <code>ConnectionPool</code> a reference to the ConnectionPool
     * object stored in the Pool Table. If the named pool does not exist, return
     * null
     *
     */
    public ConnectionPool getPool(String name)
    {
      return (ConnectionPool) m_poolTable.get(name);
    }
  
  }