Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java?rev=1833794&r1=1833793&r2=1833794&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java
 (original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java
 Tue Jun 19 09:04:08 2018
@@ -19,8 +19,10 @@ package org.apache.tomcat.dbcp.dbcp2.dat
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.ObjectInputStream;
+import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Properties;
@@ -32,22 +34,22 @@ import javax.naming.RefAddr;
 import javax.naming.Reference;
 import javax.naming.spi.ObjectFactory;
 
+import org.apache.tomcat.dbcp.dbcp2.ListException;
+
 /**
- * A JNDI ObjectFactory which creates <code>SharedPoolDataSource</code>s
- * or <code>PerUserPoolDataSource</code>s
+ * A JNDI ObjectFactory which creates <code>SharedPoolDataSource</code>s or 
<code>PerUserPoolDataSource</code>s
  *
  * @since 2.0
  */
 abstract class InstanceKeyDataSourceFactory implements ObjectFactory {
 
-    private static final Map<String, InstanceKeyDataSource> instanceMap =
-            new ConcurrentHashMap<>();
+    private static final Map<String, InstanceKeyDataSource> instanceMap = new 
ConcurrentHashMap<>();
 
     static synchronized String registerNewInstance(final InstanceKeyDataSource 
ds) {
         int max = 0;
-        final Iterator<String> i = instanceMap.keySet().iterator();
-        while (i.hasNext()) {
-            final String s = i.next();
+        final Iterator<String> iterator = instanceMap.keySet().iterator();
+        while (iterator.hasNext()) {
+            final String s = iterator.next();
             if (s != null) {
                 try {
                     max = Math.max(max, Integer.parseInt(s));
@@ -57,8 +59,8 @@ abstract class InstanceKeyDataSourceFact
             }
         }
         final String instanceKey = String.valueOf(max + 1);
-        // put a placeholder here for now, so other instances will not
-        // take our key.  we will replace with a pool when ready.
+        // Put a placeholder here for now, so other instances will not
+        // take our key. We will replace with a pool when ready.
         instanceMap.put(instanceKey, ds);
         return instanceKey;
     }
@@ -70,57 +72,70 @@ abstract class InstanceKeyDataSourceFact
     }
 
     /**
-     * Close all pools associated with this class.
-     * @throws Exception Close exception
+     * Closes all pools associated with this class.
+     *
+     * @throws Exception
+     *             a {@link ListException} containing all exceptions thrown by 
{@link InstanceKeyDataSource#close()}
+     * @see InstanceKeyDataSource#close()
+     * @see ListException
+     * @since 2.4.0 throws a {@link ListException} instead of, in 2.3.0 and 
before, the first exception thrown by
+     *        {@link InstanceKeyDataSource#close()}.
      */
     public static void closeAll() throws Exception {
-        //Get iterator to loop over all instances of this datasource.
-        final Iterator<Entry<String,InstanceKeyDataSource>> instanceIterator =
-            instanceMap.entrySet().iterator();
+        // Get iterator to loop over all instances of this data source.
+        final List<Throwable> exceptionList = new 
ArrayList<>(instanceMap.size());
+        final Iterator<Entry<String, InstanceKeyDataSource>> instanceIterator 
= instanceMap.entrySet().iterator();
         while (instanceIterator.hasNext()) {
-            instanceIterator.next().getValue().close();
+            // Bullet-proof to avoid anything else but problems from 
InstanceKeyDataSource#close().
+            final Entry<String, InstanceKeyDataSource> next = 
instanceIterator.next();
+            if (next != null) {
+                @SuppressWarnings("resource")
+                final InstanceKeyDataSource value = next.getValue();
+                if (value != null) {
+                    try {
+                        value.close();
+                    } catch (final Exception e) {
+                        exceptionList.add(e);
+                    }
+                }
+            }
         }
         instanceMap.clear();
+        if (!exceptionList.isEmpty()) {
+            throw new ListException("Could not close all InstanceKeyDataSource 
instances.", exceptionList);
+        }
     }
 
-
     /**
-     * Implements ObjectFactory to create an instance of SharedPoolDataSource
-     * or PerUserPoolDataSource.
+     * Implements ObjectFactory to create an instance of SharedPoolDataSource 
or PerUserPoolDataSource
      */
     @Override
-    public Object getObjectInstance(final Object refObj, final Name name,
-                                    final Context context, final 
Hashtable<?,?> env)
-        throws IOException, ClassNotFoundException {
+    public Object getObjectInstance(final Object refObj, final Name name, 
final Context context,
+            final Hashtable<?, ?> env) throws IOException, 
ClassNotFoundException {
         // The spec says to return null if we can't create an instance
         // of the reference
         Object obj = null;
         if (refObj instanceof Reference) {
             final Reference ref = (Reference) refObj;
             if (isCorrectClass(ref.getClassName())) {
-                final RefAddr ra = ref.get("instanceKey");
-                if (ra != null && ra.getContent() != null) {
+                final RefAddr refAddr = ref.get("instanceKey");
+                if (refAddr != null && refAddr.getContent() != null) {
                     // object was bound to jndi via Referenceable api.
-                    obj = instanceMap.get(ra.getContent());
-                }
-                else
-                {
-                    // tomcat jndi creates a Reference out of server.xml
+                    obj = instanceMap.get(refAddr.getContent());
+                } else {
+                    // Tomcat JNDI creates a Reference out of server.xml
                     // <ResourceParam> configuration and passes it to an
                     // instance of the factory given in server.xml.
                     String key = null;
-                    if (name != null)
-                    {
+                    if (name != null) {
                         key = name.toString();
                         obj = instanceMap.get(key);
                     }
-                    if (obj == null)
-                    {
+                    if (obj == null) {
                         final InstanceKeyDataSource ds = getNewInstance(ref);
                         setCommonProperties(ref, ds);
                         obj = ds;
-                        if (key != null)
-                        {
+                        if (key != null) {
                             instanceMap.put(key, ds);
                         }
                     }
@@ -130,197 +145,161 @@ abstract class InstanceKeyDataSourceFact
         return obj;
     }
 
-    private void setCommonProperties(final Reference ref,
-                                     final InstanceKeyDataSource ikds)
-        throws IOException, ClassNotFoundException {
+    private void setCommonProperties(final Reference ref, final 
InstanceKeyDataSource ikds)
+            throws IOException, ClassNotFoundException {
 
-        RefAddr ra = ref.get("dataSourceName");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDataSourceName(ra.getContent().toString());
+        RefAddr refAddr = ref.get("dataSourceName");
+        if (refAddr != null && refAddr.getContent() != null) {
+            ikds.setDataSourceName(refAddr.getContent().toString());
         }
 
-        ra = ref.get("description");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDescription(ra.getContent().toString());
+        refAddr = ref.get("description");
+        if (refAddr != null && refAddr.getContent() != null) {
+            ikds.setDescription(refAddr.getContent().toString());
         }
 
-        ra = ref.get("jndiEnvironment");
-        if (ra != null  && ra.getContent() != null) {
-            final byte[] serialized = (byte[]) ra.getContent();
+        refAddr = ref.get("jndiEnvironment");
+        if (refAddr != null && refAddr.getContent() != null) {
+            final byte[] serialized = (byte[]) refAddr.getContent();
             ikds.setJndiEnvironment((Properties) deserialize(serialized));
         }
 
-        ra = ref.get("loginTimeout");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setLoginTimeout(
-                Integer.parseInt(ra.getContent().toString()));
+        refAddr = ref.get("loginTimeout");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setLoginTimeout(Integer.parseInt(refAddr.getContent().toString()));
         }
 
         // Pool properties
-        ra = ref.get("blockWhenExhausted");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDefaultBlockWhenExhausted(Boolean.valueOf(
-                ra.getContent().toString()).booleanValue());
+        refAddr = ref.get("blockWhenExhausted");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setDefaultBlockWhenExhausted(Boolean.valueOf(refAddr.getContent().toString()).booleanValue());
         }
 
-        ra = ref.get("evictionPolicyClassName");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDefaultEvictionPolicyClassName(ra.getContent().toString());
+        refAddr = ref.get("evictionPolicyClassName");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setDefaultEvictionPolicyClassName(refAddr.getContent().toString());
         }
 
         // Pool properties
-        ra = ref.get("lifo");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDefaultLifo(Boolean.valueOf(
-                ra.getContent().toString()).booleanValue());
+        refAddr = ref.get("lifo");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setDefaultLifo(Boolean.valueOf(refAddr.getContent().toString()).booleanValue());
         }
 
-        ra = ref.get("maxIdlePerKey");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDefaultMaxIdle(
-                Integer.parseInt(ra.getContent().toString()));
+        refAddr = ref.get("maxIdlePerKey");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setDefaultMaxIdle(Integer.parseInt(refAddr.getContent().toString()));
         }
 
-        ra = ref.get("maxTotalPerKey");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDefaultMaxTotal(
-                Integer.parseInt(ra.getContent().toString()));
+        refAddr = ref.get("maxTotalPerKey");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setDefaultMaxTotal(Integer.parseInt(refAddr.getContent().toString()));
         }
 
-        ra = ref.get("maxWaitMillis");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDefaultMaxWaitMillis(
-                Long.parseLong(ra.getContent().toString()));
+        refAddr = ref.get("maxWaitMillis");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setDefaultMaxWaitMillis(Long.parseLong(refAddr.getContent().toString()));
         }
 
-        ra = ref.get("minEvictableIdleTimeMillis");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDefaultMinEvictableIdleTimeMillis(
-                Long.parseLong(ra.getContent().toString()));
+        refAddr = ref.get("minEvictableIdleTimeMillis");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setDefaultMinEvictableIdleTimeMillis(Long.parseLong(refAddr.getContent().toString()));
         }
 
-        ra = ref.get("minIdlePerKey");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDefaultMinIdle(
-                Integer.parseInt(ra.getContent().toString()));
+        refAddr = ref.get("minIdlePerKey");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setDefaultMinIdle(Integer.parseInt(refAddr.getContent().toString()));
         }
 
-        ra = ref.get("numTestsPerEvictionRun");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDefaultNumTestsPerEvictionRun(
-                Integer.parseInt(ra.getContent().toString()));
+        refAddr = ref.get("numTestsPerEvictionRun");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setDefaultNumTestsPerEvictionRun(Integer.parseInt(refAddr.getContent().toString()));
         }
 
-        ra = ref.get("softMinEvictableIdleTimeMillis");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDefaultSoftMinEvictableIdleTimeMillis(
-                Long.parseLong(ra.getContent().toString()));
+        refAddr = ref.get("softMinEvictableIdleTimeMillis");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setDefaultSoftMinEvictableIdleTimeMillis(Long.parseLong(refAddr.getContent().toString()));
         }
 
-        ra = ref.get("testOnCreate");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDefaultTestOnCreate(Boolean.valueOf(
-                ra.getContent().toString()).booleanValue());
+        refAddr = ref.get("testOnCreate");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setDefaultTestOnCreate(Boolean.valueOf(refAddr.getContent().toString()).booleanValue());
         }
 
-        ra = ref.get("testOnBorrow");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDefaultTestOnBorrow(Boolean.valueOf(
-                ra.getContent().toString()).booleanValue());
+        refAddr = ref.get("testOnBorrow");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setDefaultTestOnBorrow(Boolean.valueOf(refAddr.getContent().toString()).booleanValue());
         }
 
-        ra = ref.get("testOnReturn");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDefaultTestOnReturn(Boolean.valueOf(
-                ra.getContent().toString()).booleanValue());
+        refAddr = ref.get("testOnReturn");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setDefaultTestOnReturn(Boolean.valueOf(refAddr.getContent().toString()).booleanValue());
         }
 
-        ra = ref.get("testWhileIdle");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDefaultTestWhileIdle(Boolean.valueOf(
-                ra.getContent().toString()).booleanValue());
+        refAddr = ref.get("testWhileIdle");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setDefaultTestWhileIdle(Boolean.valueOf(refAddr.getContent().toString()).booleanValue());
         }
 
