User: mulder  
  Date: 00/06/02 06:48:42

  Added:       src/main/org/jboss/minerva/datasource
                        JDBCPoolDataSource.java PoolDriver.java
                        XAPoolDataSource.java package.html
  Log:
  Initial entry of Minerva JDBC Pools into CVS.
  
  Pools, DataSources, and other non-jBoss-dependent code is under
    org.jboss.minerva.*
  
  JavaDoc source HTML files are included - the package comments are in
    the package.html files in the various packages, and the overview
    comments are in org/jboss/minerva/minerva.html
  
  MBeans to load a pool into jBoss are in org.jboss.jdbc
  
  A new logging Writer is on org.jboss.logging.
  
  Revision  Changes    Path
  1.1                  
jboss/src/main/org/jboss/minerva/datasource/JDBCPoolDataSource.java
  
  Index: JDBCPoolDataSource.java
  ===================================================================
  /*
   * jBoss, the OpenSource EJB server
   *
   * Distributable under GPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.minerva.datasource;
  
  import java.sql.Connection;
  import java.io.PrintWriter;
  import java.util.*;
  import javax.sql.DataSource;
  import javax.naming.*;
  import javax.naming.spi.*;
  import org.jboss.minerva.factories.JDBCConnectionFactory;
  import org.jboss.minerva.pools.ObjectPool;
  
  /**
   * DataSource for non-transactional JDBC pools.  This handles configuration
   * parameters for both the pool and the JDBC driver.  It is important that you
   * set all the configuration parameters before you initialize the DataSource,
   * and you must initialize it before you use it.  All the configuration
   * parameters are not documented here; you are instead referred to ObjectPool
   * and JDBCConnectionFactory.
   * @see org.jboss.minerva.pools.ObjectPool
   * @see org.jboss.minerva.factories.JDBCConnectionFactory
   * @version $Revision: 1.1 $
   * @author Aaron Mulder ([EMAIL PROTECTED])
   */
  public class JDBCPoolDataSource implements DataSource, Referenceable, ObjectFactory {
      private static HashMap sources = new HashMap();
      /**
       * Gets all the current JDBC pool data sources.
       */
      public static Collection getDataSources() {
          return new HashSet(sources.values());
      }
      /**
       * Gets a specific JDBC pool data source by pool name.
       */
      public static JDBCPoolDataSource getDataSource(String poolName) {
          return (JDBCPoolDataSource)sources.get(poolName);
      }
  
      private ObjectPool pool;
      private JDBCConnectionFactory factory;
      private PrintWriter logWriter;
      private int timeout;
      private boolean initialized = false;
      private String jndiName;
  
      /**
       * Creates a new JDBC pool data source.  Be sure to configure it and then
       * call initialize before you try to use it.
       */
      public JDBCPoolDataSource() {
          pool = new ObjectPool();
          factory = new JDBCConnectionFactory();
          PoolDriver.instance();
      }
  
  // Unique properties
      /**
       * If you use this to set a JNDI name, this pool will be bound to that name
       * using the default InitialContext.  You can also do this manually if you
       * have additional requirements.
       */
      public void setJNDIName(String name) throws NamingException {
          InitialContext ctx = new InitialContext();
          if(jndiName != null && !jndiName.equals(name))
              ctx.unbind(jndiName);
          if(name != null)
              ctx.bind(name, this);
          jndiName = name;
      }
  
      /**
       * Gets the JNDI name this pool is bound to.  Only valid if you used
       * setJNDIName to bind it.
       * @see #setJNDIName
       */
      public String getJNDIName() {return jndiName;}
  
  // JDBC properties
      public void setJDBCURL(String url) {factory.setConnectURL(url);}
      public String getJDBCURL() {return factory.getConnectURL();}
      public void setJDBCProperties(Properties props) 
{factory.setConnectProperties(props);}
      public Properties getJDBCProperties() {return factory.getConnectProperties();}
      public void setJDBCUser(String user) {factory.setUser(user);}
      public String getJDBCUser() {return factory.getUser();}
      public void setJDBCPassword(String password) {factory.setPassword(password);}
      public String getJDBCPassword() {return factory.getPassword();}
  // Pool properties
      public void setPoolName(String name) {
          pool.setName(name);
          sources.put(pool.getName(), this);
      }
      public String getPoolName() {return pool.getName();}
      public void setMinSize(int size) {pool.setMinSize(size);}
      public int getMinSize() {return pool.getMinSize();}
      public void setMaxSize(int size) {pool.setMaxSize(size);}
      public int getMaxSize() {return pool.getMaxSize();}
      public void setBlocking(boolean blocking) {pool.setBlocking(blocking);}
      public boolean isBlocking() {return pool.isBlocking();}
      public void setShrinkingEnabled(boolean allowShrinking) 
{pool.setShrinkingEnabled(allowShrinking);}
      public boolean isShrinkingEnabled() {return pool.isShrinkingEnabled();}
      public void setGCEnabled(boolean allowGC) {pool.setGCEnabled(allowGC);}
      public boolean isGCEnabled() {return pool.isGCEnabled();}
      public void setShrinkPercent(float percent) {pool.setShrinkPercent(percent);}
      public float getShrinkPercent() {return pool.getShrinkPercent();}
      public void setShrinkMinIdleTime(long millis) 
{pool.setShrinkMinIdleTime(millis);}
      public long getShrinkMinIdleTime() {return pool.getShrinkMinIdleTime();}
      public void setGCMinIdleTime(long millis) {pool.setGCMinIdleTime(millis);}
      public long getGCMinIdleTime() {return pool.getGCMinIdleTime();}
      public void setGCInterval(long millis) {pool.setGCInterval(millis);}
      public long getGCInterval() {return pool.getGCInterval();}
      public void setTimestampUsed(boolean timestamp) 
{pool.setTimestampUsed(timestamp);}
      public boolean isTimestampUsed() {return pool.isTimestampUsed();}
  
  // Other methods
  
      /**
       * Initializes the pool.  You need to have configured all the pool and
       * JDBC properties first.
       */
      public void initialize() {
          initialized = true;
          pool.setObjectFactory(factory);
          pool.initialize();
      }
  
      /**
       * Returns a string describing the pool status (number of connections
       * created, used, and maximum).
       */
      public String getPoolStatus() {
          return pool.toString();
      }
  
      /**
       * Shuts down this data source and the underlying pool.  If you used
       * setJNDI name to bind it in JNDI, it is unbound.
       */
      public void close() {
          try {
              setJNDIName(null);
          } catch(NamingException e) {
              e.printStackTrace();
          }
          sources.remove(pool.getName());
          pool.shutDown();
          pool = null;
          factory = null;
      }
  
      /**
       * Gets a connection from the pool.
       */
      public Connection getConnection() throws java.sql.SQLException {
          if(!initialized) initialize();
          return (Connection)pool.getObject();
      }
  
      /**
       * Gets a connection from the pool.  If a new connection must be
       * created, it will use the specified user name and password.  If there is
       * a connection available in the pool, it will be used, regardless of the
       * user name and password use to created it initially.
       */
      public Connection getConnection(String user, String password) throws 
java.sql.SQLException {
          if(!initialized) initialize();
          factory.setUser(user);
          factory.setPassword(password);
          return (Connection)pool.getObject();
      }
  
      /**
       * Gets a log writer used to record pool events.
       */
      public PrintWriter getLogWriter() throws java.sql.SQLException {
          return logWriter;
      }
  
      /**
       * Sets a log writer used to record pool events.
       */
      public void setLogWriter(PrintWriter writer) throws java.sql.SQLException {
          logWriter = writer;
          pool.setLogWriter(writer);
      }
  
      /**
       * This property is not used by this implementation.
       */
      public int getLoginTimeout() throws java.sql.SQLException {
          return timeout;
      }
  
      /**
       * This property is not used by this implementation.
       */
      public void setLoginTimeout(int timeout) throws java.sql.SQLException {
          this.timeout = timeout;
      }
  
      // Referenceable implementation ----------------------------------
      /**
       * Gets a reference to this data source.
       */
      public Reference getReference() {
          return new Reference(getClass().getName(), new StringRefAddr("JDBCPool", 
pool.getName()), getClass().getName(), null);
      }
  
      // ObjectFactory implementation ----------------------------------
      /**
       * Decodes a reference to a specific pool data source.
       */
      public Object getObjectInstance(Object obj, Name name, Context nameCtx,
                                      Hashtable environment) {
          if(obj instanceof Reference) {
              Reference ref = (Reference)obj;
              if(ref.getClassName().equals(getClass().getName())) {
                  RefAddr addr = ref.get("JDBCPool");
                  return sources.get((String)addr.getContent());
              }
          }
          return null;
      }
  }
  
  
  1.1                  jboss/src/main/org/jboss/minerva/datasource/PoolDriver.java
  
  Index: PoolDriver.java
  ===================================================================
  /*
   * jBoss, the OpenSource EJB server
   *
   * Distributable under GPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.minerva.datasource;
  
  import java.sql.*;
  import java.util.Properties;
  import javax.sql.*;
  
  /**
   * JDBC Driver to access pooled JDBC connections.  Supports both JDBC 1.0
   * connections and JDBC 2.0 transactional XAConnections.  You will get a
   * java.sql.Connection back in any case (in the case of XAConnections, the
   * transactional-ness is handled under the covers).  You must create the pools
   * ahead of time by creating and initializing the appropriate DataSource.
   * <TABLE BORDER="1">
   *   <TR><TH>Connection Type</TH><TH>URL Form</TH></TR>
   *   <TR><TD>Connection</TD><TD>jdbc:minerva:<I>PoolName</I></TD></TR>
   *   <TR><TD>XAConnection</TD><TD>jdbc:minervaxa:<I>PoolName</I></TD></TR>
   * </TABLE>
   * <P>Note that you must load this driver like normal in order to use it:<BR>
   * <CODE>Class.forName("org.minerva.datasource.PoolDriver");</CODE></P>
   * @see org.jboss.minerva.datasource.JDBCPoolDataSource
   * @see org.jboss.minerva.datasource.XAPoolDataSource
   * @version $Revision: 1.1 $
   * @author Aaron Mulder ([EMAIL PROTECTED])
   */
  public class PoolDriver implements Driver {
      private final static String URL_START = "jdbc:minerva:";
      private final static String XA_URL_START = "jdbc:minervaxa:";
      private final static PoolDriver instance;
      static {
          instance = new PoolDriver();
          try {
              DriverManager.registerDriver(PoolDriver.instance());
          } catch(SQLException e) {
              System.out.println("Unable to register Minerva DB pool driver!");
              e.printStackTrace();
          }
      }
  
      /**
       * Gets the singleton driver instance.
       */
      public static PoolDriver instance() {
          return instance;
      }
  
      private PoolDriver() {
      }
  
      /**
       * Tells which URLs this driver can handle.
       */
      public boolean acceptsURL(String url) throws java.sql.SQLException {
          return url.startsWith(URL_START) || url.startsWith(XA_URL_START);
      }
  
      /**
       * Retrieves a connection from a connection pool.
       */
      public Connection connect(String url, Properties props) throws 
java.sql.SQLException {
          if(url.startsWith(URL_START))
              return getJDBCConnection(url.substring(URL_START.length()));
          else if(url.startsWith(XA_URL_START))
              return getXAConnection(url.substring(XA_URL_START.length()));
          else
              throw new SQLException("Invalid URL!");
      }
  
      private Connection getJDBCConnection(String name) {
          Connection con = null;
          try {
              DataSource source = JDBCPoolDataSource.getDataSource(name);
              con = source.getConnection();
          } catch(Exception e) {
              e.printStackTrace();
          }
          return con;
      }
  
      private Connection getXAConnection(String name) {
          Connection con = null;
          try {
              DataSource source = XAPoolDataSource.getDataSource(name);
              con = source.getConnection();
          } catch(Exception e) {
              e.printStackTrace();
          }
          return con;
      }
  
      /**
       * Returns the driver version.
       */
      public int getMajorVersion() {
          return 2;
      }
  
      /**
       * Returns the driver version.
       */
      public int getMinorVersion() {
          return 0;
      }
  
      /**
       * Returns no properties.  You do not need properties to connect to the
       * pool, and the properties for the underlying driver are not managed here.
       */
      public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws 
SQLException {
          return new DriverPropertyInfo[0];
      }
  
      /**
       * Returns <B>false</B> since it is not known which underlying driver will
       * be used and what its capabilities are.
       */
      public boolean jdbcCompliant() {
          return false;
      }
  }
  
  
  1.1                  
