This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-dbcp.git

commit fdc855e5ded81631c89c9b9142e64bde8507216e
Author: Gary Gregory <gardgreg...@gmail.com>
AuthorDate: Tue Jul 30 14:24:45 2019 -0400

    Split out factory code out of BasicDataSource in small factory classes.
    This helps reduce the size and complexity of BasicDataSource and fixes a
    Checkstyle violation for the class being too big.
---
 .../org/apache/commons/dbcp2/BasicDataSource.java  | 146 +++++----------------
 .../commons/dbcp2/BasicDataSourceFactory.java      |   4 +-
 .../commons/dbcp2/ConnectionFactoryFactory.java    |  79 +++++++++++
 .../commons/dbcp2/DriverConnectionFactory.java     | 110 ----------------
 .../org/apache/commons/dbcp2/DriverFactory.java    |  81 ++++++++++++
 5 files changed, 196 insertions(+), 224 deletions(-)

diff --git a/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java 
b/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java
index fd6b4fb..243a29f 100644
--- a/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java
+++ b/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java
@@ -469,67 +469,7 @@ public class BasicDataSource implements DataSource, 
BasicDataSourceMXBean, MBean
      */
     protected ConnectionFactory createConnectionFactory() throws SQLException {
         // Load the JDBC driver class
-        Driver driverToUse = this.driver;
-
-        if (driverToUse == null) {
-            Class<?> driverFromCCL = null;
-            if (driverClassName != null) {
-                try {
-                    try {
-                        if (driverClassLoader == null) {
-                            driverFromCCL = Class.forName(driverClassName);
-                        } else {
-                            driverFromCCL = Class.forName(driverClassName, 
true, driverClassLoader);
-                        }
-                    } catch (final ClassNotFoundException cnfe) {
-                        driverFromCCL = 
Thread.currentThread().getContextClassLoader().loadClass(driverClassName);
-                    }
-                } catch (final Exception t) {
-                    final String message = "Cannot load JDBC driver class '" + 
driverClassName + "'";
-                    logWriter.println(message);
-                    t.printStackTrace(logWriter);
-                    throw new SQLException(message, t);
-                }
-            }
-
-            try {
-                if (driverFromCCL == null) {
-                    driverToUse = DriverManager.getDriver(url);
-                } else {
-                    // Usage of DriverManager is not possible, as it does not
-                    // respect the ContextClassLoader
-                    // N.B. This cast may cause ClassCastException which is
-                    // handled below
-                    driverToUse = (Driver) 
driverFromCCL.getConstructor().newInstance();
-                    if (!driverToUse.acceptsURL(url)) {
-                        throw new SQLException("No suitable driver", "08001");
-                    }
-                }
-            } catch (final Exception t) {
-                final 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);
-            }
-        }
-
-        // Set up the driver connection factory we will use
-        final String user = userName;
-        if (user != null) {
-            connectionProperties.put("user", user);
-        } else {
-            log("DBCP DataSource configured without a 'username'");
-        }
-
-        final String pwd = password;
-        if (pwd != null) {
-            connectionProperties.put("password", pwd);
-        } else {
-            log("DBCP DataSource configured without a 'password'");
-        }
-
-        return createConnectionFactory(driverToUse);
+        return ConnectionFactoryFactory.createConnectionFactory(this, 
DriverFactory.createDriver(this));
     }
 
     /**
@@ -831,6 +771,19 @@ public class BasicDataSource implements DataSource, 
BasicDataSourceMXBean, MBean
     }
 
     /**
+     * Returns the ConnectionFactoryClassName that has been configured for use 
by this pool.
+     * <p>
+     * Note: This getter only returns the last value set by a call to {@link 
#setConnectionFactoryClassName(String)}.
+     * </p>
+     *
+     * @return the ConnectionFactoryClassName that has been configured for use 
by this pool.
+     * @since 2.7.0
+     */
+    public String getConnectionFactoryClassName() {
+        return this.connectionFactoryClassName;
+    }
+
+    /**
      * Returns the list of SQL statements executed when a physical connection 
is first created. Returns an empty list if
      * there are no initialization statements configured.
      *
@@ -991,19 +944,6 @@ public class BasicDataSource implements DataSource, 
BasicDataSourceMXBean, MBean
     }
 
     /**
-     * Returns the ConnectionFactoryClassName that has been configured for use 
by this pool.
-     * <p>
-     * Note: This getter only returns the last value set by a call to {@link 
#setConnectionFactoryClassName(String)}.
-     * </p>
-     *
-     * @return the ConnectionFactoryClassName that has been configured for use 
by this pool.
-     * @since 2.7.0
-     */
-    public String getConnectionFactoryClassName() {
-        return this.connectionFactoryClassName;
-    }
-
-    /**
      * Returns the value of the flag that controls whether or not connections 
being returned to the pool will be checked
      * and configured with {@link Connection#setAutoCommit(boolean) 
Connection.setAutoCommit(true)} if the auto commit
      * setting is {@code false} when the connection is returned. It is 
<code>true</code> by default.
@@ -1599,12 +1539,14 @@ public class BasicDataSource implements DataSource, 
BasicDataSourceMXBean, MBean
 
     /**
      * Logs the given throwable.
-     * 
+     * @param message TODO
      * @param throwable the throwable.
+     * 
      * @since 2.7.0
      */