-        ra = ref.get("timeBetweenEvictionRunsMillis");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDefaultTimeBetweenEvictionRunsMillis(
-                Long.parseLong(ra.getContent().toString()));
+        refAddr = ref.get("timeBetweenEvictionRunsMillis");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setDefaultTimeBetweenEvictionRunsMillis(Long.parseLong(refAddr.getContent().toString()));
         }
 
-
         // Connection factory properties
 
-        ra = ref.get("validationQuery");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setValidationQuery(ra.getContent().toString());
+        refAddr = ref.get("validationQuery");
+        if (refAddr != null && refAddr.getContent() != null) {
+            ikds.setValidationQuery(refAddr.getContent().toString());
         }
 
-        ra = ref.get("validationQueryTimeout");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setValidationQueryTimeout(Integer.parseInt(
-                    ra.getContent().toString()));
+        refAddr = ref.get("validationQueryTimeout");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setValidationQueryTimeout(Integer.parseInt(refAddr.getContent().toString()));
         }
 
-        ra = ref.get("rollbackAfterValidation");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setRollbackAfterValidation(Boolean.valueOf(
-                ra.getContent().toString()).booleanValue());
+        refAddr = ref.get("rollbackAfterValidation");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setRollbackAfterValidation(Boolean.valueOf(refAddr.getContent().toString()).booleanValue());
         }
 