jboss/src/main/org/jboss/minerva/datasource/XAPoolDataSource.java
  
  Index: XAPoolDataSource.java
  ===================================================================
  /*
   * jBoss, the OpenSource EJB server
   *
   * Distributable under GPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.minerva.datasource;
  
  import java.sql.Connection;
  import java.io.PrintWriter;
  import java.util.*;
  import javax.sql.*;
  import javax.naming.*;
  import javax.naming.spi.*;
  import org.jboss.minerva.factories.XAConnectionFactory;
  import org.jboss.minerva.pools.ObjectPool;
  
  /**
   * DataSource for transactional JDBC pools.  This handles configuration
   * parameters for both the pool and the JDBC connection.  It is important that
   * you set all the configuration parameters before you initialize the DataSource,
   * and you must initialize it before you use it.  All the configuration
   * parameters are not documented here; you are instead referred to ObjectPool
   * and XAConnectionFactory.
   * @see org.jboss.minerva.pools.ObjectPool
   * @see org.jboss.minerva.factories.XAConnectionFactory
   * @version $Revision: 1.1 $
   * @author Aaron Mulder ([EMAIL PROTECTED])
   */
  public class XAPoolDataSource implements DataSource, Referenceable, ObjectFactory {
      private static HashMap sources = new HashMap();
      /**
       * Gets all the current JDBC pool data sources.
       */
      public static Collection getDataSources() {
          return new HashSet(sources.values());
      }
      /**
       * Gets a specific JDBC pool data source by pool name.
       */
      public static XAPoolDataSource getDataSource(String poolName) {
          return (XAPoolDataSource)sources.get(poolName);
      }
  
  
      private ObjectPool pool;
      private XAConnectionFactory factory;
      private PrintWriter logWriter;
      private int timeout;
      private boolean initialized = false;
      private String jndiName;
  
      /**
       * Creates a new XA pool data source.  Be sure to configure it and then
       * call initialize before you try to use it.
       */
      public XAPoolDataSource() {
          pool = new ObjectPool();
          try {
              factory = new XAConnectionFactory();
          } catch(NamingException e) {
              e.printStackTrace();
          }
          PoolDriver.instance();
      }
  
  // Unique properties
      /**
       * If you use this to set a JNDI name, this pool will be bound to that name
       * using the default InitialContext.  You can also do this manually if you
       * have additional requirements.
       */
      public void setJNDIName(String name) throws NamingException {
          InitialContext ctx = new InitialContext();
          if(jndiName != null && !jndiName.equals(name))
              ctx.unbind(jndiName);
          if(name != null)
              ctx.bind(name, this);
          jndiName = name;
      }
  
      /**
       * Gets the JNDI name this pool is bound to.  Only valid if you used
       * setJNDIName to bind it.
       * @see #setJNDIName
       */
      public String getJNDIName() {return jndiName;}
  
  // XA properties
      public void setDataSource(XADataSource ds) {factory.setDataSource(ds);}
      public XADataSource getDataSource() {return factory.getDataSource();}
      public void setTransactionManagerJNDIName(String name) 
{factory.setTransactionManagerJNDIName(name);}
      public String getTransactionManagerJNDIName() {return 
factory.getTransactionManagerJNDIName();}
      public void setJDBCUser(String user) {factory.setUser(user);}
      public String getJDBCUser() {return factory.getUser();}
      public void setJDBCPassword(String password) {factory.setPassword(password);}
      public String getJDBCPassword() {return factory.getPassword();}
  // Pool properties
      public void setPoolName(String name) {
          pool.setName(name);
          sources.put(pool.getName(), this);
      }
      public String getPoolName() {return pool.getName();}
      public void setMinSize(int size) {pool.setMinSize(size);}
      public int getMinSize() {return pool.getMinSize();}
      public void setMaxSize(int size) {pool.setMaxSize(size);}
      public int getMaxSize() {return pool.getMaxSize();}
      public void setBlocking(boolean blocking) {pool.setBlocking(blocking);}
      public boolean isBlocking() {return pool.isBlocking();}
      public void setShrinkingEnabled(boolean allowShrinking) 
{pool.setShrinkingEnabled(allowShrinking);}
      public boolean isShrinkingEnabled() {return pool.isShrinkingEnabled();}
      public void setGCEnabled(boolean allowGC) {pool.setGCEnabled(allowGC);}
      public boolean isGCEnabled() {return pool.isGCEnabled();}
      public void setShrinkPercent(float percent) {pool.setShrinkPercent(percent);}
      public float getShrinkPercent() {return pool.getShrinkPercent();}
      public void setShrinkMinIdleTime(long millis) 
{pool.setShrinkMinIdleTime(millis);}
      public long getShrinkMinIdleTime() {return pool.getShrinkMinIdleTime();}
      public void setGCMinIdleTime(long millis) {pool.setGCMinIdleTime(millis);}
      public long getGCMinIdleTime() {return pool.getGCMinIdleTime();}
      public void setGCInterval(long millis) {pool.setGCInterval(millis);}
      public long getGCInterval() {return pool.getGCInterval();}
      public void setTimestampUsed(boolean timestamp) 
{pool.setTimestampUsed(timestamp);}
      public boolean isTimestampUsed() {return pool.isTimestampUsed();}
  
  // Other methods
  
      /**
       * Initializes the pool.  You need to have configured all the pool and
       * XA properties first.
       */
      public void initialize() {
          initialized = true;
          pool.setObjectFactory(factory);
          pool.initialize();
      }
  
      /**
       * Returns a string describing the pool status (number of connections
       * created, used, and maximum).
       */
      public String getPoolStatus() {
          return pool.toString();
      }
  
      /**
       * Shuts down this data source and the underlying pool.  If you used
       * setJNDI name to bind it in JNDI, it is unbound.
       */
      public void close() {
          try {
              setJNDIName(null);
          } catch(NamingException e) {
              e.printStackTrace();
          }
          sources.remove(pool.getName());
          pool.shutDown();
          pool = null;
          factory = null;
      }
  
      /**
       * Gets a connection from the pool.
       */
      public Connection getConnection() throws java.sql.SQLException {
          if(!initialized) initialize();
          return ((XAConnection)pool.getObject()).getConnection();
      }
  
      /**
       * Gets a new connection from the pool.  If a new connection must be
       * created, it will use the specified user name and password.  If there is
       * a connection available in the pool, it will be used, regardless of the
       * user name and password use to created it initially.
       */
      public Connection getConnection(String user, String password) throws 
java.sql.SQLException {
          if(!initialized) initialize();
          factory.setUser(user);
          factory.setPassword(password);
          return ((XAConnection)pool.getObject()).getConnection();
      }
  
      /**
       * Gets a log writer used to record pool events.
       */
      public PrintWriter getLogWriter() throws java.sql.SQLException {
          return logWriter;
      }
  
      /**
       * Sets a log writer used to record pool events.
       */
      public void setLogWriter(PrintWriter writer) throws java.sql.SQLException {
          logWriter = writer;
          pool.setLogWriter(writer);
      }
  
      /**
       * This property is not used by this implementation.
       */
      public int getLoginTimeout() throws java.sql.SQLException {
          return timeout;
      }
  
      /**
       * This property is not used by this implementation.
       */
      public void setLoginTimeout(int timeout) throws java.sql.SQLException {
          this.timeout = timeout;
      }
  
      // Referenceable implementation ----------------------------------
      /**
       * Gets a reference to this data source.
       */
      public Reference getReference() {
          return new Reference(getClass().getName(), new StringRefAddr("XAPool", 
pool.getName()), getClass().getName(), null);
      }
  
      // ObjectFactory implementation ----------------------------------
      /**
       * Decodes a reference to a specific pool data source.
       */
      public Object getObjectInstance(Object obj, Name name, Context nameCtx,
                                      Hashtable environment) {
          if(obj instanceof Reference) {
              Reference ref = (Reference)obj;
              if(ref.getClassName().equals(getClass().getName())) {
                  RefAddr addr = ref.get("XAPool");
                  return sources.get((String)addr.getContent());
              }
          }
          return null;
      }
  }
  
  
  1.1                  jboss/src/main/org/jboss/minerva/datasource/package.html
  
  Index: package.html
  ===================================================================
  <HTML>
    <HEAD>
      <TITLE>Minerva Pools: Package org.jboss.minerva.datasource</TITLE>
    </HEAD>
    <BODY BGCOLOR="WHITE">
      <P>Data Sources that are the main client interface for connection pools.
        The quickest way to get up and running with a JDBC or XA connection pool
        is to create and configure a DataSource.  This package includes both
        non-transactional JDBC pools, and transactional JDBC pools that will
        automatically register with a JTA TransactionManager.  You may choose
        to use the wrappers for non-transactional drivers in a transactional
        JDBC pool by using that as your XADataSource (see
        org.minerva.xa.XADataSourceImpl).</P>
    </BODY>
  </HTML>
  
  

Reply via email to