Modified: 
tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java?rev=1833816&r1=1833815&r2=1833816&view=diff
==============================================================================
--- 
tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java
 (original)
+++ 
tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java
 Tue Jun 19 11:21:13 2018
@@ -17,6 +17,7 @@
 
 package org.apache.tomcat.dbcp.dbcp2.cpdsadapter;
 
+import java.sql.CallableStatement;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.SQLException;
@@ -28,67 +29,69 @@ import javax.sql.PooledConnection;
 import javax.sql.StatementEventListener;
 
 import org.apache.tomcat.dbcp.dbcp2.DelegatingConnection;
+import org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement;
+import org.apache.tomcat.dbcp.dbcp2.PStmtKey;
+import org.apache.tomcat.dbcp.dbcp2.PoolableCallableStatement;
 import org.apache.tomcat.dbcp.dbcp2.PoolablePreparedStatement;
+import org.apache.tomcat.dbcp.dbcp2.PoolingConnection.StatementType;
 import org.apache.tomcat.dbcp.pool2.KeyedObjectPool;
 import org.apache.tomcat.dbcp.pool2.KeyedPooledObjectFactory;
 import org.apache.tomcat.dbcp.pool2.PooledObject;
 import org.apache.tomcat.dbcp.pool2.impl.DefaultPooledObject;
 
 /**
- * Implementation of PooledConnection that is returned by
- * PooledConnectionDataSource.
+ * Implementation of PooledConnection that is returned by 
PooledConnectionDataSource.
  *
- * @author John D. McNally
  * @since 2.0
  */
 class PooledConnectionImpl