-        ra = ref.get("maxConnLifetimeMillis");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setMaxConnLifetimeMillis(
-                Long.parseLong(ra.getContent().toString()));
+        refAddr = ref.get("maxConnLifetimeMillis");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setMaxConnLifetimeMillis(Long.parseLong(refAddr.getContent().toString()));
         }
 
-
         // Connection properties
 
-        ra = ref.get("defaultAutoCommit");
-        if (ra != null && ra.getContent() != null) {
-            
ikds.setDefaultAutoCommit(Boolean.valueOf(ra.getContent().toString()));
+        refAddr = ref.get("defaultAutoCommit");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setDefaultAutoCommit(Boolean.valueOf(refAddr.getContent().toString()));
         }
 
-        ra = ref.get("defaultTransactionIsolation");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDefaultTransactionIsolation(
-                Integer.parseInt(ra.getContent().toString()));
+        refAddr = ref.get("defaultTransactionIsolation");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setDefaultTransactionIsolation(Integer.parseInt(refAddr.getContent().toString()));
         }
 
-        ra = ref.get("defaultReadOnly");
-        if (ra != null && ra.getContent() != null) {
-            
ikds.setDefaultReadOnly(Boolean.valueOf(ra.getContent().toString()));
+        refAddr = ref.get("defaultReadOnly");
+        if (refAddr != null && refAddr.getContent() != null) {
+            
ikds.setDefaultReadOnly(Boolean.valueOf(refAddr.getContent().toString()));
         }
     }
 
