You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ma...@apache.org on 2013/10/30 15:46:51 UTC

svn commit: r1537116 - /commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp2/BasicDataSource.java

Author: markt
Date: Wed Oct 30 14:46:51 2013
New Revision: 1537116

URL: http://svn.apache.org/r1537116
Log:
[DBCP-402] Add a method to enable a Driver instance to be set directly.

Modified:
    commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp2/BasicDataSource.java

Modified: commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp2/BasicDataSource.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp2/BasicDataSource.java?rev=1537116&r1=1537115&r2=1537116&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp2/BasicDataSource.java (original)
+++ commons/proper/dbcp/trunk/src/java/org/apache/commons/dbcp2/BasicDataSource.java Wed Oct 30 14:46:51 2013
@@ -226,12 +226,49 @@ public class BasicDataSource implements 
     }
 
     /**
+     * The instance of the JDBC Driver to use.
+     */
+    private Driver driver = null;
+    
+    /**
+     * Returns the JDBC Driver that has been configured for use by this pool.
+     * <p>
+     * Note: This getter only returns the last value set by a call to
+     * {@link #setDriver(Driver)}. It does not return any driver instance that
+     * may have been created from the value set via
+     * {@link #setDriverClassName(String)}.
+     * 
+     * @return the JDBC Driver that has been configured for use by this pool
+     */
+    public synchronized Driver getDriver() {
+        return driver;
+    }
+    
+    /**
+     * Sets the JDBC Driver instance to use for this pool.
+     * <p>
+     * Note: this method currently has no effect once the pool has been
+     * initialized.  The pool is initialized the first time one of the
+     * following methods is invoked: <code>getConnection, setLogwriter,
+     * setLoginTimeout, getLoginTimeout, getLogWriter.</code></p>
+     * 
+     * @param driver
+     */
+    public synchronized void setDriver(Driver driver) {
+        this.driver = driver;
+    }
+    
+    /**
      * The fully qualified Java class name of the JDBC driver to be used.
      */
     protected String driverClassName = null;
 
     /**
      * Returns the jdbc driver class name.
+     * <p>
+     * Note: This getter only returns the last value set by a call to
+     * {@link #setDriverClassName(String)}. It does not return the class name of
+     * any driver that may have been set via {@link #setDriver(Driver)}.
      *
      * @return the jdbc driver class name
      */
