[jboss-cvs] JBossCache/src/org/jboss/cache/loader ...

Galder Zamarreno galder.zamarreno at jboss.com
Sun Jan 21 10:46:42 EST 2007


  User: gzamarreno
  Date: 07/01/21 10:46:42

  Modified:    src/org/jboss/cache/loader       JDBCCacheLoaderConfig.java
                        JDBCCacheLoader.java
  Added:       src/org/jboss/cache/loader      
                        NonManagedConnectionFactory.java
                        ManagedConnectionFactory.java
                        ConnectionFactory.java C3p0ConnectionFactory.java
  Log:
  [JBCACHE-802] c3p0 JDBC connection pooling functionality and corresponding unit tests added. JDBCCacheLoader has been refactored to provide better reporting by not swallowing exceptions and making ConnectionFactory and implementations separate java class files.
  
  Revision  Changes    Path
  1.3       +23 -2     JBossCache/src/org/jboss/cache/loader/JDBCCacheLoaderConfig.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: JDBCCacheLoaderConfig.java
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/loader/JDBCCacheLoaderConfig.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -b -r1.2 -r1.3
  --- JDBCCacheLoaderConfig.java	30 Dec 2006 19:48:44 -0000	1.2
  +++ JDBCCacheLoaderConfig.java	21 Jan 2007 15:46:42 -0000	1.3
  @@ -4,12 +4,18 @@
   
   import java.util.Properties;
   
  +/**
  + * JDBCCacheLoaderConfig
  + *
  + * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a> 
  + * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
  + */
   public class JDBCCacheLoaderConfig extends IndividualCacheLoaderConfig
   {
      /**
       * The serialVersionUID
       */
  -   private static final long serialVersionUID = -5923661816427361643L;
  +   private static final long serialVersionUID = -8371846151643130281L;
   
      private boolean createTable;
      private String createTableDDL;
  @@ -29,6 +35,7 @@
      private String table;
      private String updateNodeSql;
      private String updateTableSql;
  +   private String connectionFactoryClass;
   
      public JDBCCacheLoaderConfig()
      {
  @@ -244,6 +251,17 @@
         this.jdbcUser = jdbcUser;
      }
   
  +   public String getConnectionFactoryClass()
  +   {
  +      return connectionFactoryClass;
  +   }
  +
  +   public void setConnectionFactoryClass(String connectionFactoryClass)
  +   {
  +      testImmutability("connectionFactoryClass");
  +      this.connectionFactoryClass = connectionFactoryClass;
  +   }
  +
      public void setProperties(Properties props)
      {
         super.setProperties(props);
  @@ -316,6 +334,7 @@
                 ", constraint " + primaryKey + " primary key (" + fqnColumn + "))";
   
         dropTableDDL = "drop table " + table;
  +      connectionFactoryClass = props.getProperty("cache.jdbc.connection.factory", "org.jboss.cache.loader.NonManagedConnectionFactory");
      }
   
      public boolean equals(Object obj)
  @@ -341,7 +360,8 @@
                    && safeEquals(selectNodeSql, other.selectNodeSql)
                    && safeEquals(table, other.table)
                    && safeEquals(updateNodeSql, other.updateNodeSql)
  -                 && safeEquals(updateTableSql, other.updateTableSql);
  +                 && safeEquals(updateTableSql, other.updateTableSql)
  +                 && safeEquals(connectionFactoryClass, other.connectionFactoryClass);
         }
   
         return false;
  @@ -368,6 +388,7 @@
         result = 31 * result + (table == null ? 0 : table.hashCode());
         result = 31 * result + (updateNodeSql == null ? 0 : updateNodeSql.hashCode());
         result = 31 * result + (updateTableSql == null ? 0 : updateTableSql.hashCode());
  +      result = 31 * result + (connectionFactoryClass == null ? 0 : connectionFactoryClass.hashCode());
   
         return result;
      }
  
  
  
  1.30      +39 -311   JBossCache/src/org/jboss/cache/loader/JDBCCacheLoader.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: JDBCCacheLoader.java
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/loader/JDBCCacheLoader.java,v
  retrieving revision 1.29
  retrieving revision 1.30
  diff -u -b -r1.29 -r1.30
  --- JDBCCacheLoader.java	17 Jan 2007 18:53:29 -0000	1.29
  +++ JDBCCacheLoader.java	21 Jan 2007 15:46:42 -0000	1.30
  @@ -10,17 +10,14 @@
   import org.apache.commons.logging.LogFactory;
   import org.jboss.cache.Fqn;
   import org.jboss.cache.Modification;
  +import org.jboss.cache.util.Util;
   import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
   
  -import javax.naming.InitialContext;
  -import javax.naming.NamingException;
  -import javax.sql.DataSource;
   import java.io.ByteArrayInputStream;
   import java.io.IOException;
   import java.io.InputStream;
   import java.sql.Connection;
   import java.sql.DatabaseMetaData;
  -import java.sql.DriverManager;
   import java.sql.PreparedStatement;
   import java.sql.ResultSet;
   import java.sql.SQLException;
  @@ -77,14 +74,12 @@
    * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
    * @author <a href="mailto:hmesha at novell.com">Hany Mesha </a>
    * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
  - * @version <tt>$Revision: 1.29 $</tt>
  + * @version <tt>$Revision: 1.30 $</tt>
    */
   public class JDBCCacheLoader extends AbstractCacheLoader
   {
      private static final Log log = LogFactory.getLog(JDBCCacheLoader.class);
   
  -   private static final ThreadLocal connection = new ThreadLocal();
  -
      private JDBCCacheLoaderConfig config;
      private ConnectionFactory cf;
      private String driverName;
  @@ -102,10 +97,26 @@
   
         if (config.getDatasourceName() == null)
         {
  -         this.cf = new NonManagedConnectionFactory(config.getJdbcURL(), config.getJdbcUser(), config.getJdbcPassword());
  +         try
  +         {
  +            /* Instantiate an standalone connection factory as per configuration, either explicitly
  +            defined or the default one */
  +            cf = (ConnectionFactory)Util.loadClass(config.getConnectionFactoryClass()).newInstance();
  +         }
  +         catch (Exception e)
  +         {
  +            reportAndRethrowError("Connectionn factory class could not be loaded", e);
         }
  -      // else we wait until the start method to do a JNDI lookup
  -      // of the datasource, since that's when its registered in its lifecycle
  +      }
  +      else
  +      {
  +         /* We create the ManagedConnectionFactory instance but the JNDI lookup is no done until
  +            the start method is called, since that's when its registered in its lifecycle */
  +         cf = new ManagedConnectionFactory();
  +      }
  +
  +      /* Regardless of the type of connection factory, we set the configuration */
  +      cf.setConfig(config);
      }
   
      public IndividualCacheLoaderConfig getConfig()
  @@ -154,8 +165,7 @@
         }
         catch (SQLException e)
         {
  -         log.error("Failed to get children names for fqn " + fqn, e);
  -         throw new IllegalStateException("Failed to get children names for fqn " + fqn + ": " + e.getMessage());
  +         reportAndRethrowError("Failed to get children names for fqn " + fqn, e);
         }
         finally
         {
  @@ -381,8 +391,7 @@
         }
         catch (SQLException e)
         {
  -         log.error("Failed to remove node " + name, e);
  -         throw new IllegalStateException("Failed to remove node " + name + ": " + e.getMessage());
  +         reportAndRethrowError("Failed to remove node " + name, e);
         }
         finally
         {
  @@ -414,15 +423,7 @@
      public void prepare(Object tx, List<Modification> modifications, boolean one_phase) throws Exception
      {
         // start a tx
  -      //JBCACHE-346 fix, we don't need to prepare a DataSource object (Managed connection)
  -      if (cf instanceof NonManagedConnectionFactory)
  -      {
  -         Connection con = cf.prepare(tx);
  -         if (log.isTraceEnabled())
  -         {
  -            log.trace("openned tx connection: tx=" + tx + ", con=" + con);
  -         }
  -      }
  +      cf.prepare(tx);
   
         try
         {
  @@ -472,41 +473,7 @@
   
      public void start() throws Exception
      {
  -      if (config.getDriverClass() != null)
  -      {
  -         loadDriver(config.getDriverClass());
  -      }
  -      else
  -      {
  -         // A datasource will be registered in JNDI in the start portion of
  -         // its lifecycle, so now that we are in start() we can look it up
  -         InitialContext ctx = null;
  -         try
  -         {
  -            ctx = new InitialContext();
  -            DataSource dataSource = (DataSource) ctx.lookup(config.getDatasourceName());
  -            this.cf = new ManagedConnectionFactory(dataSource);
  -         }
  -         catch (NamingException e)
  -         {
  -            log.error("Failed to lookup datasource " + config.getDatasourceName() + ": " + e.getMessage(), e);
  -            throw new IllegalStateException("Failed to lookup datasource " + config.getDatasourceName() + ": " + e.getMessage());
  -         }
  -         finally
  -         {
  -            if (ctx != null)
  -            {
  -               try
  -               {
  -                  ctx.close();
  -               }
  -               catch (NamingException e)
  -               {
  -                  log.warn("Failed to close naming context.", e);
  -               }
  -            }
  -         }
  -      }
  +      cf.start();
   
         Connection con = null;
         Statement st = null;
  @@ -561,6 +528,7 @@
            {
               safeClose(st);
               cf.close(con);
  +            cf.stop();
            }
         }
      }
  @@ -718,8 +686,7 @@
         }
         catch (Exception e)
         {
  -         log.error("Failed to insert node: " + e.getMessage(), e);
  -         throw new IllegalStateException("Failed to insert node: " + e.getMessage());
  +         reportAndRethrowError("Failed to insert node", e);
         }
         finally
         {
  @@ -774,8 +741,7 @@
         }
         catch (Exception e)
         {
  -         log.error("Failed to update node for fqn " + name + ": " + e.getMessage(), e);
  -         throw new IllegalStateException("Failed to update node for fqn " + name + ": " + e.getMessage());
  +         reportAndRethrowError("Failed to update node for fqn " + name, e);
         }
         finally
         {
  @@ -841,8 +807,7 @@
         }
         catch (Exception e)
         {
  -         log.error("Failed to load node for fqn " + name + ": ", e);
  -         throw new IllegalStateException("Failed to load node for fqn " + name + ":", e);
  +         reportAndRethrowError("Failed to load node for fqn " + name, e);
         }
         finally
         {
  @@ -869,21 +834,6 @@
         }
      }
   
  -   private static void safeClose(Connection con)
  -   {
  -      if (con != null)
  -      {
  -         try
  -         {
  -            con.close();
  -         }
  -         catch (SQLException e)
  -         {
  -            log.warn("Failed to close connection: " + e.getMessage());
  -         }
  -      }
  -   }
  -
      private static void safeClose(Statement st)
      {
         if (st != null)
  @@ -914,19 +864,6 @@
         }
      }
   
  -   private static void loadDriver(String drv)
  -   {
  -      try
  -      {
  -         Class.forName(drv).newInstance();
  -      }
  -      catch (Exception e)
  -      {
  -         log.error("Failed to load driver " + drv, e);
  -         throw new IllegalStateException("Failed to load driver " + drv + ": " + e.getMessage());
  -      }
  -   }
  -
      private static String getDriverName(Connection con)
      {
         if (con == null) return null;
  @@ -939,8 +876,7 @@
         {
            // This should not happen. A J2EE compatiable JDBC driver is
            // required to fully support metadata.
  -         throw new IllegalStateException(
  -                 "Error while getting the driver name " + ": " + e.getMessage());
  +         throw new IllegalStateException("Error while getting the driver name", e);
         }
      }
   
  @@ -1009,8 +945,7 @@
         {
            // This should not happen. A J2EE compatiable JDBC driver is
            // required fully support metadata.
  -         throw new IllegalStateException(
  -                 "Error while checking if table aleady exists " + tableName + ": " + e.getMessage());
  +         throw new IllegalStateException("Error while checking if table aleady exists " + tableName, e);
         }
         finally
         {
  @@ -1018,6 +953,12 @@
         }
      }
   
  +   private void reportAndRethrowError(String message, Exception cause) throws IllegalStateException
  +   {
  +      log.error(message, cause);
  +      throw new IllegalStateException(message, cause);
  +   }
  +
      // Inner
   
      private static final Map NULL_NODE_IN_ROW = new Map()
  @@ -1082,217 +1023,4 @@
            throw new UnsupportedOperationException();
         }
      };
  -
  -   interface ConnectionFactory
  -   {
  -      Connection getConnection() throws SQLException;
  -
  -      Connection prepare(Object tx);
  -
  -      void commit(Object tx);
  -
  -      void rollback(Object tx);
  -
  -      void close(Connection con);
  -   }
  -
  -   private final class NonManagedConnectionFactory implements ConnectionFactory
  -   {
  -      private final String url;
  -      private final String usr;
  -      private final String pwd;
  -
  -      public NonManagedConnectionFactory(String url, String usr, String pwd)
  -      {
  -         this.url = url;
  -         this.usr = usr;
  -         this.pwd = pwd;
  -      }
  -
  -      public Connection prepare(Object tx)
  -      {
  -         Connection con = getConnection();
  -         try
  -         {
  -            if (con.getAutoCommit())
  -            {
  -               con.setAutoCommit(false);
  -            }
  -         }
  -         catch (Exception e)
  -         {
  -            log.error("Failed to set auto-commit: " + e.getMessage(), e);
  -            throw new IllegalStateException("Failed to set auto-commit: " + e.getMessage());
  -         }
  -         connection.set(con);
  -         return con;
  -      }
  -
  -      public Connection getConnection()
  -      {
  -         Connection con = (Connection) connection.get();
  -         if (con == null)
  -         {
  -            try
  -            {
  -               con = DriverManager.getConnection(url, usr, pwd);
  -               //               connection.set(con);
  -            }
  -            catch (SQLException e)
  -            {
  -               log.error("Failed to get connection for url=" + url + ", user=" + usr + ", password=" + pwd, e);
  -               throw new IllegalStateException("Failed to get connection for url=" +
  -                       url +
  -                       ", user=" +
  -                       usr +
  -                       ", password=" +
  -                       pwd +
  -                       ": " +
  -                       e.getMessage());
  -            }
  -         }
  -
  -         if (log.isTraceEnabled())
  -         {
  -            log.debug("using connection: " + con);
  -         }
  -
  -         return con;
  -      }
  -
  -      public void commit(Object tx)
  -      {
  -         Connection con = (Connection) connection.get();
  -         if (con == null)
  -         {
  -            throw new IllegalStateException("Failed to commit: thread is not associated with the connection!");
  -         }
  -
  -         try
  -         {
  -            con.commit();
  -            if (log.isTraceEnabled())
  -            {
  -               log.trace("committed tx=" + tx + ", con=" + con);
  -            }
  -         }
  -         catch (SQLException e)
  -         {
  -            log.error("Failed to commit", e);
  -            throw new IllegalStateException("Failed to commit: " + e.getMessage());
  -         }
  -         finally
  -         {
  -            closeTxConnection(con);
  -         }
  -      }
  -
  -      public void rollback(Object tx)
  -      {
  -         Connection con = (Connection) connection.get();
  -         if (con == null)
  -         {
  -            // todo: prepare was not called. why is rollback called?
  -            throw new IllegalStateException("Failed to rollback: thread is not associated with the connection!");
  -         }
  -
  -         try
  -         {
  -            con.rollback();
  -            if (log.isTraceEnabled())
  -            {
  -               log.trace("rolledback tx=" + tx + ", con=" + con);
  -            }
  -         }
  -         catch (SQLException e)
  -         {
  -            log.error("Failed to rollback", e);
  -            throw new IllegalStateException("Failed to rollback: " + e.getMessage());
  -         }
  -         finally
  -         {
  -            closeTxConnection(con);
  -         }
  -      }
  -
  -      public void close(Connection con)
  -      {
  -         if (con != null && con != connection.get())
  -         {
  -            try
  -            {
  -               con.close();
  -               if (log.isTraceEnabled())
  -               {
  -                  //log.trace("closed non tx connection: " + con);
  -               }
  -            }
  -            catch (SQLException e)
  -            {
  -               log.warn("Failed to close connection: " + e.getMessage());
  -            }
  -         }
  -      }
  -
  -      private void closeTxConnection(Connection con)
  -      {
  -         safeClose(con);
  -         connection.set(null);
  -      }
  -   }
  -
  -   private final class ManagedConnectionFactory
  -           implements ConnectionFactory
  -   {
  -      private final DataSource dataSource;
  -
  -      public ManagedConnectionFactory(DataSource dataSource)
  -      {
  -         // Test that ds isn't null.  This wouldn't happen in the real
  -         // world as the JNDI lookup would fail, but this check here
  -         // allows a unit test using DummyContext
  -         if (dataSource == null)
  -         {
  -            throw new IllegalArgumentException("dataSource cannot be null");
  -         }
  -
  -         this.dataSource = dataSource;
  -      }
  -
  -      public Connection prepare(Object tx)
  -      {
  -         // we don't need to set autocommit to false beause the DataSource object
  -         // is almost always has a connection pool associated with it and distributed 
  -         // transaction participation turned on which means autocommit is off by default
  -
  -         try
  -         {
  -            return getConnection();
  -         }
  -         catch (SQLException e)
  -         {
  -            log.error("Failed to get connection: " + e.getMessage(), e);
  -            throw new IllegalStateException("Failed to get connection: " + e.getMessage());
  -         }
  -      }
  -
  -      public Connection getConnection()
  -              throws SQLException
  -      {
  -         return dataSource.getConnection();
  -      }
  -
  -      public void commit(Object tx)
  -      {
  -      }
  -
  -      public void rollback(Object tx)
  -      {
  -      }
  -
  -      public void close(Connection con)
  -      {
  -         safeClose(con);
  -      }
  -   }
   }
  
  
  
  1.1      date: 2007/01/21 15:46:42;  author: gzamarreno;  state: Exp;JBossCache/src/org/jboss/cache/loader/NonManagedConnectionFactory.java
  
  Index: NonManagedConnectionFactory.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   * 
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.loader;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  import java.sql.Connection;
  import java.sql.DriverManager;
  import java.sql.SQLException;
  
  /**
   * Standard connection factory for standalone JBossCache implementations without connection pooling capabilities.
   *
   * @author <a href="mailto:hmesha at novell.com">Hany Mesha </a>
   * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
   */
  class NonManagedConnectionFactory implements ConnectionFactory
  {
     private static final Log log = LogFactory.getLog(NonManagedConnectionFactory.class);
     
     private static final ThreadLocal connection = new ThreadLocal();
  
     private String url;
     private String usr;
     private String pwd;
     private String driverClass;
  
     public void setConfig(JDBCCacheLoaderConfig config)
     {
        url = config.getJdbcURL();
        usr = config.getJdbcUser();
        pwd = config.getJdbcPassword();
        driverClass = config.getDriverClass();
     }
  
     public void start() throws Exception
     {
        loadDriver(driverClass);
     }
  
     public void prepare(Object tx)
     {
        Connection con = getConnection();
        try
        {
           if (con.getAutoCommit())
           {
              con.setAutoCommit(false);
           }
        }
        catch (Exception e)
        {
           reportAndRethrowError("Failed to set auto-commit", e);
        }
  
        /* Connection set in ThreadLocal, no reason to return. It was previously returned for legacy purpouses
        and to trace log the connection opening in JDBCCacheLoader. */
        connection.set(con);
  
        if (log.isTraceEnabled())
        {
           log.trace("opened tx connection: tx=" + tx + ", con=" + con);
        }      
  
     }
  
     public Connection getConnection()
     {
        Connection con = (Connection) connection.get();
        
        if (con == null)
        {
           try
           {
              con = checkoutConnection();
              //               connection.set(con);
           }
           catch (SQLException e)
           {
              reportAndRethrowError("Failed to get connection for url=" + url + ", user=" + usr + ", password=" + pwd, e);
           }
        }
  
        if (log.isTraceEnabled())
        {
           log.trace("using connection: " + con);
        }
  
        return con;
     }
  
     public Connection checkoutConnection() throws SQLException
     {
        return DriverManager.getConnection(url, usr, pwd);
     }
  
     public void commit(Object tx)
     {
        Connection con = (Connection) connection.get();
        if (con == null)
        {
           throw new IllegalStateException("Failed to commit: thread is not associated with the connection!");
        }
  
        try
        {
           con.commit();
           if (log.isTraceEnabled())
           {
              log.trace("committed tx=" + tx + ", con=" + con);
           }
        }
        catch (SQLException e)
        {
           reportAndRethrowError("Failed to commit", e);
        }
        finally
        {
           closeTxConnection(con);
        }
     }
  
     public void rollback(Object tx)
     {
        Connection con = (Connection) connection.get();
        if (con == null)
        {
           // todo: prepare was not called. why is rollback called?
           throw new IllegalStateException("Failed to rollback: thread is not associated with the connection!");
        }
  
        try
        {
           con.rollback();
           if (log.isTraceEnabled())
           {
              log.trace("rolledback tx=" + tx + ", con=" + con);
           }
        }
        catch (SQLException e)
        {
           reportAndRethrowError("Failed to rollback", e);
        }
        finally
        {
           closeTxConnection(con);
        }
     }
  
     public void close(Connection con)
     {
        if (con != null && con != connection.get())
        {
           try
           {
              con.close();
              
              if (log.isTraceEnabled())
              {
                 log.trace("closed non tx connection: " + con);
              }
           }
           catch (SQLException e)
           {
              log.warn("Failed to close connection " + con , e);
           }
        }
     }
  
     public void stop()
     {
     }
  
     public String getUrl()
     {
        return url;
     }
  
     public String getUsr()
     {
        return usr;
     }
  
     public String getPwd()
     {
        return pwd;
     }
  
     public String getDriverClass()
     {
        return driverClass;
     }   
  
     protected void loadDriver(String drv)
     {
        try
        {
           if (log.isTraceEnabled()) { log.trace("Attempting to load driver: " + drv); }
           Class.forName(drv).newInstance();
        }
        catch (Exception e)
        {
           reportAndRethrowError("Failed to load driver " + drv, e);
        }
     }   
  
     private void closeTxConnection(Connection con)
     {
        safeClose(con);
        connection.set(null);
     }
  
     private void safeClose(Connection con)
     {
        if (con != null)
        {
           try
           {
              con.close();
           }
           catch (SQLException e)
           {
              log.warn("Failed to close connection", e);
           }
        }
     }
  
     private void reportAndRethrowError(String message, Exception cause) throws IllegalStateException
     {
        log.error(message, cause);
        throw new IllegalStateException(message, cause);
     }
  }
  
  
  
  
  1.1      date: 2007/01/21 15:46:42;  author: gzamarreno;  state: Exp;JBossCache/src/org/jboss/cache/loader/ManagedConnectionFactory.java
  
  Index: ManagedConnectionFactory.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   * 
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.loader;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  import javax.sql.DataSource;
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  import java.sql.Connection;
  import java.sql.SQLException;
  
  /**
   * ManagedConnectionFactory for Application Server managed environments
   *
   * @author <a href="mailto:hmesha at novell.com">Hany Mesha </a>
   * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
   */
  public class ManagedConnectionFactory implements ConnectionFactory
  {
     private static final Log log = LogFactory.getLog(ManagedConnectionFactory.class);
     
     private DataSource dataSource;
     private String datasourceName;
  
     public void setConfig(JDBCCacheLoaderConfig config)
     {
        datasourceName = config.getDatasourceName();
     }
  
     public void start() throws Exception
     {
        // A datasource will be registered in JNDI in the start portion of
        // its lifecycle, so now that we are in start() we can look it up
        InitialContext ctx = null;
        try
        {
           ctx = new InitialContext();
           dataSource = (DataSource) ctx.lookup(datasourceName);
           if (log.isTraceEnabled()) { log.trace("Datasource lookup for " + datasourceName + " succeded: " + dataSource);}
        }
        catch (NamingException e)
        {
           reportAndRethrowError("Failed to lookup datasource " + datasourceName, e);
        }
        finally
        {
           if (ctx != null)
           {
              try
              {
                 ctx.close();
              }
              catch (NamingException e)
              {
                 log.warn("Failed to close naming context.", e);
              }
           }
        }
     }
  
     public Connection getConnection()
             throws SQLException
     {
        Connection connection = dataSource.getConnection();
        if (log.isTraceEnabled()) { log.trace("Connection checked out: " + connection); }
        return connection;
     }
  
     public void prepare(Object txId)
     {
        /* This implementation should be left empty. In a managed environment, we retrieve the datasource from
        the application server, and it's down to the configuration of the datasource whether it will participate
        in the current transaction, i.e. local-tx-datasource, no-tx-datasource,...etc. The application server will
        make sure that if configured, the datasource will participate in the transaction and will commit/rollback
        changes if required. Therefore, we don't have to do anything for these transactional methods but leave them
        empty. */
     }
  
     public void commit(Object txId)
     {
        /* This implementation should be left empty. In a managed environment, we retrieve the datasource from
        the application server, and it's down to the configuration of the datasource whether it will participate
        in the current transaction, i.e. local-tx-datasource, no-tx-datasource,...etc. The application server will
        make sure that if configured, the datasource will participate in the transaction and will commit/rollback
        changes if required. Therefore, we don't have to do anything for these transactional methods but leave them
        empty. */
     }
  
     public void rollback(Object txId)
     {
        /* This implementation should be left empty. In a managed environment, we retrieve the datasource from
        the application server, and it's down to the configuration of the datasource whether it will participate
        in the current transaction, i.e. local-tx-datasource, no-tx-datasource,...etc. The application server will
        make sure that if configured, the datasource will participate in the transaction and will commit/rollback
        changes if required. Therefore, we don't have to do anything for these transactional methods but leave them
        empty. */      
     }
  
     public void close(Connection con)
     {
        safeClose(con);
     }
  
     public void stop()
     {
     }
  
     private void safeClose(Connection con)
     {
        if (con != null)
        {
           try
           {
              con.close();
           }
           catch (SQLException e)
           {
              log.warn("Failed to close connection", e);
           }
        }
     }
  
     private void reportAndRethrowError(String message, Exception cause) throws IllegalStateException
     {
        log.error(message, cause);
        throw new IllegalStateException(message, cause);
     }
  }
  
  
  
  1.1      date: 2007/01/21 15:46:42;  author: gzamarreno;  state: Exp;JBossCache/src/org/jboss/cache/loader/ConnectionFactory.java
  
  Index: ConnectionFactory.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   * 
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.loader;
  
  import java.sql.Connection;
  import java.sql.SQLException;
  
  /**
   * ConnectionFactory interface defining the operations to be defined by connection providers
   *
   * @author <a href="mailto:hmesha at novell.com">Hany Mesha </a>
   * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
   */
  public interface ConnectionFactory
  {
      void setConfig(JDBCCacheLoaderConfig config);
  
      void start() throws Exception;
  
      Connection getConnection() throws SQLException;
  
      void prepare(Object tx);
  
      void commit(Object tx);
  
      void rollback(Object tx);
  
      void close(Connection con);
  
      void stop();
  }
  
  
  
  1.1      date: 2007/01/21 15:46:42;  author: gzamarreno;  state: Exp;JBossCache/src/org/jboss/cache/loader/C3p0ConnectionFactory.java
  
  Index: C3p0ConnectionFactory.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   * 
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.loader;
  
  import com.mchange.v2.c3p0.DataSources;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  import javax.sql.DataSource;
  import java.sql.Connection;
  import java.sql.SQLException;
  import java.util.Enumeration;
  import java.util.Properties;
  
  /**
   * Standalone connection factory based on c3p0 connection pooling library
   *
   * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
   */
  public class C3p0ConnectionFactory extends NonManagedConnectionFactory
  {
     private static final Log log = LogFactory.getLog(C3p0ConnectionFactory.class);
  
     private DataSource ds;
  
     public void setConfig(JDBCCacheLoaderConfig config)
     {
        super.setConfig(config);
  
        Properties properties = config.getProperties();
        Enumeration e = properties.propertyNames();
        while (e.hasMoreElements())
        {
           String property = (String) e.nextElement();
           if (property.startsWith("c3p0."))
           {
              /* System properties should come before settings from XML configuration.
  
              For simplicity (c3p0 manual says overrides should not carry c3p0. start whereas system properties yes)
              and to avoid parsing, it's easier to set the values from XML configuration that should be c3p0. as
              system properties.
  
              So, this check allows us to determine if the System property was not set, in which case, we take the
              value from the XML configuration and set it to be a System property. If the value from the XML config
              was already set as System property, we do nothing, original System property should stand. */
  
              String xmlPropertyValue = properties.getProperty(property);
              String sysPropertyValue = System.getProperty(property);
              if (System.getProperty(property) == null)
              {
                 System.setProperty(property, xmlPropertyValue);
                 if (log.isDebugEnabled())
                 {
                    log.debug("c3p0 property defined in XML: " + property + "=" + xmlPropertyValue);
                 }
              }
              else
              {
                 if (log.isDebugEnabled())
                 {
                    log.debug(property + "=" + sysPropertyValue + " defined as system property. It will override the value defined in XML which was: " + xmlPropertyValue);
                 };
              }
           }
        }
     }
  
     public void start() throws Exception
     {
        /* We need to call super so that the driver is loaded. This is required by the C3P0 manual. */
        super.start();
  
        DataSource unpooled = DataSources.unpooledDataSource(getUrl(), getUsr(), getPwd());
        ds = DataSources.pooledDataSource(unpooled);
  
        if (log.isDebugEnabled())
        {
           log.debug("Pooled datasource(url=" + getUrl() + ",usr=" + getUsr() + ",pwd=" + getPwd() + ") started.");
        }
     }
  
     public Connection checkoutConnection() throws SQLException
     {
        Connection connection = ds.getConnection();
        if (log.isTraceEnabled()) { log.trace("Connection checked out: " + connection); }
        return connection;
     }
  
     public void stop()
     {
        try
        {
           DataSources.destroy(ds);
           if (log.isDebugEnabled()) { log.debug("Pooled datasource destroyed."); }
        } catch (SQLException sqle)
        {
           log.warn("Could not destroy C3P0 connection pool: " + ds, sqle);
        }
     }
  
     protected DataSource getDataSource()
     {
        return ds;
     }
  }
  
  
  



More information about the jboss-cvs-commits mailing list