-
     /**
-     * @param className The class name
-     * @return true if and only if className is the value returned
-     * from getClass().getName().toString()
+     * @return true if and only if className is the value returned from 
getClass().getName().toString()
      */
     protected abstract boolean isCorrectClass(String className);
 
     /**
-     * Creates an instance of the subclass and sets any properties
-     * contained in the Reference.
-     * @param ref The reference
-     * @return the data source
-     * @throws IOException IO error
-     * @throws ClassNotFoundException Couldn't load data source implementation
+     * Creates an instance of the subclass and sets any properties contained 
in the Reference.
      */
-    protected abstract InstanceKeyDataSource getNewInstance(Reference ref)
-        throws IOException, ClassNotFoundException;
+    protected abstract InstanceKeyDataSource getNewInstance(Reference ref) 
throws IOException, ClassNotFoundException;
 
     /**
-     * Used to set some properties saved within a Reference.
-     * @param data Object data
-     * @return the deserialized object
-     * @throws IOException Stream error
-     * @throws ClassNotFoundException Couldn't load object class
+     * Sets some properties saved within a Reference
      */
-    protected static final Object deserialize(final byte[] data)
-        throws IOException, ClassNotFoundException {
+    protected static final Object deserialize(final byte[] data) throws 
IOException, ClassNotFoundException {
         ObjectInputStream in = null;
         try {
             in = new ObjectInputStream(new ByteArrayInputStream(data));
@@ -330,9 +309,9 @@ abstract class InstanceKeyDataSourceFact
                 try {
                     in.close();
                 } catch (final IOException ex) {
+                    // ignore
                 }
             }
         }
     }
 }