@@ -270,6 +307,11 @@ public class BasicDataSource implements 
     /**
      * Returns the class loader specified for loading the JDBC driver. Returns
      * <code>null</code> if no class loader has been explicitly specified.
+     * <p>
+     * Note: This getter only returns the last value set by a call to
+     * {@link #setDriverClassLoader(ClassLoader)}. It does not return the class
+     * loader of any driver that may have been set via
+     * {@link #setDriver(Driver)}.
      */
     public synchronized ClassLoader getDriverClassLoader() {
         return this.driverClassLoader;
@@ -1677,10 +1719,12 @@ public class BasicDataSource implements 
      * Creates a JDBC connection factory for this datasource.  The JDBC driver
      * is loaded using the following algorithm:
      * <ol>
-     * <li>If {@link #driverClassName} is specified that class is loaded using
-     * the {@link ClassLoader} of this class or, if {@link #driverClassLoader}
-     * is set, {@link #driverClassName} is loaded with the specified
-     * {@link ClassLoader}.</li>
+     * <li>If a Driver instance has been specified via
+     * {@link #setDriver(Driver)} use it</li>
+     * <li>If no Driver instance was specified and {@link #driverClassName} is
+     * specified that class is loaded using the {@link ClassLoader} of this
+     * class or, if {@link #driverClassLoader} is set, {@link #driverClassName}
+     * is loaded with the specified {@link ClassLoader}.</li>
      * <li>If {@link #driverClassName} is specified and the previous attempt
      * fails, the class is loaded using the context class loader of the current
      * thread.</li>
@@ -1692,58 +1736,60 @@ public class BasicDataSource implements 
     protected ConnectionFactory createConnectionFactory() throws SQLException {
         // Load the JDBC driver class
         Class<Driver> driverFromCCL = null;
-        if (driverClassName != null) {
-            try {
+        Driver driver = this.driver;
+
+        if (driver == null) {
+            if (driverClassName != null) {
                 try {
-                    if (driverClassLoader == null) {
-                        @SuppressWarnings("unchecked")
-                        Class<Driver> c =
-                                (Class<Driver>) Class.forName(driverClassName);
-                        driverFromCCL = c;
-                    } else {
+                    try {
+                        if (driverClassLoader == null) {
+                            @SuppressWarnings("unchecked")
+                            Class<Driver> c =
+                                    (Class<Driver>) Class.forName(driverClassName);
+                            driverFromCCL = c;
+                        } else {
+                            @SuppressWarnings("unchecked")
+                            Class<Driver> c = (Class<Driver>) Class.forName(
+                                    driverClassName, true, driverClassLoader);
+                            driverFromCCL = c;
+                        }
+                    } catch (ClassNotFoundException cnfe) {
                         @SuppressWarnings("unchecked")
-                        Class<Driver> c = (Class<Driver>) Class.forName(
-                                driverClassName, true, driverClassLoader);
+                        Class<Driver> c = (Class<Driver>) Thread.currentThread(
+                                ).getContextClassLoader().loadClass(
+                                        driverClassName);
                         driverFromCCL = c;
                     }
-                } catch (ClassNotFoundException cnfe) {
-                    @SuppressWarnings("unchecked")
-                    Class<Driver> c = (Class<Driver>) Thread.currentThread(
-                            ).getContextClassLoader().loadClass(
-                                    driverClassName);
-                    driverFromCCL = c;
+                } catch (Exception t) {
+                    String message = "Cannot load JDBC driver class '" +
+                        driverClassName + "'";
+                    logWriter.println(message);
+                    t.printStackTrace(logWriter);
+                    throw new SQLException(message, t);
+                }
+            }
+
+            try {
+                if (driverFromCCL == null) {
+                    driver = DriverManager.getDriver(url);
+                } else {
+                    // Usage of DriverManager is not possible, as it does not
+                    // respect the ContextClassLoader
+                    driver = driverFromCCL.newInstance();
+                    if (!driver.acceptsURL(url)) {
+                        throw new SQLException("No suitable driver", "08001");
+                    }
                 }
             } catch (Exception t) {
-                String message = "Cannot load JDBC driver class '" +
-                    driverClassName + "'";
+                String message = "Cannot create JDBC driver of class '" +
+                    (driverClassName != null ? driverClassName : "") +
+                    "' for connect URL '" + url + "'";
                 logWriter.println(message);
                 t.printStackTrace(logWriter);
                 throw new SQLException(message, t);
             }
         }
 
-        // Create a JDBC driver instance
-        Driver driver = null;
-        try {
-            if (driverFromCCL == null) {
-                driver = DriverManager.getDriver(url);
-            } else {
-                // Usage of DriverManager is not possible, as it does not
-                // respect the ContextClassLoader
-                driver = driverFromCCL.newInstance();
-                if (!driver.acceptsURL(url)) {
-                    throw new SQLException("No suitable driver", "08001");
-                }
-            }
-        } catch (Exception t) {
-            String message = "Cannot create JDBC driver of class '" +
-                (driverClassName != null ? driverClassName : "") +
-                "' for connect URL '" + url + "'";
-            logWriter.println(message);
-            t.printStackTrace(logWriter);
-            throw new SQLException(message, t);
-        }
-
         // Can't test without a validationQuery
         if (validationQuery == null) {
             setTestOnBorrow(false);
@@ -1766,7 +1812,8 @@ public class BasicDataSource implements 
             log("DBCP DataSource configured without a 'password'");
         }
 
-        ConnectionFactory driverConnectionFactory = new DriverConnectionFactory(driver, url, connectionProperties);
+        ConnectionFactory driverConnectionFactory =
+                new DriverConnectionFactory(driver, url, connectionProperties);
         return driverConnectionFactory;
     }