-    protected void log(Throwable throwable) {
+    protected void log(String message, Throwable throwable) {
         if (logWriter != null) {
+            logWriter.println(message);
             throwable.printStackTrace(logWriter);
         }        
     }
@@ -1715,6 +1657,8 @@ public class BasicDataSource implements DataSource, 
BasicDataSourceMXBean, MBean
         this.autoCommitOnReturn = autoCommitOnReturn;
     }
 
+    // ----------------------------------------------------- DataSource Methods
+
     /**
      * Sets the state caching flag.
      *
@@ -1724,7 +1668,19 @@ public class BasicDataSource implements DataSource, 
BasicDataSourceMXBean, MBean
         this.cacheState = cacheState;
     }
 
-    // ----------------------------------------------------- DataSource Methods
+    /**
+     * Sets the ConnectionFactory class name.
+     *
+     * @param connectionFactoryClassName A class name.
+     * @since 2.7.0
+     */
+    public void setConnectionFactoryClassName(final String 
connectionFactoryClassName) {
+        if (isEmpty(connectionFactoryClassName)) {
+            this.connectionFactoryClassName = null;
+        } else {
+            this.connectionFactoryClassName = connectionFactoryClassName;
+        }
+    }
 
     /**
      * Sets the list of SQL statements to be executed when a physical 
connection is first created.
@@ -1974,20 +1930,6 @@ public class BasicDataSource implements DataSource, 
BasicDataSourceMXBean, MBean
     }
 
     /**
-     * Sets the ConnectionFactory class name.
-     *
-     * @param connectionFactoryClassName A class name.
-     * @since 2.7.0
-     */
-    public void setConnectionFactoryClassName(final String 
connectionFactoryClassName) {
-        if (isEmpty(connectionFactoryClassName)) {
-            this.connectionFactoryClassName = null;
-        } else {
-            this.connectionFactoryClassName = connectionFactoryClassName;
-        }
-    }
-
-    /**
      * Sets the value of the flag that controls whether or not connections 
being returned to the pool will be checked
      * and configured with {@link Connection#setAutoCommit(boolean) 
Connection.setAutoCommit(true)} if the auto commit
      * setting is {@code false} when the connection is returned. It is 
<code>true</code> by default.
@@ -2214,6 +2156,8 @@ public class BasicDataSource implements DataSource, 
BasicDataSourceMXBean, MBean
         }
     }
 
+    // ------------------------------------------------------ Protected Methods
+
     /**
      * Sets the minimum number of idle connections in the pool. The pool 
attempts to ensure that minIdle connections are
      * available when the idle object evictor runs. The value of this property 
has no effect unless
@@ -2229,8 +2173,6 @@ public class BasicDataSource implements DataSource, 
BasicDataSourceMXBean, MBean
         }
     }
 
-    // ------------------------------------------------------ Protected Methods
-
     /**
      * Sets the value of the {@link #numTestsPerEvictionRun} property.
      *
@@ -2515,22 +2457,4 @@ public class BasicDataSource implements DataSource, 
BasicDataSourceMXBean, MBean
         config.setJmxNamePrefix(Constants.JMX_CONNECTION_POOL_PREFIX);
     }
 
-    private ConnectionFactory createConnectionFactory(final Driver driver) 
throws SQLException {
-        if (connectionFactoryClassName != null) {
-            try {
-                Class<?> connectionFactoryFromCCL = 
Class.forName(connectionFactoryClassName);
-                return (ConnectionFactory) connectionFactoryFromCCL
-                        .getConstructor(Driver.class, String.class, 
Properties.class)
-                        .newInstance(driver, url, connectionProperties);
-            } catch (final Exception t) {
-                final String message = "Cannot load ConnectionFactory 
implementation '" + connectionFactoryClassName
-                        + "'";
-                logWriter.println(message);
-                t.printStackTrace(logWriter);
-                throw new SQLException(message, t);
-            }
-        }
-        return new DriverConnectionFactory(driver, url, connectionProperties);
-    }
-
 }
diff --git a/src/main/java/org/apache/commons/dbcp2/BasicDataSourceFactory.java 
b/src/main/java/org/apache/commons/dbcp2/BasicDataSourceFactory.java
index e826cff..945d163 100644
--- a/src/main/java/org/apache/commons/dbcp2/BasicDataSourceFactory.java
+++ b/src/main/java/org/apache/commons/dbcp2/BasicDataSourceFactory.java
@@ -552,11 +552,9 @@ public class BasicDataSourceFactory implements 
ObjectFactory {
 
         value = properties.getProperty(PROP_CONNECTION_FACTORY_CLASS_NAME);
         if (value != null) {
-               dataSource.setConnectionFactoryClassName(value);
+            dataSource.setConnectionFactoryClassName(value);
         }
 
-
-
         // DBCP-215
         // Trick to make sure that initialSize connections are created
         if (dataSource.getInitialSize() > 0) {
diff --git 
a/src/main/java/org/apache/commons/dbcp2/ConnectionFactoryFactory.java 
b/src/main/java/org/apache/commons/dbcp2/ConnectionFactoryFactory.java
new file mode 100644
index 0000000..5d635bb
--- /dev/null
+++ b/src/main/java/org/apache/commons/dbcp2/ConnectionFactoryFactory.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.dbcp2;
+
+import java.sql.Driver;
+import java.sql.SQLException;
+import java.util.Properties;
+
+/*
+ * Creates {@link ConnectionFactory} instances.
+ * 
+ * @since 2.7.0
+ */
+class ConnectionFactoryFactory {
+
+    /**
+     * Creates a new {@link DriverConnectionFactory} allowing for an override 
through
+     * {@link BasicDataSource#getDriverClassName()}.
+     * 
+     * @param basicDataSource Configures creation.
+     * @param driver          The JDBC driver.
+     * @return a new {@link DriverConnectionFactory} allowing for a {@link 
BasicDataSource#getDriverClassName()}
+     *         override.
+     * @throws SQLException Thrown when instantiation fails.
+     */
+    static ConnectionFactory createConnectionFactory(final BasicDataSource 
basicDataSource, final Driver driver)
+            throws SQLException {
+        final Properties connectionProperties = 
basicDataSource.getConnectionProperties();
+        final String url = basicDataSource.getUrl();
+        // Set up the driver connection factory we will use
+        final String user = basicDataSource.getUsername();
+        if (user != null) {
+            connectionProperties.put("user", user);
+        } else {
+            basicDataSource.log("DBCP DataSource configured without a 
'username'");
+        }
+
+        final String pwd = basicDataSource.getPassword();
+        if (pwd != null) {
+            connectionProperties.put("password", pwd);
+        } else {
+            basicDataSource.log("DBCP DataSource configured without a 
'password'");
+        }
+        if (basicDataSource != null) {
+            final String connectionFactoryClassName = 
basicDataSource.getConnectionFactoryClassName();
+            if (connectionFactoryClassName != null) {
+                try {
+                    final Class<?> connectionFactoryFromCCL = 
Class.forName(connectionFactoryClassName);
+                    return (ConnectionFactory) connectionFactoryFromCCL
+                            .getConstructor(Driver.class, String.class, 
Properties.class)
+                            .newInstance(driver, url, connectionProperties);
+                } catch (final Exception t) {
+                    final String message = "Cannot load ConnectionFactory 
implementation '" + connectionFactoryClassName
+                            + "'";
+                    basicDataSource.log(message, t);
+                    throw new SQLException(message, t);
+                }
+            }
+        }
+        // Defaults to DriverConnectionFactory
+        return new DriverConnectionFactory(driver, url, connectionProperties);
+    }
+
+}
diff --git 
a/src/main/java/org/apache/commons/dbcp2/DriverConnectionFactory.java 
b/src/main/java/org/apache/commons/dbcp2/DriverConnectionFactory.java
index 1e25e4d..0434584 100644
--- a/src/main/java/org/apache/commons/dbcp2/DriverConnectionFactory.java
+++ b/src/main/java/org/apache/commons/dbcp2/DriverConnectionFactory.java
@@ -18,7 +18,6 @@ package org.apache.commons.dbcp2;
 
 import java.sql.Connection;
 import java.sql.Driver;
-import java.sql.DriverManager;
 import java.sql.SQLException;
 import java.util.Properties;
 
@@ -29,115 +28,6 @@ import java.util.Properties;
  */
 public class DriverConnectionFactory implements ConnectionFactory {
 
-    /**
-     * Creates a JDBC connection factory for the given data source. The JDBC 
driver is loaded using the following
-     * algorithm:
-     * <ol>
-     * <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>
-     * <li>If a driver still isn't loaded one is loaded via the {@link 
DriverManager} using the specified {@link #url}.
-     * </ol>
-     * <p>
-     * This method exists so subclasses can replace the implementation class.
-     * </p>
-     *
-     * @return A new connection factory.
-     *
-     * @throws SQLException If the connection factory cannot be created
-     */
-    static ConnectionFactory createConnectionFactory(final BasicDataSource 
basicDataSource) throws SQLException {
-        // Load the JDBC driver class
-        Driver driverToUse = basicDataSource.getDriver();
-        final String driverClassName = basicDataSource.getDriverClassName();
-        final ClassLoader driverClassLoader = 
basicDataSource.getDriverClassLoader();
-        final String url = basicDataSource.getUrl();
-        
-        final Properties connectionProperties = 
basicDataSource.getConnectionProperties();
-        
-        if (driverToUse == null) {
-            Class<?> driverFromCCL = null;
-            if (driverClassName != null) {
-                try {
-                    try {
-                        if (driverClassLoader == null) {
-                            driverFromCCL = Class.forName(driverClassName);
-                        } else {
-                            driverFromCCL = Class.forName(driverClassName, 
true, driverClassLoader);
-                        }
-                    } catch (final ClassNotFoundException cnfe) {
-                        driverFromCCL = 
Thread.currentThread().getContextClassLoader().loadClass(driverClassName);
-                    }
-                } catch (final Exception t) {
-                    final String message = "Cannot load JDBC driver class '" + 
driverClassName + "'";
-                    basicDataSource.log(message);
-                    basicDataSource.log(t);
-                    throw new SQLException(message, t);
-                }
-            }
-
-            try {
-                if (driverFromCCL == null) {
-                    driverToUse = DriverManager.getDriver(url);
-                } else {
-                    // Usage of DriverManager is not possible, as it does not
-                    // respect the ContextClassLoader
-                    // N.B. This cast may cause ClassCastException which is
-                    // handled below
-                    driverToUse = (Driver) 
driverFromCCL.getConstructor().newInstance();
-                    if (!driverToUse.acceptsURL(url)) {
-                        throw new SQLException("No suitable driver", "08001");
-                    }
-                }
-            } catch (final Exception t) {
-                final String message = "Cannot create JDBC driver of class '"
-                        + (driverClassName != null ? driverClassName : "") + 
"' for connect URL '" + url + "'";
-                basicDataSource.log(message);
-                basicDataSource.log(t);
-                throw new SQLException(message, t);
-            }
-        }
-
-        // Set up the driver connection factory we will use
-        final String user = basicDataSource.getUsername();
-        if (user != null) {
-            connectionProperties.put("user", user);
-        } else {
-            basicDataSource.log("DBCP DataSource configured without a 
'username'");
-        }
-
-        final String pwd = basicDataSource.getPassword();
-        if (pwd != null) {
-            connectionProperties.put("password", pwd);
-        } else {
-            basicDataSource.log("DBCP DataSource configured without a 
'password'");
-        }
-
-        return createConnectionFactory(basicDataSource, driverToUse);
-    }
-    private static ConnectionFactory createConnectionFactory(final 
BasicDataSource basicDataSource, final Driver driver) throws SQLException {
-        final String connectionFactoryClassName = 
basicDataSource.getConnectionFactoryClassName();
-        final Properties connectionProperties = 
basicDataSource.getConnectionProperties();
-        final String url = basicDataSource.getUrl();
-        if (connectionFactoryClassName != null) {
-            try {
-                final Class<?> connectionFactoryFromCCL = 
Class.forName(connectionFactoryClassName);
-                return (ConnectionFactory) connectionFactoryFromCCL
-                        .getConstructor(Driver.class, String.class, 
Properties.class)
-                        .newInstance(driver, url, connectionProperties);
-            } catch (final Exception t) {
-                final String message = "Cannot load ConnectionFactory 
implementation '" + connectionFactoryClassName
-                        + "'";
-                basicDataSource.log(message);
-                basicDataSource.log(t);
-                throw new SQLException(message, t);
-            }
-        }
-        return new DriverConnectionFactory(driver, url, connectionProperties);
-    }
     private final String connectionString;
 
     private final Driver driver;
diff --git a/src/main/java/org/apache/commons/dbcp2/DriverFactory.java 
b/src/main/java/org/apache/commons/dbcp2/DriverFactory.java
new file mode 100644
index 0000000..2a05453
--- /dev/null
+++ b/src/main/java/org/apache/commons/dbcp2/DriverFactory.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.dbcp2;
+
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+/*
+ * Creates {@link Driver} instances.
+ * 
+ * @since 2.7.0
+ */
+class DriverFactory {
+
+    static Driver createDriver(final BasicDataSource basicDataSource) throws 
SQLException {
+        // Load the JDBC driver class
+        Driver driverToUse = basicDataSource.getDriver();
+        String driverClassName = basicDataSource.getDriverClassName();
+        ClassLoader driverClassLoader = basicDataSource.getDriverClassLoader();
+        String url = basicDataSource.getUrl();
+
+        if (driverToUse == null) {
+            Class<?> driverFromCCL = null;
+            if (driverClassName != null) {
+                try {
+                    try {
+                        if (driverClassLoader == null) {
+                            driverFromCCL = Class.forName(driverClassName);
+                        } else {
+                            driverFromCCL = Class.forName(driverClassName, 
true, driverClassLoader);
+                        }
+                    } catch (final ClassNotFoundException cnfe) {
+                        driverFromCCL = 
Thread.currentThread().getContextClassLoader().loadClass(driverClassName);
+                    }
+                } catch (final Exception t) {
+                    final String message = "Cannot load JDBC driver class '" + 
driverClassName + "'";
+                    basicDataSource.log(message, t);
+                    throw new SQLException(message, t);
+                }
+            }
+
+            try {
+                if (driverFromCCL == null) {
+                    driverToUse = DriverManager.getDriver(url);
+                } else {
+                    // Usage of DriverManager is not possible, as it does not
+                    // respect the ContextClassLoader
+                    // N.B. This cast may cause ClassCastException which is
+                    // handled below
+                    driverToUse = (Driver) 
driverFromCCL.getConstructor().newInstance();
+                    if (!driverToUse.acceptsURL(url)) {
+                        throw new SQLException("No suitable driver", "08001");
+                    }
+                }
+            } catch (final Exception t) {
+                final String message = "Cannot create JDBC driver of class '"
+                        + (driverClassName != null ? driverClassName : "") + 
"' for connect URL '" + url + "'";
+                basicDataSource.log(message, t);
+                throw new SQLException(message, t);
+            }
+        }
+        return driverToUse;
+    }
+
+}

Reply via email to