-

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/KeyedCPDSConnectionFactory.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/KeyedCPDSConnectionFactory.java?rev=1833794&r1=1833793&r2=1833794&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/KeyedCPDSConnectionFactory.java
 (original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/KeyedCPDSConnectionFactory.java
 Tue Jun 19 09:04:08 2018
@@ -38,66 +38,59 @@ import org.apache.tomcat.dbcp.pool2.Pool
 import org.apache.tomcat.dbcp.pool2.impl.DefaultPooledObject;
 
 /**
- * A {@link KeyedPooledObjectFactory} that creates
- * {@link org.apache.tomcat.dbcp.dbcp2.PoolableConnection PoolableConnection}s.
+ * A {@link KeyedPooledObjectFactory} that creates {@link 
org.apache.tomcat.dbcp.dbcp2.PoolableConnection
+ * PoolableConnection}s.
  *
- * @author John D. McNally
  * @since 2.0
  */
-class KeyedCPDSConnectionFactory
-    implements KeyedPooledObjectFactory<UserPassKey,PooledConnectionAndInfo>,
-    ConnectionEventListener, PooledConnectionManager {
+class KeyedCPDSConnectionFactory implements 
KeyedPooledObjectFactory<UserPassKey, PooledConnectionAndInfo>,
+        ConnectionEventListener, PooledConnectionManager {
 
-    private static final String NO_KEY_MESSAGE
-            = "close() was called on a Connection, but "
+    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 KeyedObjectPool<UserPassKey,PooledConnectionAndInfo> _pool;
+    private final ConnectionPoolDataSource cpds;
+    private final String validationQuery;
+    private final int validationQueryTimeoutSeconds;
+    private final boolean rollbackAfterValidation;
+    private KeyedObjectPool<UserPassKey, PooledConnectionAndInfo> pool;
     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 KeyedPoolableConnectionFactory}.
-     * @param cpds the ConnectionPoolDataSource from which to obtain
-     * PooledConnections
-     * @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 case3 {@link Connection#isValid(int)} will be used
-     * to validate connections.
-     * @param validationQueryTimeout The time, in seconds, to allow for the
-     *        validation query to complete
-     * @param rollbackAfterValidation whether a rollback should be issued after
-     * {@link #validateObject validating} {@link Connection}s.
-     */
-    public KeyedCPDSConnectionFactory(final ConnectionPoolDataSource cpds,
-                                      final String validationQuery,
-                                      final int validationQueryTimeout,
-                                      final boolean rollbackAfterValidation) {
-        _cpds = cpds;
-        _validationQuery = validationQuery;
-        _validationQueryTimeout = validationQueryTimeout;
-        _rollbackAfterValidation = rollbackAfterValidation;
+     *
+     * @param cpds
+     *            the ConnectionPoolDataSource from which to obtain 
PooledConnections
+     * @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 case3 {@link 
Connection#isValid(int)} will be used to validate
+     *            connections.
+     * @param validationQueryTimeoutSeconds
+     *            The time, in seconds, to allow for the validation query to 
complete
+     * @param rollbackAfterValidation
+     *            whether a rollback should be issued after {@link 
#validateObject validating} {@link Connection}s.
+     */
+    public KeyedCPDSConnectionFactory(final ConnectionPoolDataSource cpds, 
final String validationQuery,
+            final int validationQueryTimeoutSeconds, final boolean 
rollbackAfterValidation) {
+        this.cpds = cpds;
+        this.validationQuery = validationQuery;
+        this.validationQueryTimeoutSeconds = validationQueryTimeoutSeconds;
+        this.rollbackAfterValidation = rollbackAfterValidation;
     }
 
-    public void setPool(final 
KeyedObjectPool<UserPassKey,PooledConnectionAndInfo> pool) {
-        this._pool = pool;
+    public void setPool(final KeyedObjectPool<UserPassKey, 
PooledConnectionAndInfo> pool) {
+        this.pool = pool;
     }
 
     /**
@@ -105,29 +98,30 @@ class KeyedCPDSConnectionFactory
      *
      * @return KeyedObjectPool managing pooled connections
      */
-    public KeyedObjectPool<UserPassKey,PooledConnectionAndInfo> getPool() {
-        return _pool;
+    public KeyedObjectPool<UserPassKey, PooledConnectionAndInfo> getPool() {
+        return pool;
     }
 
     /**
      * Creates a new {@link PooledConnectionAndInfo} from the given {@link 
UserPassKey}.
      *
-     * @param upkey {@link UserPassKey} containing user credentials
-     * @throws SQLException if the connection could not be created.
+     * @param upkey
+     *            {@link UserPassKey} containing user credentials
+     * @throws SQLException
+     *             if the connection could not be created.
      * @see 
org.apache.tomcat.dbcp.pool2.KeyedPooledObjectFactory#makeObject(java.lang.Object)
      */
     @Override
-    public synchronized PooledObject<PooledConnectionAndInfo> makeObject(final 
UserPassKey upkey)
-            throws Exception {
+    public synchronized PooledObject<PooledConnectionAndInfo> makeObject(final 
UserPassKey upkey) throws Exception {
         PooledConnectionAndInfo pci = null;
 
         PooledConnection pc = null;
-        final String username = upkey.getUsername();
+        final String userName = upkey.getUsername();
         final String password = upkey.getPassword();
-        if (username == null) {
-            pc = _cpds.getPooledConnection();
+        if (userName == null) {
+            pc = cpds.getPooledConnection();
         } else {
-            pc = _cpds.getPooledConnection(username, password);
+            pc = cpds.getPooledConnection(userName, password);
         }
 
         if (pc == null) {
@@ -137,7 +131,7 @@ class KeyedCPDSConnectionFactory
         // 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, 
upkey.getPasswordCharArray());
         pcMap.put(pc, pci);
 
         return new DefaultPooledObject<>(pci);
@@ -147,8 +141,7 @@ class KeyedCPDSConnectionFactory
      * Closes the PooledConnection and stops listening for events from it.
      */
     @Override
-    public void destroyObject(final UserPassKey key, final 
PooledObject<PooledConnectionAndInfo> p)
-            throws Exception {
+    public void destroyObject(final UserPassKey key, final 
PooledObject<PooledConnectionAndInfo> p) throws Exception {
         final PooledConnection pc = p.getObject().getPooledConnection();
         pc.removeConnectionEventListener(this);
         pcMap.remove(pc);
@@ -158,31 +151,31 @@ class KeyedCPDSConnectionFactory
     /**
      * Validates a pooled connection.
      *
-     * @param key ignored
-     * @param p wrapped {@link PooledConnectionAndInfo} containing the
-     *          connection to validate
+     * @param key
+     *            ignored
+     * @param pooledObject
+     *            wrapped {@link PooledConnectionAndInfo} containing the 
connection to validate
      * @return true if validation succeeds
      */
     @Override
-    public boolean validateObject(final UserPassKey key,
-            final PooledObject<PooledConnectionAndInfo> p) {
+    public boolean validateObject(final UserPassKey key, final 
PooledObject<PooledConnectionAndInfo> pooledObject) {
         try {
-            validateLifetime(p);
+            validateLifetime(pooledObject);
         } catch (final Exception e) {
             return false;
         }
         boolean valid = false;
-        final PooledConnection pconn = p.getObject().getPooledConnection();
+        final PooledConnection pconn = 
pooledObject.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 {
@@ -200,16 +193,16 @@ class KeyedCPDSConnectionFactory
             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) {
+            } catch (final Exception e) {
                 valid = false;
             } finally {
                 Utils.closeQuietly(rset);
@@ -222,14 +215,12 @@ class KeyedCPDSConnectionFactory
     }
 
     @Override
-    public void passivateObject(final UserPassKey key,
-            final PooledObject<PooledConnectionAndInfo> p) throws Exception {
+    public void passivateObject(final UserPassKey key, final 
PooledObject<PooledConnectionAndInfo> p) throws Exception {
         validateLifetime(p);
     }
 
     @Override
-    public void activateObject(final UserPassKey key,
-            final PooledObject<PooledConnectionAndInfo> p) throws Exception {
+    public void activateObject(final UserPassKey key, final 
PooledObject<PooledConnectionAndInfo> p) throws Exception {
         validateLifetime(p);
     }
 
@@ -238,14 +229,13 @@ class KeyedCPDSConnectionFactory
     // ***********************************************************************
 
     /**
-     * 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) {
-        final PooledConnection pc = (PooledConnection)event.getSource();
+        final PooledConnection pc = (PooledConnection) event.getSource();
         // if this event occurred because we were validating, or if this
         // connection has been marked for removal, ignore it
         // otherwise return the connection to the pool.
@@ -255,16 +245,14 @@ class KeyedCPDSConnectionFactory
                 throw new IllegalStateException(NO_KEY_MESSAGE);
             }
             try {
-                _pool.returnObject(pci.getUserPassKey(), pci);
+                pool.returnObject(pci.getUserPassKey(), 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 {
-                    _pool.invalidateObject(pci.getUserPassKey(), pci);
+                    pool.invalidateObject(pci.getUserPassKey(), pci);
                 } catch (final Exception e3) {
-                    System.err.println("EXCEPTION WHILE DESTROYING OBJECT " +
-                            pci);
+                    System.err.println("EXCEPTION WHILE DESTROYING OBJECT " + 
pci);
                     e3.printStackTrace();
                 }
             }
@@ -272,16 +260,13 @@ class KeyedCPDSConnectionFactory
     }
 
     /**
-     * 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);
 
@@ -290,7 +275,7 @@ class KeyedCPDSConnectionFactory
             throw new IllegalStateException(NO_KEY_MESSAGE);
         }
         try {
-            _pool.invalidateObject(info.getUserPassKey(), info);
+            pool.invalidateObject(info.getUserPassKey(), info);
         } catch (final Exception e) {
             System.err.println("EXCEPTION WHILE DESTROYING OBJECT " + info);
             e.printStackTrace();
@@ -302,11 +287,10 @@ class KeyedCPDSConnectionFactory
     // ***********************************************************************
 
     /**
-     * Invalidates the PooledConnection in the pool.  The 
KeyedCPDSConnectionFactory
-     * closes the connection and pool counters are updated appropriately.
-     * Also clears any idle instances associated with the username that was 
used
-     * to create the PooledConnection.  Connections associated with this user
-     * are not affected and they will not be automatically closed on return to 
the pool.
+     * Invalidates the PooledConnection in the pool. The 
KeyedCPDSConnectionFactory closes the connection and pool
+     * counters are updated appropriately. Also clears any idle instances 
associated with the user name that was used to
+     * create the PooledConnection. Connections associated with this user are 
not affected and they will not be
+     * automatically closed on return to the pool.
      */
     @Override
     public void invalidate(final PooledConnection pc) throws SQLException {
@@ -316,53 +300,50 @@ class KeyedCPDSConnectionFactory
         }
         final UserPassKey key = info.getUserPassKey();
         try {
-            _pool.invalidateObject(key, info);  // Destroy and update pool 
counters
-            _pool.clear(key); // Remove any idle instances with this key
+            pool.invalidateObject(key, info); // Destroy and update pool 
counters
+            pool.clear(key); // Remove any idle instances with this key
         } catch (final Exception ex) {
             throw new SQLException("Error invalidating connection", ex);
         }
     }
 
     /**
-     * Does nothing.  This factory does not cache user credentials.
+     * Does nothing. This factory does not cache user credentials.
      */
     @Override
     public void setPassword(final String password) {
+        // Does nothing. This factory does not cache user credentials.
     }
 
     /**
-     * Sets the maximum lifetime in milliseconds of a connection after which 
the
-     * connection will always fail activation, passivation and validation.
+     * 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.
+     * @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;
     }
 
     /**
-     * This implementation does not fully close the KeyedObjectPool, as
-     * this would affect all users.  Instead, it clears the pool associated
-     * with the given user.  This method is not currently used.
+     * This implementation does not fully close the KeyedObjectPool, as this 
would affect all users. Instead, it clears
+     * the pool associated with the given user. This method is not currently 
used.
      */
     @Override
-    public void closePool(final String username) throws SQLException {
+    public void closePool(final String userName) throws SQLException {
         try {
-            _pool.clear(new UserPassKey(username, null));
+            pool.clear(new UserPassKey(userName));
         } 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