-        implements PooledConnection, KeyedPooledObjectFactory<PStmtKeyCPDS, 
PoolablePreparedStatement<PStmtKeyCPDS>> {
+        implements PooledConnection, KeyedPooledObjectFactory<PStmtKey, 
DelegatingPreparedStatement> {
 
-    private static final String CLOSED
-            = "Attempted to use PooledConnection after closed() was called.";
+    private static final String CLOSED = "Attempted to use PooledConnection 
after closed() was called.";
 
     /**
      * The JDBC database connection that represents the physical db connection.
      */
-    private Connection connection = null;
+    private Connection connection;
 
     /**
-     * A DelegatingConnection used to create a PoolablePreparedStatementStub
+     * A DelegatingConnection used to create a PoolablePreparedStatementStub.
      */
     private final DelegatingConnection<?> delegatingConnection;
 
     /**
      * The JDBC database logical connection.
      */
-    private Connection logicalConnection = null;
+    private Connection logicalConnection;
 
     /**
-     * ConnectionEventListeners
+     * ConnectionEventListeners.
      */
     private final Vector<ConnectionEventListener> eventListeners;
 
     /**
-     * StatementEventListeners
+     * StatementEventListeners.
      */
-    private final Vector<StatementEventListener> statementEventListeners =
-            new Vector<>();
+    private final Vector<StatementEventListener> statementEventListeners = new 
Vector<>();
 
     /**
-     * flag set to true, once close() is called.
+     * Flag set to true, once {@link #close()} is called.
      */
-    private boolean isClosed;
+    private boolean closed;
 
     /** My pool of {@link PreparedStatement}s. */
-    private KeyedObjectPool<PStmtKeyCPDS, 
PoolablePreparedStatement<PStmtKeyCPDS>> pstmtPool = null;
+    private KeyedObjectPool<PStmtKey, DelegatingPreparedStatement> pStmtPool;
 
     /**
-     * Controls access to the underlying connection
+     * Controls access to the underlying connection.
      */
-    private boolean accessToUnderlyingConnectionAllowed = false;
+    private boolean accessToUnderlyingConnectionAllowed;
 
     /**
-     * Wrap the real connection.
-     * @param connection the connection to be wrapped
+     * Wraps the real connection.
+     *
+     * @param connection
+     *            the connection to be wrapped.
      */
     PooledConnectionImpl(final Connection connection) {
         this.connection = connection;
@@ -98,12 +101,21 @@ class PooledConnectionImpl
             this.delegatingConnection = new DelegatingConnection<>(connection);
         }
         eventListeners = new Vector<>();
-        isClosed = false;
+        closed = false;
     }
 
-    public void setStatementPool(
-            final KeyedObjectPool<PStmtKeyCPDS, 
PoolablePreparedStatement<PStmtKeyCPDS>> statementPool) {
-        pstmtPool = statementPool;
+    /**
+     * My {@link KeyedPooledObjectFactory} method for activating {@link 
PreparedStatement}s.
+     *
+     * @param key
+     *            Ignored.
+     * @param pooledObject
+     *            Ignored.
+     */
+    @Override
+    public void activateObject(final PStmtKey key, final 
PooledObject<DelegatingPreparedStatement> pooledObject)
+            throws Exception {
+        pooledObject.getObject().activate();
     }
 
     /**
@@ -126,22 +138,31 @@ class PooledConnectionImpl
     /* JDBC_4_ANT_KEY_END */
 
     /**
-     * Closes the physical connection and marks this
-     * <code>PooledConnection</code> so that it may not be used
-     * to generate any more logical <code>Connection</code>s.
+     * Throws an SQLException, if isClosed is true
+     */
+    private void assertOpen() throws SQLException {
+        if (closed) {
+            throw new SQLException(CLOSED);
+        }
+    }
+
+    /**
+     * Closes the physical connection and marks this 
<code>PooledConnection</code> so that it may not be used to
+     * generate any more logical <code>Connection</code>s.
      *
-     * @throws SQLException if an error occurs or the connection is already 
closed
+     * @throws SQLException
+     *             Thrown when an error occurs or the connection is already 
closed.
      */
     @Override
     public void close() throws SQLException {
         assertOpen();
-        isClosed = true;
+        closed = true;
         try {
-            if (pstmtPool != null) {
+            if (pStmtPool != null) {
                 try {
-                    pstmtPool.close();
+                    pStmtPool.close();
                 } finally {
-                    pstmtPool = null;
+                    pStmtPool = null;
                 }
             }
         } catch (final RuntimeException e) {
@@ -158,11 +179,115 @@ class PooledConnectionImpl
     }
 
     /**
-     * Throws an SQLException, if isClosed is true
+     * Creates a {@link PooledConnectionImpl.PStmtKey} for the given arguments.
      */
-    private void assertOpen() throws SQLException {
-        if (isClosed) {
-            throw new SQLException(CLOSED);
+    protected PStmtKey createKey(final String sql) {
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull());
+    }
+
+    /**
+     * Creates a {@link PooledConnectionImpl.PStmtKey} for the given arguments.
+     */
+    protected PStmtKey createKey(final String sql, final int 
autoGeneratedKeys) {
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
autoGeneratedKeys);
+    }
+
+    /**
+     * Creates a {@link PooledConnectionImpl.PStmtKey} for the given arguments.
+     */
+    protected PStmtKey createKey(final String sql, final int columnIndexes[]) {
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
columnIndexes);
+    }
+
+    /**
+     * Creates a {@link PooledConnectionImpl.PStmtKey} for the given arguments.
+     */
+    protected PStmtKey createKey(final String sql, final int resultSetType, 
final int resultSetConcurrency) {
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
resultSetType, resultSetConcurrency);
+    }
+
+    /**
+     * Creates a {@link PooledConnectionImpl.PStmtKey} for the given arguments.
+     */
+    protected PStmtKey createKey(final String sql, final int resultSetType, 
final int resultSetConcurrency,
+            final int resultSetHoldability) {
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
resultSetType, resultSetConcurrency,
+                resultSetHoldability);
+    }
+
+    /**
+     * Creates a {@link PooledConnectionImpl.PStmtKey} for the given arguments.
+     *
+     * @since 2.4.0
+     */
+    protected PStmtKey createKey(final String sql, final int resultSetType, 
final int resultSetConcurrency,
+            final int resultSetHoldability, final StatementType statementType) 
{
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
resultSetType, resultSetConcurrency,
+                resultSetHoldability, statementType);
+    }
+
+    /**
+     * Creates a {@link PooledConnectionImpl.PStmtKey} for the given arguments.
+     *
+     * @since 2.4.0
+     */
+    protected PStmtKey createKey(final String sql, final int resultSetType, 
final int resultSetConcurrency,
+            final StatementType statementType) {
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
resultSetType, resultSetConcurrency, statementType);
+    }
+
+    /**
+     * Creates a {@link PooledConnectionImpl.PStmtKey} for the given arguments.
+     */
+    protected PStmtKey createKey(final String sql, final StatementType 
statementType) {
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
statementType);
+    }
+
+    /**
+     * Creates a {@link PooledConnectionImpl.PStmtKey} for the given arguments.
+     */
+    protected PStmtKey createKey(final String sql, final String columnNames[]) 
{
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
columnNames);
+    }
+
+    /**
+     * My {@link KeyedPooledObjectFactory} method for destroying {@link 
PreparedStatement}s.
+     *
+     * @param key
+     *            ignored
+     * @param pooledObject
+     *            the wrapped {@link PreparedStatement} to be destroyed.
+     */
+    @Override
+    public void destroyObject(final PStmtKey key, final 
PooledObject<DelegatingPreparedStatement> pooledObject)
+            throws Exception {
+        pooledObject.getObject().getInnermostDelegate().close();
+    }
+
+    /**
+     * Closes the physical connection and checks that the logical connection 
was closed as well.
+     */
+    @Override
+    protected void finalize() throws Throwable {
+        // Closing the Connection ensures that if anyone tries to use it,
+        // an error will occur.
+        try {
+            connection.close();
+        } catch (final Exception ignored) {
+            // ignore
+        }
+
+        // make sure the last connection is marked as closed
+        if (logicalConnection != null && !logicalConnection.isClosed()) {
+            throw new SQLException("PooledConnection was gc'ed, without its 
last Connection being closed.");
+        }
+    }
+
+    private String getCatalogOrNull() {
+        try {
+            return connection == null ? null : connection.getCatalog();
+        } catch (final SQLException e) {
+            return null;
         }
     }
 
@@ -170,7 +295,8 @@ class PooledConnectionImpl
      * Returns a JDBC connection.
      *
      * @return The database connection.
-     * @throws SQLException if the connection is not open or the previous 
logical connection is still open
+     * @throws SQLException
+     *             if the connection is not open or the previous logical 
connection is still open
      */
     @Override
     public Connection getConnection() throws SQLException {
@@ -179,54 +305,58 @@ class PooledConnectionImpl
         if (logicalConnection != null && !logicalConnection.isClosed()) {
             // should notify pool of error so the pooled connection can
             // be removed !FIXME!
-            throw new SQLException("PooledConnection was reused, without "
-                    + "its previous Connection being closed.");
+            throw new SQLException("PooledConnection was reused, without its 
previous Connection being closed.");
         }
 
         // the spec requires that this return a new Connection instance.
-        logicalConnection = new ConnectionImpl(
-                this, connection, isAccessToUnderlyingConnectionAllowed());
+        logicalConnection = new ConnectionImpl(this, connection, 
isAccessToUnderlyingConnectionAllowed());
         return logicalConnection;
     }
 
     /**
-     * {@inheritDoc}
+     * Returns the value of the accessToUnderlyingConnectionAllowed property.
+     *
+     * @return true if access to the underlying is allowed, false otherwise.
      */
-    @Override
-    public void removeConnectionEventListener(
-            final ConnectionEventListener listener) {
-        eventListeners.remove(listener);
-    }
-
-    /* JDBC_4_ANT_KEY_BEGIN */
-    @Override
-    public void removeStatementEventListener(final StatementEventListener 
listener) {
-        statementEventListeners.remove(listener);
+    public synchronized boolean isAccessToUnderlyingConnectionAllowed() {
+        return this.accessToUnderlyingConnectionAllowed;
     }
-    /* JDBC_4_ANT_KEY_END */
 
     /**
-     * Closes the physical connection and checks that the logical connection
-     * was closed as well.
+     * My {@link KeyedPooledObjectFactory} method for creating {@link 
PreparedStatement}s.
+     *
+     * @param key
+     *            The key for the {@link PreparedStatement} to be created.
      */
+    @SuppressWarnings("resource")
     @Override
-    protected void finalize() throws Throwable {
-        // Closing the Connection ensures that if anyone tries to use it,
-        // an error will occur.
-        try {
-            connection.close();
-        } catch (final Exception ignored) {
+    public PooledObject<DelegatingPreparedStatement> makeObject(final PStmtKey 
key) throws Exception {
+        if (null == key) {
+            throw new IllegalArgumentException("Prepared statement key is null 
or invalid.");
         }
-
-        // make sure the last connection is marked as closed
-        if (logicalConnection != null && !logicalConnection.isClosed()) {
-            throw new SQLException("PooledConnection was gc'ed, without"
-                    + "its last Connection being closed.");
+        if (key.getStmtType() == StatementType.PREPARED_STATEMENT) {
+            final PreparedStatement statement = (PreparedStatement) 
key.createStatement(connection);
+            @SuppressWarnings({"rawtypes", "unchecked" }) // Unable to find 
way to avoid this
+            final PoolablePreparedStatement pps = new 
PoolablePreparedStatement(statement, key, pStmtPool,
+                    delegatingConnection);
+            return new DefaultPooledObject<DelegatingPreparedStatement>(pps);
         }
+        final CallableStatement statement = (CallableStatement) 
key.createStatement(connection);
+        @SuppressWarnings("unchecked")
+        final PoolableCallableStatement pcs = new 
PoolableCallableStatement(statement, key, pStmtPool,
+                (DelegatingConnection<Connection>) delegatingConnection);
+        return new DefaultPooledObject<DelegatingPreparedStatement>(pcs);
     }
 
     /**
-     * sends a connectionClosed event.
+     * Normalizes the given SQL statement, producing a canonical form that is 
semantically equivalent to the original.
+     */
+    protected String normalizeSQL(final String sql) {
+        return sql.trim();
+    }
+
+    /**
+     * Sends a connectionClosed event.
      */
     void notifyListeners() {
         final ConnectionEvent event = new ConnectionEvent(this);
@@ -236,52 +366,132 @@ class PooledConnectionImpl
         }
     }
 
-    // -------------------------------------------------------------------
-    // The following code implements a PreparedStatement pool
+    /**
+     * My {@link KeyedPooledObjectFactory} method for passivating {@link 
PreparedStatement}s. Currently invokes
+     * {@link PreparedStatement#clearParameters}.
+     *
+     * @param key
+     *            ignored
+     * @param pooledObject
+     *            a wrapped {@link PreparedStatement}
+     */
+    @Override
+    public void passivateObject(final PStmtKey key, final 
PooledObject<DelegatingPreparedStatement> pooledObject)
+            throws Exception {
+        @SuppressWarnings("resource")
+        final DelegatingPreparedStatement dps = pooledObject.getObject();
+        dps.clearParameters();
+        dps.passivate();
+    }
 
     /**
-     * Create or obtain a {@link PreparedStatement} from my pool.
-     * @param sql the SQL statement
-     * @return a {@link PoolablePreparedStatement}
+     * Creates or obtains a {@link CallableStatement} from my pool.
+     *
+     * @param sql
+     *            an SQL statement that may contain one or more '?' parameter 
placeholders. Typically this statement is
+     *            specified using JDBC call escape syntax.
+     * @return a default <code>CallableStatement</code> object containing the 
pre-compiled SQL statement.
+     * @exception SQLException
+     *                Thrown if a database access error occurs or this method 
is called on a closed connection.
+     * @since 2.4.0
+     */
+    CallableStatement prepareCall(final String sql) throws SQLException {
+        if (pStmtPool == null) {
+            return connection.prepareCall(sql);
+        }
+        try {
+            return (CallableStatement) pStmtPool.borrowObject(createKey(sql, 
StatementType.CALLABLE_STATEMENT));
+        } catch (final RuntimeException e) {
+            throw e;
+        } catch (final Exception e) {
+            throw new SQLException("Borrow prepareCall from pool failed", e);
+        }
+    }
+
+    /**
+     * Creates or obtains a {@link CallableStatement} from my pool.
+     *
+     * @param sql
+     *            a <code>String</code> object that is the SQL statement to be 
sent to the database; may contain on or
+     *            more '?' parameters.
+     * @param resultSetType
+     *            a result set type; one of 
<code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *            <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or 
<code>ResultSet.TYPE_SCROLL_SENSITIVE</code>.
+     * @param resultSetConcurrency
+     *            a concurrency type; one of 
<code>ResultSet.CONCUR_READ_ONLY</code> or
+     *            <code>ResultSet.CONCUR_UPDATABLE</code>.
+     * @return a <code>CallableStatement</code> object containing the 
pre-compiled SQL statement that will produce
+     *         <code>ResultSet</code> objects with the given type and 
concurrency.
+     * @throws SQLException
+     *             Thrown if a database access error occurs, this method is 
called on a closed connection or the given
+     *             parameters are not <code>ResultSet</code> constants 
indicating type and concurrency.
+     * @since 2.4.0
      */
-    PreparedStatement prepareStatement(final String sql) throws SQLException {
-        if (pstmtPool == null) {
-            return connection.prepareStatement(sql);
+    CallableStatement prepareCall(final String sql, final int resultSetType, 
final int resultSetConcurrency)
+            throws SQLException {
+        if (pStmtPool == null) {
+            return connection.prepareCall(sql, resultSetType, 
resultSetConcurrency);
         }
         try {
-            return pstmtPool.borrowObject(createKey(sql));
+            return (CallableStatement) pStmtPool.borrowObject(
+                    createKey(sql, resultSetType, resultSetConcurrency, 
StatementType.CALLABLE_STATEMENT));
         } catch (final RuntimeException e) {
             throw e;
         } catch (final Exception e) {
-            throw new SQLException("Borrow prepareStatement from pool failed", 
e);
+            throw new SQLException("Borrow prepareCall from pool failed", e);
         }
     }
 
     /**
-     * Create or obtain a {@link PreparedStatement} from my pool.
-     * @param sql a <code>String</code> object that is the SQL statement to
-     *            be sent to the database; may contain one or more '?' IN
-     *            parameters
-     * @param resultSetType a result set type; one of
-     *         <code>ResultSet.TYPE_FORWARD_ONLY</code>,
-     *         <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
-     *         <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
-     * @param resultSetConcurrency a concurrency type; one of
-     *         <code>ResultSet.CONCUR_READ_ONLY</code> or
-     *         <code>ResultSet.CONCUR_UPDATABLE</code>
+     * Creates or obtains a {@link CallableStatement} from my pool.
      *
+     * @param sql
+     *            a <code>String</code> object that is the SQL statement to be 
sent to the database; may contain on or
+     *            more '?' parameters.
+     * @param resultSetType
+     *            one of the following <code>ResultSet</code> constants: 
<code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *            <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or 
<code>ResultSet.TYPE_SCROLL_SENSITIVE</code>.
+     * @param resultSetConcurrency
+     *            one of the following <code>ResultSet</code> constants: 
<code>ResultSet.CONCUR_READ_ONLY</code> or
+     *            <code>ResultSet.CONCUR_UPDATABLE</code>.
+     * @param resultSetHoldability
+     *            one of the following <code>ResultSet</code> constants: 
<code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code>
+     *            or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>.
+     * @return a new <code>CallableStatement</code> object, containing the 
pre-compiled SQL statement, that will
+     *         generate <code>ResultSet</code> objects with the given type, 
concurrency, and holdability.
+     * @throws SQLException
+     *             Thrown if a database access error occurs, this method is 
called on a closed connection or the given
+     *             parameters are not <code>ResultSet</code> constants 
indicating type, concurrency, and holdability.
+     * @since 2.4.0
+     */
+    CallableStatement prepareCall(final String sql, final int resultSetType, 
final int resultSetConcurrency,
+            final int resultSetHoldability) throws SQLException {
+        if (pStmtPool == null) {
+            return connection.prepareCall(sql, resultSetType, 
resultSetConcurrency, resultSetHoldability);
+        }
+        try {
+            return (CallableStatement) pStmtPool.borrowObject(createKey(sql, 
resultSetType, resultSetConcurrency,
+                    resultSetHoldability, StatementType.CALLABLE_STATEMENT));
+        } catch (final RuntimeException e) {
+            throw e;
+        } catch (final Exception e) {
+            throw new SQLException("Borrow prepareCall from pool failed", e);
+        }
+    }
+
+    /**
+     * Creates or obtains a {@link PreparedStatement} from my pool.
+     *
+     * @param sql
+     *            the SQL statement.
      * @return a {@link PoolablePreparedStatement}
-     * @see Connection#prepareStatement(String, int, int)
      */
-    PreparedStatement prepareStatement(final String sql, final int 
resultSetType,
-                                       final int resultSetConcurrency)
-            throws SQLException {
-        if (pstmtPool == null) {
-            return connection.prepareStatement(sql, resultSetType, 
resultSetConcurrency);
+    PreparedStatement prepareStatement(final String sql) throws SQLException {
+        if (pStmtPool == null) {
+            return connection.prepareStatement(sql);
         }
         try {
-            return pstmtPool.borrowObject(
-                    createKey(sql,resultSetType,resultSetConcurrency));
+            return pStmtPool.borrowObject(createKey(sql));
         } catch (final RuntimeException e) {
             throw e;
         } catch (final Exception e) {
@@ -290,23 +500,22 @@ class PooledConnectionImpl
     }
 
     /**
-     * Create or obtain a {@link PreparedStatement} from my pool.
-     * @param sql an SQL statement that may contain one or more '?' IN
-     *        parameter placeholders
-     * @param autoGeneratedKeys a flag indicating whether auto-generated keys
-     *        should be returned; one of
-     *        <code>Statement.RETURN_GENERATED_KEYS</code> or
-     *        <code>Statement.NO_GENERATED_KEYS</code>
+     * Creates or obtains a {@link PreparedStatement} from my pool.
+     *
+     * @param sql
+     *            an SQL statement that may contain one or more '?' IN 
parameter placeholders.
+     * @param autoGeneratedKeys
+     *            a flag indicating whether auto-generated keys should be 
returned; one of
+     *            <code>Statement.RETURN_GENERATED_KEYS</code> or 
<code>Statement.NO_GENERATED_KEYS</code>.
      * @return a {@link PoolablePreparedStatement}
      * @see Connection#prepareStatement(String, int)
      */
-    PreparedStatement prepareStatement(final String sql, final int 
autoGeneratedKeys)
-            throws SQLException {
-        if (pstmtPool == null) {
+    PreparedStatement prepareStatement(final String sql, final int 
autoGeneratedKeys) throws SQLException {
+        if (pStmtPool == null) {
             return connection.prepareStatement(sql, autoGeneratedKeys);
         }
         try {
-            return pstmtPool.borrowObject(createKey(sql,autoGeneratedKeys));
+            return pStmtPool.borrowObject(createKey(sql, autoGeneratedKeys));
         } catch (final RuntimeException e) {
             throw e;
         } catch (final Exception e) {
@@ -314,16 +523,12 @@ class PooledConnectionImpl
         }
     }
 
-    PreparedStatement prepareStatement(final String sql, final int 
resultSetType,
-            final int resultSetConcurrency, final int resultSetHoldability)
-    throws SQLException {
-        if (pstmtPool == null) {
-            return connection.prepareStatement(sql, resultSetType,
-                    resultSetConcurrency, resultSetHoldability);
+    PreparedStatement prepareStatement(final String sql, final int 
columnIndexes[]) throws SQLException {
+        if (pStmtPool == null) {
+            return connection.prepareStatement(sql, columnIndexes);
         }
         try {
-            return pstmtPool.borrowObject(createKey(sql, resultSetType,
-                    resultSetConcurrency, resultSetHoldability));
+            return pStmtPool.borrowObject(createKey(sql, columnIndexes));
         } catch (final RuntimeException e) {
             throw e;
         } catch (final Exception e) {
@@ -331,13 +536,29 @@ class PooledConnectionImpl
         }
     }
 
-    PreparedStatement prepareStatement(final String sql, final int 
columnIndexes[])
-    throws SQLException {
-        if (pstmtPool == null) {
-            return connection.prepareStatement(sql, columnIndexes);
+    /**
+     * Creates or obtains a {@link PreparedStatement} from my pool.
+     *
+     * @param sql
+     *            a <code>String</code> object that is the SQL statement to be 
sent to the database; may contain one or
+     *            more '?' IN parameters.
+     * @param resultSetType
+     *            a result set type; one of 
<code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *            <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or 
<code>ResultSet.TYPE_SCROLL_SENSITIVE</code>.
+     * @param resultSetConcurrency
+     *            a concurrency type; one of 
<code>ResultSet.CONCUR_READ_ONLY</code> or
+     *            <code>ResultSet.CONCUR_UPDATABLE</code>.
+     *
+     * @return a {@link PoolablePreparedStatement}.
+     * @see Connection#prepareStatement(String, int, int)
+     */
+    PreparedStatement prepareStatement(final String sql, final int 
resultSetType, final int resultSetConcurrency)
+            throws SQLException {
+        if (pStmtPool == null) {
+            return connection.prepareStatement(sql, resultSetType, 
resultSetConcurrency);
         }
         try {
-            return pstmtPool.borrowObject(createKey(sql, columnIndexes));
+            return pStmtPool.borrowObject(createKey(sql, resultSetType, 
resultSetConcurrency));
         } catch (final RuntimeException e) {
             throw e;
         } catch (final Exception e) {
@@ -345,13 +566,13 @@ class PooledConnectionImpl
         }
     }
 
-    PreparedStatement prepareStatement(final String sql, final String 
columnNames[])
-    throws SQLException {
-        if (pstmtPool == null) {
-            return connection.prepareStatement(sql, columnNames);
+    PreparedStatement prepareStatement(final String sql, final int 
resultSetType, final int resultSetConcurrency,
+            final int resultSetHoldability) throws SQLException {
+        if (pStmtPool == null) {
+            return connection.prepareStatement(sql, resultSetType, 
resultSetConcurrency, resultSetHoldability);
         }
         try {
-            return pstmtPool.borrowObject(createKey(sql, columnNames));
+            return pStmtPool.borrowObject(createKey(sql, resultSetType, 
resultSetConcurrency, resultSetHoldability));
         } catch (final RuntimeException e) {
             throw e;
         } catch (final Exception e) {
@@ -359,161 +580,60 @@ class PooledConnectionImpl
         }
     }
 
-    /**
-     * Create a {@link PooledConnectionImpl.PStmtKey} for the given arguments.
-     */
-    protected PStmtKeyCPDS createKey(final String sql, final int 
autoGeneratedKeys) {
-        return new PStmtKeyCPDS(normalizeSQL(sql), autoGeneratedKeys);
-    }
-
-    /**
-     * Create a {@link PooledConnectionImpl.PStmtKey} for the given arguments.
-     */
-    protected PStmtKeyCPDS createKey(final String sql, final int resultSetType,
-            final int resultSetConcurrency, final int resultSetHoldability) {
-        return new PStmtKeyCPDS(normalizeSQL(sql), resultSetType,
-                resultSetConcurrency, resultSetHoldability);
-    }
-
-    /**
-     * Create a {@link PooledConnectionImpl.PStmtKey} for the given arguments.
-     */
-    protected PStmtKeyCPDS createKey(final String sql, final int 
columnIndexes[]) {
-        return new PStmtKeyCPDS(normalizeSQL(sql), columnIndexes);
-    }
-
-    /**
-     * Create a {@link PooledConnectionImpl.PStmtKey} for the given arguments.
-     */
-    protected PStmtKeyCPDS createKey(final String sql, final String 
columnNames[]) {
-        return new PStmtKeyCPDS(normalizeSQL(sql), columnNames);
-    }
-
-    /**
-     * Create a {@link PooledConnectionImpl.PStmtKey} for the given arguments.
-     */
-    protected PStmtKeyCPDS createKey(final String sql, final int resultSetType,
-                               final int resultSetConcurrency) {
-        return new PStmtKeyCPDS(normalizeSQL(sql), resultSetType,
-                            resultSetConcurrency);
-    }
-
-    /**
-     * Create a {@link PooledConnectionImpl.PStmtKey} for the given arguments.
-     */
-    protected PStmtKeyCPDS createKey(final String sql) {
-        return new PStmtKeyCPDS(normalizeSQL(sql));
-    }
-
-    /**
-     * Normalize the given SQL statement, producing a
-     * canonical form that is semantically equivalent to the original.
-     */
-    protected String normalizeSQL(final String sql) {
-        return sql.trim();
-    }
-
-    /**
-     * My {@link KeyedPooledObjectFactory} method for creating
-     * {@link PreparedStatement}s.
-     * @param key the key for the {@link PreparedStatement} to be created
-     */
-    @Override
-    public PooledObject<PoolablePreparedStatement<PStmtKeyCPDS>> 
makeObject(final PStmtKeyCPDS key) throws Exception {
-        if (null == key) {
-            throw new IllegalArgumentException();
+    PreparedStatement prepareStatement(final String sql, final String 
columnNames[]) throws SQLException {
+        if (pStmtPool == null) {
+            return connection.prepareStatement(sql, columnNames);
         }
-        // _openPstmts++;
-        if (null == key.getResultSetType()
-                && null == key.getResultSetConcurrency()) {
-            if (null == key.getAutoGeneratedKeys()) {
-                return new DefaultPooledObject<>(new 
PoolablePreparedStatement<>(
-                        connection.prepareStatement(key.getSql()),
-                        key, pstmtPool, delegatingConnection));
-            }
-            return new DefaultPooledObject<>(new PoolablePreparedStatement<>(
-                            connection.prepareStatement(key.getSql(),
-                                    key.getAutoGeneratedKeys().intValue()),
-                            key, pstmtPool, delegatingConnection));
+        try {
+            return pStmtPool.borrowObject(createKey(sql, columnNames));
+        } catch (final RuntimeException e) {
+            throw e;
+        } catch (final Exception e) {
+            throw new SQLException("Borrow prepareStatement from pool failed", 
e);
         }
-        return new DefaultPooledObject<>(new PoolablePreparedStatement<>(
-                connection.prepareStatement(key.getSql(),
-                        key.getResultSetType().intValue(),
-                        key.getResultSetConcurrency().intValue()),
-                        key, pstmtPool, delegatingConnection));
-    }
-
-    /**
-     * My {@link KeyedPooledObjectFactory} method for destroying
-     * {@link PreparedStatement}s.
-     * @param key ignored
-     * @param p the wrapped {@link PreparedStatement} to be destroyed.
-     */
-    @Override
-    public void destroyObject(final PStmtKeyCPDS key,
-            final PooledObject<PoolablePreparedStatement<PStmtKeyCPDS>> p)
-            throws Exception {
-        p.getObject().getInnermostDelegate().close();
     }
 
     /**
-     * My {@link KeyedPooledObjectFactory} method for validating
-     * {@link PreparedStatement}s.
-     * @param key ignored
-     * @param p ignored
-     * @return {@code true}
+     * {@inheritDoc}
      */
     @Override
-    public boolean validateObject(final PStmtKeyCPDS key,
-            final PooledObject<PoolablePreparedStatement<PStmtKeyCPDS>> p) {
-        return true;
+    public void removeConnectionEventListener(final ConnectionEventListener 
listener) {
+        eventListeners.remove(listener);
     }
 
-    /**
-     * My {@link KeyedPooledObjectFactory} method for activating
-     * {@link PreparedStatement}s.
-     * @param key ignored
-     * @param p ignored
-     */
+    /* JDBC_4_ANT_KEY_BEGIN */
     @Override
-    public void activateObject(final PStmtKeyCPDS key,
-            final PooledObject<PoolablePreparedStatement<PStmtKeyCPDS>> p)
-            throws Exception {
-        p.getObject().activate();
+    public void removeStatementEventListener(final StatementEventListener 
listener) {
+        statementEventListeners.remove(listener);
     }
+    /* JDBC_4_ANT_KEY_END */
 
     /**
-     * My {@link KeyedPooledObjectFactory} method for passivating
-     * {@link PreparedStatement}s.  Currently invokes {@link 
PreparedStatement#clearParameters}.
-     * @param key ignored
-     * @param p a wrapped {@link PreparedStatement}
+     * Sets the value of the accessToUnderlyingConnectionAllowed property. It 
controls if the PoolGuard allows access to
+     * the underlying connection. (Default: false.)
+     *
+     * @param allow
+     *            Access to the underlying connection is granted when true.
      */
-    @Override
-    public void passivateObject(final PStmtKeyCPDS key,
-            final PooledObject<PoolablePreparedStatement<PStmtKeyCPDS>> p)
-            throws Exception {
-        final PoolablePreparedStatement<PStmtKeyCPDS> ppss = p.getObject();
-        ppss.clearParameters();
-        ppss.passivate();
+    public synchronized void setAccessToUnderlyingConnectionAllowed(final 
boolean allow) {
+        this.accessToUnderlyingConnectionAllowed = allow;
     }
 
-    /**
-     * Returns the value of the accessToUnderlyingConnectionAllowed property.
-     *
-     * @return true if access to the underlying is allowed, false otherwise.
-     */
-    public synchronized boolean isAccessToUnderlyingConnectionAllowed() {
-        return this.accessToUnderlyingConnectionAllowed;
+    public void setStatementPool(final KeyedObjectPool<PStmtKey, 
DelegatingPreparedStatement> statementPool) {
+        pStmtPool = statementPool;
     }
 
     /**
-     * Sets the value of the accessToUnderlyingConnectionAllowed property.
-     * It controls if the PoolGuard allows access to the underlying connection.
-     * (Default: false)
+     * My {@link KeyedPooledObjectFactory} method for validating {@link 
PreparedStatement}s.
      *
-     * @param allow Access to the underlying connection is granted when true.
+     * @param key
+     *            Ignored.
+     * @param pooledObject
+     *            Ignored.
+     * @return {@code true}
      */
-    public synchronized void setAccessToUnderlyingConnectionAllowed(final 
boolean allow) {
-        this.accessToUnderlyingConnectionAllowed = allow;
+    @Override
+    public boolean validateObject(final PStmtKey key, final 
PooledObject<DelegatingPreparedStatement> pooledObject) {
+        return true;
     }
 }

Modified: 
tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/CPDSConnectionFactory.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/CPDSConnectionFactory.java?rev=1833816&r1=1833815&r2=1833816&view=diff
==============================================================================
--- 
tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/CPDSConnectionFactory.java
 (original)
+++ 
tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/CPDSConnectionFactory.java
 Tue Jun 19 11:21:13 2018
@@ -40,67 +40,86 @@ import org.apache.tomcat.dbcp.pool2.impl
  * A {@link PooledObjectFactory} that creates
  * {@link org.apache.tomcat.dbcp.dbcp2.PoolableConnection PoolableConnection}s.
  *
- * @author John D. McNally
  * @since 2.0
  */
 class CPDSConnectionFactory
-        implements PooledObjectFactory<PooledConnectionAndInfo>,
-        ConnectionEventListener, PooledConnectionManager {
+        implements PooledObjectFactory<PooledConnectionAndInfo>, 
ConnectionEventListener, PooledConnectionManager {
 
-    private static final String NO_KEY_MESSAGE
-            = "close() was called on a Connection, but "
-            + "I have no record of the underlying PooledConnection.";
-
-    private final ConnectionPoolDataSource _cpds;
-    private final String _validationQuery;
-    private final int _validationQueryTimeout;
-    private final boolean _rollbackAfterValidation;
-    private ObjectPool<PooledConnectionAndInfo> _pool;
-    private final String _username;
-    private String _password = null;
-    private long maxConnLifetimeMillis = -1;
+    private static final String NO_KEY_MESSAGE = "close() was called on a 
Connection, but I have no record of the underlying PooledConnection.";
 
+    private final ConnectionPoolDataSource cpds;
+    private final String validationQuery;
+    private final int validationQueryTimeoutSeconds;
+    private final boolean rollbackAfterValidation;
+    private ObjectPool<PooledConnectionAndInfo> pool;
+    private final String userName;
+    private char[] userPassword;
+    private long maxConnLifetimeMillis = -1;
 
     /**
-     * Map of PooledConnections for which close events are ignored.
-     * Connections are muted when they are being validated.
+     * Map of PooledConnections for which close events are ignored. 
Connections are muted when they are being validated.
      */
-    private final Set<PooledConnection> validatingSet =
-            Collections.newSetFromMap(new 
ConcurrentHashMap<PooledConnection,Boolean>());
+    private final Set<PooledConnection> validatingSet = Collections
+            .newSetFromMap(new ConcurrentHashMap<PooledConnection, Boolean>());
 
     /**
      * Map of PooledConnectionAndInfo instances
      */
-    private final Map<PooledConnection, PooledConnectionAndInfo> pcMap =
-        new ConcurrentHashMap<>();
+    private final Map<PooledConnection, PooledConnectionAndInfo> pcMap = new 
ConcurrentHashMap<>();
 
     /**
-     * Create a new {@code PoolableConnectionFactory}.
+     * Creates a new {@code PoolableConnectionFactory}.
      *
-     * @param cpds the ConnectionPoolDataSource from which to obtain
-     * PooledConnection's
-     * @param validationQuery a query to use to {@link #validateObject
-     * validate} {@link Connection}s. Should return at least one row.
-     * May be {@code null} in which case {@link Connection#isValid(int)} will
-     * be used to validate connections.
-     * @param validationQueryTimeout Timeout in seconds before validation fails
-     * @param rollbackAfterValidation whether a rollback should be issued
-     * after {@link #validateObject validating} {@link Connection}s.
-     * @param username
-     * @param password
-     */
-    public CPDSConnectionFactory(final ConnectionPoolDataSource cpds,
-                                 final String validationQuery,
-                                 final int validationQueryTimeout,
-                                 final boolean rollbackAfterValidation,
-                                 final String username,
-                                 final String password) {
-        _cpds = cpds;
-        _validationQuery = validationQuery;
-        _validationQueryTimeout = validationQueryTimeout;
-        _username = username;
-        _password = password;
-        _rollbackAfterValidation = rollbackAfterValidation;
+     * @param cpds
+     *            the ConnectionPoolDataSource from which to obtain 
PooledConnection's
+     * @param validationQuery
+     *            a query to use to {@link #validateObject validate} {@link 
Connection}s. Should return at least one
+     *            row. May be {@code null} in which case {@link 
Connection#isValid(int)} will be used to validate
+     *            connections.
+     * @param validationQueryTimeoutSeconds
+     *            Timeout in seconds before validation fails
+     * @param rollbackAfterValidation
+     *            whether a rollback should be issued after {@link 
#validateObject validating} {@link Connection}s.
+     * @param userName
+     *            The user name to use to create connections
+     * @param userPassword
+     *            The password to use to create connections
+     * @since 2.4.0
+     */
+    public CPDSConnectionFactory(final ConnectionPoolDataSource cpds, final 
String validationQuery,
+            final int validationQueryTimeoutSeconds, final boolean 
rollbackAfterValidation, final String userName,
+            final char[] userPassword) {
+        this.cpds = cpds;
+        this.validationQuery = validationQuery;
+        this.validationQueryTimeoutSeconds = validationQueryTimeoutSeconds;
+        this.userName = userName;
+        this.userPassword = userPassword;
+        this.rollbackAfterValidation = rollbackAfterValidation;
+    }
+
+    /**
+     * Creates a new {@code PoolableConnectionFactory}.
+     *
+     * @param cpds
+     *            the ConnectionPoolDataSource from which to obtain 
PooledConnection's
+     * @param validationQuery
+     *            a query to use to {@link #validateObject validate} {@link 
Connection}s. Should return at least one
+     *            row. May be {@code null} in which case {@link 
Connection#isValid(int)} will be used to validate
+     *            connections.
+     * @param validationQueryTimeoutSeconds
+     *            Timeout in seconds before validation fails
+     * @param rollbackAfterValidation
+     *            whether a rollback should be issued after {@link 
#validateObject validating} {@link Connection}s.
+     * @param userName
+     *            The user name to use to create connections
+     * @param userPassword
+     *            The password to use to create connections
+     */
+    public CPDSConnectionFactory(final ConnectionPoolDataSource cpds, final 
String validationQuery,
+            final int validationQueryTimeoutSeconds, final boolean 
rollbackAfterValidation, final String userName,
+            final String userPassword) {
+        this(cpds, validationQuery, validationQueryTimeoutSeconds, 
rollbackAfterValidation, userName,
+                Utils.toCharArray(userPassword));
     }
 
     /**
@@ -109,16 +128,16 @@ class CPDSConnectionFactory
      * @return ObjectPool managing pooled connections
      */
     public ObjectPool<PooledConnectionAndInfo> getPool() {
-        return _pool;
+        return pool;
     }
 
     /**
      *
-     * @param pool the {@link ObjectPool} in which to pool those {@link
-     * Connection}s
+     * @param pool
+     *            the {@link ObjectPool} in which to pool those {@link 
Connection}s
      */
     public void setPool(final ObjectPool<PooledConnectionAndInfo> pool) {
-        this._pool = pool;
+        this.pool = pool;
     }
 
     @Override
@@ -126,10 +145,10 @@ class CPDSConnectionFactory
         PooledConnectionAndInfo pci;
         try {
             PooledConnection pc = null;
-            if (_username == null) {
-                pc = _cpds.getPooledConnection();
+            if (userName == null) {
+                pc = cpds.getPooledConnection();
             } else {
-                pc = _cpds.getPooledConnection(_username, _password);
+                pc = cpds.getPooledConnection(userName, 
Utils.toString(userPassword));
             }
 
             if (pc == null) {
@@ -139,7 +158,7 @@ class CPDSConnectionFactory
             // should we add this object as a listener or the pool.
             // consider the validateObject method in decision
             pc.addConnectionEventListener(this);
-            pci = new PooledConnectionAndInfo(pc, _username, _password);
+            pci = new PooledConnectionAndInfo(pc, userName, userPassword);
             pcMap.put(pc, pci);
         } catch (final SQLException e) {
             throw new RuntimeException(e.getMessage());
@@ -155,7 +174,7 @@ class CPDSConnectionFactory
         doDestroyObject(p.getObject());
     }
 
-    private void doDestroyObject(final PooledConnectionAndInfo pci) throws 
Exception{
+    private void doDestroyObject(final PooledConnectionAndInfo pci) throws 
Exception {
         final PooledConnection pc = pci.getPooledConnection();
         pc.removeConnectionEventListener(this);
         pcMap.remove(pc);
@@ -173,14 +192,14 @@ class CPDSConnectionFactory
         final PooledConnection pconn = p.getObject().getPooledConnection();
         Connection conn = null;
         validatingSet.add(pconn);
-        if (null == _validationQuery) {
-            int timeout = _validationQueryTimeout;
-            if (timeout < 0) {
-                timeout = 0;
+        if (null == validationQuery) {
+            int timeoutSeconds = validationQueryTimeoutSeconds;
+            if (timeoutSeconds < 0) {
+                timeoutSeconds = 0;
             }
             try {
                 conn = pconn.getConnection();
-                valid = conn.isValid(timeout);
+                valid = conn.isValid(timeoutSeconds);
             } catch (final SQLException e) {
                 valid = false;
             } finally {
@@ -198,13 +217,13 @@ class CPDSConnectionFactory
             try {
                 conn = pconn.getConnection();
                 stmt = conn.createStatement();
-                rset = stmt.executeQuery(_validationQuery);
+                rset = stmt.executeQuery(validationQuery);
                 if (rset.next()) {
                     valid = true;
                 } else {
                     valid = false;
                 }
-                if (_rollbackAfterValidation) {
+                if (rollbackAfterValidation) {
                     conn.rollback();
                 }
             } catch (final Exception e) {
@@ -220,14 +239,12 @@ class CPDSConnectionFactory
     }
 
     @Override
-    public void passivateObject(final PooledObject<PooledConnectionAndInfo> p)
-            throws Exception {
+    public void passivateObject(final PooledObject<PooledConnectionAndInfo> p) 
throws Exception {
         validateLifetime(p);
     }
 
     @Override
-    public void activateObject(final PooledObject<PooledConnectionAndInfo> p)
-            throws Exception {
+    public void activateObject(final PooledObject<PooledConnectionAndInfo> p) 
throws Exception {
         validateLifetime(p);
     }
 
@@ -236,10 +253,9 @@ class CPDSConnectionFactory
     // ***********************************************************************
 
     /**
-     * This will be called if the Connection returned by the getConnection
-     * method came from a PooledConnection, and the user calls the close()
-     * method of this connection object. What we need to do here is to
-     * release this PooledConnection from our pool...
+     * This will be called if the Connection returned by the getConnection 
method came from a PooledConnection, and the
+     * user calls the close() method of this connection object. What we need 
to do here is to release this
+     * PooledConnection from our pool...
      */
     @Override
     public void connectionClosed(final ConnectionEvent event) {
@@ -253,16 +269,14 @@ class CPDSConnectionFactory
             }
 
             try {
-                _pool.returnObject(pci);
+                pool.returnObject(pci);
             } catch (final Exception e) {
-                System.err.println("CLOSING DOWN CONNECTION AS IT COULD "
-                        + "NOT BE RETURNED TO THE POOL");
+                System.err.println("CLOSING DOWN CONNECTION AS IT COULD " + 
"NOT BE RETURNED TO THE POOL");
                 pc.removeConnectionEventListener(this);
                 try {
                     doDestroyObject(pci);
                 } catch (final Exception e2) {
-                    System.err.println("EXCEPTION WHILE DESTROYING OBJECT "
-                            + pci);
+                    System.err.println("EXCEPTION WHILE DESTROYING OBJECT " + 
pci);
                     e2.printStackTrace();
                 }
             }
@@ -270,16 +284,13 @@ class CPDSConnectionFactory
     }
 
     /**
-     * If a fatal error occurs, close the underlying physical connection so as
-     * not to be returned in the future
+     * If a fatal error occurs, close the underlying physical connection so as 
not to be returned in the future
      */
     @Override
     public void connectionErrorOccurred(final ConnectionEvent event) {
-        final PooledConnection pc = (PooledConnection)event.getSource();
+        final PooledConnection pc = (PooledConnection) event.getSource();
         if (null != event.getSQLException()) {
-            System.err.println(
-                    "CLOSING DOWN CONNECTION DUE TO INTERNAL ERROR ("
-                    + event.getSQLException() + ")");
+            System.err.println("CLOSING DOWN CONNECTION DUE TO INTERNAL ERROR 
(" + event.getSQLException() + ")");
         }
         pc.removeConnectionEventListener(this);
 
@@ -288,7 +299,7 @@ class CPDSConnectionFactory
             throw new IllegalStateException(NO_KEY_MESSAGE);
         }
         try {
-            _pool.invalidateObject(pci);
+            pool.invalidateObject(pci);
         } catch (final Exception e) {
             System.err.println("EXCEPTION WHILE DESTROYING OBJECT " + pci);
             e.printStackTrace();
@@ -300,10 +311,9 @@ class CPDSConnectionFactory
     // ***********************************************************************
 
     /**
-     * Invalidates the PooledConnection in the pool.  The CPDSConnectionFactory
-     * closes the connection and pool counters are updated appropriately.
-     * Also closes the pool.  This ensures that all idle connections are closed
-     * and connections that are checked out are closed on return.
+     * Invalidates the PooledConnection in the pool. The CPDSConnectionFactory 
closes the connection and pool counters
+     * are updated appropriately. Also closes the pool. This ensures that all 
idle connections are closed and
+     * connections that are checked out are closed on return.
      */
     @Override
     public void invalidate(final PooledConnection pc) throws SQLException {
@@ -312,8 +322,8 @@ class CPDSConnectionFactory
             throw new IllegalStateException(NO_KEY_MESSAGE);
         }
         try {
-            _pool.invalidateObject(pci);  // Destroy instance and update pool 
counters
-            _pool.close();  // Clear any other instances in this pool and kill 
others as they come back
+            pool.invalidateObject(pci); // Destroy instance and update pool 
counters
+            pool.close(); // Clear any other instances in this pool and kill 
others as they come back
         } catch (final Exception ex) {
             throw new SQLException("Error invalidating connection", ex);
         }
@@ -322,49 +332,58 @@ class CPDSConnectionFactory
     /**
      * Sets the database password used when creating new connections.
      *
-     * @param password new password
+     * @param userPassword
+     *            new password
+     */
+    public synchronized void setPassword(final char[] userPassword) {
+        this.userPassword = userPassword;
+    }
+
+    /**
+     * Sets the database password used when creating new connections.
+     *
+     * @param userPassword
+     *            new password
      */
     @Override
-    public synchronized void setPassword(final String password) {
-        _password = password;
+    public synchronized void setPassword(final String userPassword) {
+        this.userPassword = Utils.toCharArray(userPassword);
     }
 
     /**
-     * Sets the maximum lifetime in milliseconds of a connection after which 
the
-     * connection will always fail activation, passivation and validation. A
-     * value of zero or less indicates an infinite lifetime. The default value
-     * is -1.
+     * Sets the maximum lifetime in milliseconds of a connection after which 
the connection will always fail activation,
+     * passivation and validation.
+     *
+     * @param maxConnLifetimeMillis
+     *            A value of zero or less indicates an infinite lifetime. The 
default value is -1.
      */
     public void setMaxConnLifetimeMillis(final long maxConnLifetimeMillis) {
         this.maxConnLifetimeMillis = maxConnLifetimeMillis;
     }
 
     /**
-     * Verifies that the username matches the user whose connections are being 
managed by this
-     * factory and closes the pool if this is the case; otherwise does nothing.
+     * Verifies that the user name matches the user whose connections are 
being managed by this factory and closes the
+     * pool if this is the case; otherwise does nothing.
      */
     @Override
-    public void closePool(final String username) throws SQLException {
+    public void closePool(final String userName) throws SQLException {
         synchronized (this) {
-            if (username == null || !username.equals(_username)) {
+            if (userName == null || !userName.equals(this.userName)) {
                 return;
             }
         }
         try {
-            _pool.close();
+            pool.close();
         } catch (final Exception ex) {
             throw new SQLException("Error closing connection pool", ex);
         }
     }
 
-    private void validateLifetime(final PooledObject<PooledConnectionAndInfo> 
p)
-            throws Exception {
+    private void validateLifetime(final PooledObject<PooledConnectionAndInfo> 
p) throws Exception {
         if (maxConnLifetimeMillis > 0) {
             final long lifetime = System.currentTimeMillis() - 
p.getCreateTime();
             if (lifetime > maxConnLifetimeMillis) {
-                throw new Exception(Utils.getMessage(
-                        "connectionFactory.lifetimeExceeded",
-                        Long.valueOf(lifetime),
+                throw new 
Exception(Utils.getMessage("connectionFactory.lifetimeExceeded", 
Long.valueOf(lifetime),
                         Long.valueOf(maxConnLifetimeMillis)));
             }
         }



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to