You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ma...@apache.org on 2014/02/13 22:53:13 UTC

svn commit: r1568055 [1/2] - in /commons/proper/dbcp/trunk/src: changes/ main/java/org/apache/commons/dbcp2/datasources/ test/java/org/apache/commons/dbcp2/cpdsadapter/ test/java/org/apache/commons/dbcp2/datasources/

Author: markt
Date: Thu Feb 13 21:53:12 2014
New Revision: 1568055

URL: http://svn.apache.org/r1568055
Log:
Fix DBCP-373
Modify SharedPoolDataSource and PerUserPoolDataSource to expose all of the configuration properties of the underlying connection pool(s).

Modified:
    commons/proper/dbcp/trunk/src/changes/changes.xml
    commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSource.java
    commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSourceFactory.java
    commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/PerUserPoolDataSource.java
    commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/PerUserPoolDataSourceFactory.java
    commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/SharedPoolDataSource.java
    commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/SharedPoolDataSourceFactory.java
    commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/cpdsadapter/TestDriverAdapterCPDS.java
    commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestCPDSConnectionFactory.java
    commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestKeyedCPDSConnectionFactory.java
    commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestPerUserPoolDataSource.java
    commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestSharedPoolDataSource.java

Modified: commons/proper/dbcp/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/changes/changes.xml?rev=1568055&r1=1568054&r2=1568055&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/changes/changes.xml (original)
+++ commons/proper/dbcp/trunk/src/changes/changes.xml Thu Feb 13 21:53:12 2014
@@ -151,6 +151,12 @@ The <action> type attribute can be add,u
         Register pooled connections with JMX so that they may be forcibly closed
         via JMX if required.
       </action>
+      <action dev="markt" issue="DBCP-373" type="add">
+        Modify SharedPoolDataSource and PerUserPoolDataSource to expose all of
+        the configuration properties of the underlying connection pool(s). This
+        represents a significant refactoring of these classes and a number of
+        property names have changed as a result. 
+      </action>
     </release>
     <release version="1.5.1" date="TBD" description="TBD">
       <action dev="markt" issue="DBCP-400" type="fix">

Modified: commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSource.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSource.java?rev=1568055&r1=1568054&r2=1568055&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSource.java (original)
+++ commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSource.java Thu Feb 13 21:53:12 2014
@@ -30,14 +30,13 @@ import java.util.logging.Logger;
 
 import javax.naming.Context;
 import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.naming.Reference;
-import javax.naming.StringRefAddr;
 import javax.naming.Referenceable;
 import javax.sql.ConnectionPoolDataSource;
 import javax.sql.DataSource;
 import javax.sql.PooledConnection;
 
+import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;
+import org.apache.commons.pool2.impl.GenericObjectPool;
 import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
 
 /**
@@ -87,12 +86,16 @@ import org.apache.commons.pool2.impl.Gen
  */
 public abstract class InstanceKeyDataSource
         implements DataSource, Referenceable, Serializable {
+
+    // TODO - Recalculate this
     private static final long serialVersionUID = -4243533936955098795L;
+
     private static final String GET_CONNECTION_CALLED
             = "A Connection was already requested from this source, "
             + "further initialization is not allowed.";
     private static final String BAD_TRANSACTION_ISOLATION
         = "The requested TransactionIsolation level is invalid.";
+
     /**
     * Internal constant to indicate the level is not set.
     */
@@ -107,11 +110,6 @@ public abstract class InstanceKeyDataSou
     /** DataSource Name used to find the ConnectionPoolDataSource */
     private String dataSourceName = null;
 
-    // Default connection properties
-    private Boolean defaultAutoCommit = null;
-    private int defaultTransactionIsolation = UNKNOWN_TRANSACTIONISOLATION;
-    private Boolean defaultReadOnly = null;
-
     /** Description */
     private String description = null;
 
@@ -124,33 +122,48 @@ public abstract class InstanceKeyDataSou
     /** Log stream */
     private PrintWriter logWriter = null;
 
+    /** Instance key */
+    private String instanceKey = null;
+
     // Pool properties
-    private boolean _testOnBorrow =
+    private boolean defaultBlockWhenExhausted =
+            GenericKeyedObjectPoolConfig.DEFAULT_BLOCK_WHEN_EXHAUSTED;
+    private String defaultEvictionPolicyClassName =
+            GenericKeyedObjectPoolConfig.DEFAULT_EVICTION_POLICY_CLASS_NAME;
+    private boolean defaultLifo = GenericKeyedObjectPoolConfig.DEFAULT_LIFO;
+    private int defaultMaxIdle =
+            GenericKeyedObjectPoolConfig.DEFAULT_MAX_IDLE_PER_KEY;
+    private int defaultMaxTotal =
+            GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL;
+    private long defaultMaxWaitMillis =
+            GenericKeyedObjectPoolConfig.DEFAULT_MAX_WAIT_MILLIS;
+    private long defaultMinEvictableIdleTimeMillis =
+            GenericKeyedObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
+    private int defaultMinIdle =
+            GenericKeyedObjectPoolConfig.DEFAULT_MIN_IDLE_PER_KEY;
+    private int defaultNumTestsPerEvictionRun =
+            GenericKeyedObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
+    private long defaultSoftMinEvictableIdleTimeMillis =
+            GenericObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
+    private boolean defaultTestOnBorrow =
             GenericObjectPoolConfig.DEFAULT_TEST_ON_BORROW;
-    private boolean _testOnReturn =
+    private boolean defaultTestOnReturn =
             GenericObjectPoolConfig.DEFAULT_TEST_ON_RETURN;
-    private int _timeBetweenEvictionRunsMillis = (int)
-            Math.min(Integer.MAX_VALUE,
-                     GenericObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS);
-    private int _numTestsPerEvictionRun =
-            GenericObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
-    private int _minEvictableIdleTimeMillis = (int)
-            Math.min(Integer.MAX_VALUE,
-                    GenericObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS);
-    private String evictionPolicyClassName =
-            GenericObjectPoolConfig.DEFAULT_EVICTION_POLICY_CLASS_NAME;
-    private boolean _testWhileIdle =
+    private boolean defaultTestWhileIdle =
             GenericObjectPoolConfig.DEFAULT_TEST_WHILE_IDLE;
+    private long defaultTimeBetweenEvictionRunsMillis =
+            GenericObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
+
+    // Connection factory properties
     private String validationQuery = null;
     private boolean rollbackAfterValidation = false;
     private long maxConnLifetimeMillis = -1;
 
+    // Connection properties
+    private Boolean defaultAutoCommit = null;
+    private int defaultTransactionIsolation = UNKNOWN_TRANSACTIONISOLATION;
+    private Boolean defaultReadOnly = null;
 
-    /** true iff one of the setters for testOnBorrow, testOnReturn, testWhileIdle has been called. */
-    private boolean testPositionSet = false;
-
-    /** Instance key */
-    private String instanceKey = null; // TODO make packge protected?
 
     /**
      * Default no-arg constructor for Serialization
@@ -193,10 +206,301 @@ public abstract class InstanceKeyDataSou
         throw new SQLFeatureNotSupportedException();
     }
 
+
     // -------------------------------------------------------------------
     // Properties
 
     /**
+     * Gets the default value for
+     * {@link GenericKeyedObjectPoolConfig#getBlockWhenExhausted()} for each per
+     * user pool.
+     */
+    public boolean getDefaultBlockWhenExhausted() {
+        return this.defaultBlockWhenExhausted;
+    }
+
+    /**
+     * Sets the default value for
+     * {@link GenericKeyedObjectPoolConfig#getBlockWhenExhausted()} for each per
+     * user pool.
+     */
+    public void setDefaultBlockWhenExhausted(boolean blockWhenExhausted) {
+        assertInitializationAllowed();
+        this.defaultBlockWhenExhausted = blockWhenExhausted;
+    }
+
+
+    /**
+     * Gets the default value for
+     * {@link GenericKeyedObjectPoolConfig#getEvictionPolicyClassName()} for
+     * each per user pool.
+     */
+    public String getDefaultEvictionPolicyClassName() {
+        return this.defaultEvictionPolicyClassName;
+    }
+
+    /**
+     * Sets the default value for
+     * {@link GenericKeyedObjectPoolConfig#getEvictionPolicyClassName()} for
+     * each per user pool.
+     */
+    public void setDefaultEvictionPolicyClassName(
+            String evictionPolicyClassName) {
+        assertInitializationAllowed();
+        this.defaultEvictionPolicyClassName = evictionPolicyClassName;
+    }
+
+
+    /**
+     * Gets the default value for
+     * {@link GenericKeyedObjectPoolConfig#getLifo()} for each per user pool.
+     */
+    public boolean getDefaultLifo() {
+        return this.defaultLifo;
+    }
+
+    /**
+     * Sets the default value for
+     * {@link GenericKeyedObjectPoolConfig#getLifo()} for each per user pool.
+     */
+    public void setDefaultLifo(boolean lifo) {
+        assertInitializationAllowed();
+        this.defaultLifo = lifo;
+    }
+
+
+    /**
+     * Gets the default value for
+     * {@link GenericKeyedObjectPoolConfig#getMaxIdlePerKey()} for each per user
+     * pool.
+     */
+    public int getDefaultMaxIdle() {
+        return this.defaultMaxIdle;
+    }
+
+    /**
+     * Sets the default value for
+     * {@link GenericKeyedObjectPoolConfig#getMaxIdlePerKey()} for each per user
+     * pool.
+     */
+    public void setDefaultMaxIdle(int maxIdle) {
+        assertInitializationAllowed();
+        this.defaultMaxIdle = maxIdle;
+    }
+
+
+    /**
+     * Gets the default value for
+     * {@link GenericKeyedObjectPoolConfig#getMaxTotalPerKey()} for each per
+     * user pool.
+     */
+    public int getDefaultMaxTotal() {
+        return this.defaultMaxTotal;
+    }
+
+    /**
+     * Sets the default value for
+     * {@link GenericKeyedObjectPoolConfig#getMaxTotalPerKey()} for each per
+     * user pool.
+     */
+    public void setDefaultMaxTotal(int maxTotal) {
+        assertInitializationAllowed();
+        this.defaultMaxTotal = maxTotal;
+    }
+
+
+    /**
+     * Gets the default value for
+     * {@link GenericKeyedObjectPoolConfig#getMaxWaitMillis()} for each per user
+     * pool.
+     */
+    public long getDefaultMaxWaitMillis() {
+        return this.defaultMaxWaitMillis;
+    }
+
+    /**
+     * Sets the default value for
+     * {@link GenericKeyedObjectPoolConfig#getMaxWaitMillis()} for each per user
+     * pool.
+     */
+    public void setDefaultMaxWaitMillis(long maxWaitMillis) {
+        assertInitializationAllowed();
+        this.defaultMaxWaitMillis = maxWaitMillis;
+    }
+
+
+    /**
+     * Gets the default value for
+     * {@link GenericKeyedObjectPoolConfig#getMinEvictableIdleTimeMillis()} for
+     * each per user pool.
+     */
+    public long getDefaultMinEvictableIdleTimeMillis() {
+        return this.defaultMinEvictableIdleTimeMillis;
+    }
+
+    /**
+     * Sets the default value for
+     * {@link GenericKeyedObjectPoolConfig#getMinEvictableIdleTimeMillis()} for
+     * each per user pool.
+     */
+    public void setDefaultMinEvictableIdleTimeMillis(
+            long minEvictableIdleTimeMillis) {
+        assertInitializationAllowed();
+        this.defaultMinEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
+    }
+
+
+    /**
+     * Gets the default value for
+     * {@link GenericKeyedObjectPoolConfig#getMinIdlePerKey()} for each per user
+     * pool.
+     */
+    public int getDefaultMinIdle() {
+        return this.defaultMinIdle;
+    }
+
+    /**
+     * Sets the default value for
+     * {@link GenericKeyedObjectPoolConfig#getMinIdlePerKey()} for each per user
+     * pool.
+     */
+    public void setDefaultMinIdle(int minIdle) {
+        assertInitializationAllowed();
+        this.defaultMinIdle = minIdle;
+    }
+
+
+    /**
+     * Gets the default value for
+     * {@link GenericKeyedObjectPoolConfig#getNumTestsPerEvictionRun()} for each
+     * per user pool.
+     */
+    public int getDefaultNumTestsPerEvictionRun() {
+        return this.defaultNumTestsPerEvictionRun;
+    }
+
+    /**
+     * Sets the default value for
+     * {@link GenericKeyedObjectPoolConfig#getNumTestsPerEvictionRun()} for each
+     * per user pool.
+     */
+    public void setDefaultNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
+        assertInitializationAllowed();
+        this.defaultNumTestsPerEvictionRun = numTestsPerEvictionRun;
+    }
+
+
+    /**
+     * Gets the default value for
+     * {@link GenericObjectPool#getSoftMinEvictableIdleTimeMillis()} for each
+     * per user pool.
+     */
+    public long getDefaultSoftMinEvictableIdleTimeMillis() {
+        return this.defaultSoftMinEvictableIdleTimeMillis;
+    }
+
+    /**
+     * Sets the default value for
+     * {@link GenericObjectPool#getSoftMinEvictableIdleTimeMillis()} for each per user pool.
+     */
+    public void setDefaultSoftMinEvictableIdleTimeMillis(
+            long softMinEvictableIdleTimeMillis) {
+        assertInitializationAllowed();
+        this.defaultSoftMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
+    }
+
+
+    /**
+     * Gets the default value for
+     * {@link GenericObjectPool#getTestOnBorrow()} for each per user pool.
+     */
+    public boolean getDefaultTestOnBorrow() {
+        return this.defaultTestOnBorrow;
+    }
+
+    /**
+     * Sets the default value for
+     * {@link GenericObjectPool#getTestOnBorrow()} for each per user pool.
+     */
+    public void setDefaultTestOnBorrow(boolean testOnBorrow) {
+        assertInitializationAllowed();
+        this.defaultTestOnBorrow = testOnBorrow;
+    }
+
+
+    /**
+     * Gets the default value for
+     * {@link GenericObjectPool#getTestOnReturn()} for each per user pool.
+     */
+    public boolean getDefaultTestOnReturn() {
+        return this.defaultTestOnReturn;
+    }
+
+    /**
+     * Sets the default value for
+     * {@link GenericObjectPool#getTestOnReturn()} for each per user pool.
+     */
+    public void setDefaultTestOnReturn(boolean TestOnReturn) {
+        assertInitializationAllowed();
+        this.defaultTestOnReturn = TestOnReturn;
+    }
+
+
+    /**
+     * Gets the default value for
+     * {@link GenericObjectPool#getTestWhileIdle()} for each per user pool.
+     */
+    public boolean getDefaultTestWhileIdle() {
+        return this.defaultTestWhileIdle;
+    }
+
+    /**
+     * Sets the default value for
+     * {@link GenericObjectPool#getTestWhileIdle()} for each per user pool.
+     */
+    public void setDefaultTestWhileIdle(boolean TestWhileIdle) {
+        assertInitializationAllowed();
+        this.defaultTestWhileIdle = TestWhileIdle;
+    }
+
+
+    /**
+     * Gets the default value for
+     * {@link GenericObjectPool#getTimeBetweenEvictionRunsMillis ()} for each
+     * per user pool.
+     */
+    public long getDefaultTimeBetweenEvictionRunsMillis () {
+        return this.defaultTimeBetweenEvictionRunsMillis ;
+    }
+
+    /**
+     * Sets the default value for
+     * {@link GenericObjectPool#getTimeBetweenEvictionRunsMillis ()} for each
+     * per user pool.
+     */
+    public void setDefaultTimeBetweenEvictionRunsMillis (
+            long TimeBetweenEvictionRunsMillis ) {
+        assertInitializationAllowed();
+        this.defaultTimeBetweenEvictionRunsMillis = TimeBetweenEvictionRunsMillis ;
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    /**
      * Get the value of connectionPoolDataSource.  This method will return
      * null, if the backing datasource is being accessed via jndi.
      *
@@ -465,228 +769,13 @@ public abstract class InstanceKeyDataSou
     }
 
     /**
-     * @see #getTestOnBorrow
-     */
-    public final boolean isTestOnBorrow() {
-        return getTestOnBorrow();
-    }
-
-    /**
-     * When <tt>true</tt>, objects will be
-     * {*link PoolableObjectFactory#validateObject validated}
-     * before being returned by the {*link #borrowObject}
-     * method.  If the object fails to validate,
-     * it will be dropped from the pool, and we will attempt
-     * to borrow another.
-     *
-     * @see #setTestOnBorrow
-     */
-    public boolean getTestOnBorrow() {
-        return _testOnBorrow;
-    }
-
-    /**
-     * When <tt>true</tt>, objects will be
-     * {*link PoolableObjectFactory#validateObject validated}
-     * before being returned by the {*link #borrowObject}
-     * method.  If the object fails to validate,
-     * it will be dropped from the pool, and we will attempt
-     * to borrow another. For a <code>true</code> value to have any effect,
-     * the <code>validationQuery</code> property must be set to a non-null
-     * string.
-     *
-     * @see #getTestOnBorrow
-     */
-    public void setTestOnBorrow(boolean testOnBorrow) {
-        assertInitializationAllowed();
-        _testOnBorrow = testOnBorrow;
-        testPositionSet = true;
-    }
-
-    /**
-     * @see #getTestOnReturn
-     */
-    public final boolean isTestOnReturn() {
-        return getTestOnReturn();
-    }
-
-    /**
-     * When <tt>true</tt>, objects will be
-     * {*link PoolableObjectFactory#validateObject validated}
-     * before being returned to the pool within the
-     * {*link #returnObject}.
-     *
-     * @see #setTestOnReturn
-     */
-    public boolean getTestOnReturn() {
-        return _testOnReturn;
-    }
-
-    /**
-     * When <tt>true</tt>, objects will be
-     * {*link PoolableObjectFactory#validateObject validated}
-     * before being returned to the pool within the
-     * {*link #returnObject}. For a <code>true</code> value to have any effect,
-     * the <code>validationQuery</code> property must be set to a non-null
-     * string.
-     *
-     * @see #getTestOnReturn
-     */
-    public void setTestOnReturn(boolean testOnReturn) {
-        assertInitializationAllowed();
-        _testOnReturn = testOnReturn;
-        testPositionSet = true;
-    }
-
-    /**
-     * Returns the number of milliseconds to sleep between runs of the
-     * idle object evictor thread.
-     * When non-positive, no idle object evictor thread will be
-     * run.
-     *
-     * @see #setTimeBetweenEvictionRunsMillis
-     */
-    public int getTimeBetweenEvictionRunsMillis() {
-        return _timeBetweenEvictionRunsMillis;
-    }
-
-    /**
-     * Sets the number of milliseconds to sleep between runs of the
-     * idle object evictor thread.
-     * When non-positive, no idle object evictor thread will be
-     * run.
-     *
-     * @see #getTimeBetweenEvictionRunsMillis
-     */
-    public void
-        setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
-        assertInitializationAllowed();
-            _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
-    }
-
-    /**
-     * Returns the number of objects to examine during each run of the
-     * idle object evictor thread (if any).
-     *
-     * @see #setNumTestsPerEvictionRun
-     * @see #setTimeBetweenEvictionRunsMillis
-     */
-    public int getNumTestsPerEvictionRun() {
-        return _numTestsPerEvictionRun;
-    }
-
-    /**
-     * Sets the number of objects to examine during each run of the
-     * idle object evictor thread (if any).
-     * <p>
-     * When a negative value is supplied, <tt>ceil({*link #numIdle})/abs({*link #getNumTestsPerEvictionRun})</tt>
-     * tests will be run.  I.e., when the value is <i>-n</i>, roughly one <i>n</i>th of the
-     * idle objects will be tested per run.
-     *
-     * @see #getNumTestsPerEvictionRun
-     * @see #setTimeBetweenEvictionRunsMillis
-     */
-    public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
-        assertInitializationAllowed();
-        _numTestsPerEvictionRun = numTestsPerEvictionRun;
-    }
-
-    /**
-     * Returns the minimum amount of time an object may sit idle in the pool
-     * before it is eligable for eviction by the idle object evictor
-     * (if any).
-     *
-     * @see #setMinEvictableIdleTimeMillis
-     * @see #setTimeBetweenEvictionRunsMillis
-     */
-    public int getMinEvictableIdleTimeMillis() {
-        return _minEvictableIdleTimeMillis;
-    }
-
-    /**
-     * Sets the minimum amount of time an object may sit idle in the pool
-     * before it is eligable for eviction by the idle object evictor
-     * (if any).
-     * When non-positive, no objects will be evicted from the pool
-     * due to idle time alone.
-     *
-     * @see #getMinEvictableIdleTimeMillis
-     * @see #setTimeBetweenEvictionRunsMillis
-     */
-    public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
-        assertInitializationAllowed();
-        _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
-    }
-
-    /**
-     * Gets the EvictionPolicy implementation in use with this connection pool.
-     *
-     * @since 2.0
-     */
-    public synchronized String getEvictionPolicyClassName() {
-        return evictionPolicyClassName;
-    }
-
-    /**
-     * Sets the EvictionPolicy implementation to use with this connection pool.
-     *
-     * @param evictionPolicyClassName   The fully qualified class name of the
-     *                                  EvictionPolicy implementation
-     *
-     * @since 2.0
-     */
-    public synchronized void setEvictionPolicyClassName(
-            String evictionPolicyClassName) {
-        assertInitializationAllowed();
-        this.evictionPolicyClassName = evictionPolicyClassName;
-    }
-
-    /**
-     * @see #getTestWhileIdle
-     */
-    public final boolean isTestWhileIdle() {
-        return getTestWhileIdle();
-    }
-
-    /**
-     * When <tt>true</tt>, objects will be
-     * {*link PoolableObjectFactory#validateObject validated}
-     * by the idle object evictor (if any).  If an object
-     * fails to validate, it will be dropped from the pool.
-     *
-     * @see #setTestWhileIdle
-     * @see #setTimeBetweenEvictionRunsMillis
-     */
-    public boolean getTestWhileIdle() {
-        return _testWhileIdle;
-    }
-
-    /**
-     * When <tt>true</tt>, objects will be
-     * {*link PoolableObjectFactory#validateObject validated}
-     * by the idle object evictor (if any).  If an object
-     * fails to validate, it will be dropped from the pool. For a
-     * <code>true</code> value to have any effect,
-     * the <code>validationQuery</code> property must be set to a non-null
-     * string.
-     *
-     * @see #getTestWhileIdle
-     * @see #setTimeBetweenEvictionRunsMillis
-     */
-    public void setTestWhileIdle(boolean testWhileIdle) {
-        assertInitializationAllowed();
-        _testWhileIdle = testWhileIdle;
-        testPositionSet = true;
-    }
-
-    /**
      * The SQL query that will be used to validate connections from this pool
      * before returning them to the caller.  If specified, this query
      * <strong>MUST</strong> be an SQL SELECT statement that returns at least
      * one row.
      */
     public String getValidationQuery() {
-        return (this.validationQuery);
+        return this.validationQuery;
     }
 
     /**
@@ -699,9 +788,6 @@ public abstract class InstanceKeyDataSou
     public void setValidationQuery(String validationQuery) {
         assertInitializationAllowed();
         this.validationQuery = validationQuery;
-        if (!testPositionSet) {
-            setTestOnBorrow(true);
-        }
     }
 
     /**
@@ -944,30 +1030,4 @@ public abstract class InstanceKeyDataSou
         }
         return cpds;
     }
-
-    // ----------------------------------------------------------------------
-    // Referenceable implementation
-
-    /**
-     * Retrieves the Reference of this object.
-     * <strong>Note:</strong> <code>InstanceKeyDataSource</code> subclasses
-     * should override this method. The implementaion included below
-     * is not robust and will be removed at the next major version DBCP
-     * release.
-     *
-     * @return The non-null Reference of this object.
-     * @exception NamingException If a naming exception was encountered
-     *      while retrieving the reference.
-     */
-    // TODO: Remove the implementation of this method at next major
-    // version release.
-
-    @Override
-    public Reference getReference() throws NamingException {
-        final String className = getClass().getName();
-        final String factoryName = className + "Factory"; // XXX: not robust
-        Reference ref = new Reference(className, factoryName, null);
-        ref.add(new StringRefAddr("instanceKey", instanceKey));
-        return ref;
-    }
 }

Modified: commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSourceFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSourceFactory.java?rev=1568055&r1=1568054&r2=1568055&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSourceFactory.java (original)
+++ commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSourceFactory.java Thu Feb 13 21:53:12 2014
@@ -139,16 +139,6 @@ abstract class InstanceKeyDataSourceFact
             ikds.setDataSourceName(ra.getContent().toString());
         }
 
-        ra = ref.get("defaultAutoCommit");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDefaultAutoCommit(Boolean.valueOf(ra.getContent().toString()));
-        }
-
-        ra = ref.get("defaultReadOnly");
-        if (ra != null && ra.getContent() != null) {
-            ikds.setDefaultReadOnly(Boolean.valueOf(ra.getContent().toString()));
-        }
-
         ra = ref.get("description");
         if (ra != null && ra.getContent() != null) {
             ikds.setDescription(ra.getContent().toString());
@@ -166,46 +156,129 @@ abstract class InstanceKeyDataSourceFact
                 Integer.parseInt(ra.getContent().toString()));
         }
 
-        ra = ref.get("testOnBorrow");
+        // Pool properties
+        ra = ref.get("blockWhenExhausted");
         if (ra != null && ra.getContent() != null) {
-            ikds.setTestOnBorrow(Boolean.valueOf(
+            ikds.setDefaultBlockWhenExhausted(Boolean.valueOf(
                 ra.getContent().toString()).booleanValue());
         }
 
-        ra = ref.get("testOnReturn");
+        ra = ref.get("evictionPolicyClassName");
         if (ra != null && ra.getContent() != null) {
-            ikds.setTestOnReturn(Boolean.valueOf(
+            ikds.setDefaultEvictionPolicyClassName(ra.getContent().toString());
+        }
+
+        // Pool properties
+        ra = ref.get("lifo");
+        if (ra != null && ra.getContent() != null) {
+            ikds.setDefaultLifo(Boolean.valueOf(
                 ra.getContent().toString()).booleanValue());
         }
 
-        ra = ref.get("timeBetweenEvictionRunsMillis");
+        ra = ref.get("maxIdlePerKey");
         if (ra != null && ra.getContent() != null) {
-            ikds.setTimeBetweenEvictionRunsMillis(
+            ikds.setDefaultMaxIdle(
                 Integer.parseInt(ra.getContent().toString()));
         }
 
-        ra = ref.get("numTestsPerEvictionRun");
+        ra = ref.get("maxTotalPerKey");
         if (ra != null && ra.getContent() != null) {
-            ikds.setNumTestsPerEvictionRun(
+            ikds.setDefaultMaxTotal(
                 Integer.parseInt(ra.getContent().toString()));
         }
 
+        ra = ref.get("maxWaitMillis");
+        if (ra != null && ra.getContent() != null) {
+            ikds.setDefaultMaxWaitMillis(
+                Long.parseLong(ra.getContent().toString()));
+        }
+
         ra = ref.get("minEvictableIdleTimeMillis");
         if (ra != null && ra.getContent() != null) {
-            ikds.setMinEvictableIdleTimeMillis(
+            ikds.setDefaultMinEvictableIdleTimeMillis(
+                Long.parseLong(ra.getContent().toString()));
+        }
+
+        ra = ref.get("minIdlePerKey");
+        if (ra != null && ra.getContent() != null) {
+            ikds.setDefaultMinIdle(
                 Integer.parseInt(ra.getContent().toString()));
         }
 
+        ra = ref.get("numTestsPerEvictionRun");
+        if (ra != null && ra.getContent() != null) {
+            ikds.setDefaultNumTestsPerEvictionRun(
+                Integer.parseInt(ra.getContent().toString()));
+        }
+
+        ra = ref.get("softMinEvictableIdleTimeMillis");
+        if (ra != null && ra.getContent() != null) {
+            ikds.setDefaultSoftMinEvictableIdleTimeMillis(
+                Long.parseLong(ra.getContent().toString()));
+        }
+
+        ra = ref.get("testOnBorrow");
+        if (ra != null && ra.getContent() != null) {
+            ikds.setDefaultTestOnBorrow(Boolean.valueOf(
+                ra.getContent().toString()).booleanValue());
+        }
+
+        ra = ref.get("testOnReturn");
+        if (ra != null && ra.getContent() != null) {
+            ikds.setDefaultTestOnReturn(Boolean.valueOf(
+                ra.getContent().toString()).booleanValue());
+        }
+
         ra = ref.get("testWhileIdle");
         if (ra != null && ra.getContent() != null) {
-            ikds.setTestWhileIdle(Boolean.valueOf(
+            ikds.setDefaultTestWhileIdle(Boolean.valueOf(
                 ra.getContent().toString()).booleanValue());
         }
 
+        ra = ref.get("timeBetweenEvictionRunsMillis");
+        if (ra != null && ra.getContent() != null) {
+            ikds.setDefaultTimeBetweenEvictionRunsMillis(
+                Long.parseLong(ra.getContent().toString()));
+        }
+
+
+        // Connection factory properties
+
         ra = ref.get("validationQuery");
         if (ra != null && ra.getContent() != null) {
             ikds.setValidationQuery(ra.getContent().toString());
         }
+
+        ra = ref.get("rollbackAfterValidation");
+        if (ra != null && ra.getContent() != null) {
+            ikds.setRollbackAfterValidation(Boolean.valueOf(
+                ra.getContent().toString()).booleanValue());
+        }
+
+        ra = ref.get("maxConnLifetimeMillis");
+        if (ra != null && ra.getContent() != null) {
+            ikds.setMaxConnLifetimeMillis(
+                Long.parseLong(ra.getContent().toString()));
+        }
+
+
+        // Connection properties
+
+        ra = ref.get("defaultAutoCommit");
+        if (ra != null && ra.getContent() != null) {
+            ikds.setDefaultAutoCommit(Boolean.valueOf(ra.getContent().toString()));
+        }
+
+        ra = ref.get("defaultTransactionIsolation");
+        if (ra != null && ra.getContent() != null) {
+            ikds.setDefaultTransactionIsolation(
+                Integer.parseInt(ra.getContent().toString()));
+        }
+
+        ra = ref.get("defaultReadOnly");
+        if (ra != null && ra.getContent() != null) {
+            ikds.setDefaultReadOnly(Boolean.valueOf(ra.getContent().toString()));
+        }
     }
 
 

Modified: commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/PerUserPoolDataSource.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/PerUserPoolDataSource.java?rev=1568055&r1=1568054&r2=1568055&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/PerUserPoolDataSource.java (original)
+++ commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/PerUserPoolDataSource.java Thu Feb 13 21:53:12 2014
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.commons.dbcp2.datasources;
 
 import java.io.IOException;
@@ -35,7 +34,6 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.commons.pool2.ObjectPool;
 import org.apache.commons.pool2.impl.GenericObjectPool;
-import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
 
 /**
  * <p>A pooling <code>DataSource</code> appropriate for deployment within
@@ -49,31 +47,42 @@ import org.apache.commons.pool2.impl.Gen
  *
  * <p>User passwords can be changed without re-initializing the datasource.
  * When a <code>getConnection(username, password)</code> request is processed
- * with a password that is different from those used to create connections in the
- * pool associated with <code>username</code>, an attempt is made to create a
- * new connection using the supplied password and if this succeeds, the existing
- * pool is cleared and a new pool is created for connections using the new password.</p>
- *
+ * with a password that is different from those used to create connections in
+ * the pool associated with <code>username</code>, an attempt is made to create
+ * a new connection using the supplied password and if this succeeds, the
+ * existing pool is cleared and a new pool is created for connections using the
+ * new password.</p>
  *
  * @author John D. McNally
  * @version $Revision$ $Date$
  */
 public class PerUserPoolDataSource extends InstanceKeyDataSource {
 
+    // TODO Re-calculate this
     private static final long serialVersionUID = -3104731034410444060L;
 
     private static final Log log =
             LogFactory.getLog(PerUserPoolDataSource.class);
 
-    private int defaultMaxTotal = GenericObjectPoolConfig.DEFAULT_MAX_TOTAL;
-    private int defaultMaxIdle = GenericObjectPoolConfig.DEFAULT_MAX_IDLE;
-    private int defaultMaxWaitMillis = (int)Math.min(Integer.MAX_VALUE,
-            GenericObjectPoolConfig.DEFAULT_MAX_WAIT_MILLIS);
+    // Per user pool properties
+    private Map<String,Boolean> perUserBlockWhenExhausted = null;
+    private Map<String,String> perUserEvictionPolicyClassName = null;
+    private Map<String,Boolean> perUserLifo = null;
+    private Map<String,Integer> perUserMaxIdle = null;
+    private Map<String,Integer> perUserMaxTotal = null;
+    private Map<String,Long> perUserMaxWaitMillis = null;
+    private Map<String,Long> perUserMinEvictableIdleTimeMillis = null;
+    private Map<String,Integer> perUserMinIdle = null;
+    private Map<String,Integer> perUserNumTestsPerEvictionRun = null;
+    private Map<String,Long> perUserSoftMinEvictableIdleTimeMillis = null;
+    private Map<String,Boolean> perUserTestOnBorrow = null;
+    private Map<String,Boolean> perUserTestOnReturn = null;
+    private Map<String,Boolean> perUserTestWhileIdle = null;
+    private Map<String,Long> perUserTimeBetweenEvictionRunsMillis = null;
+
+    // Per user connection properties
     private Map<String,Boolean> perUserDefaultAutoCommit = null;
     private Map<String,Integer> perUserDefaultTransactionIsolation = null;
-    private Map<String,Integer> perUserMaxTotal = null;
-    private Map<String,Integer> perUserMaxIdle = null;
-    private Map<String,Integer> perUserMaxWaitMillis = null;
     private Map<String,Boolean> perUserDefaultReadOnly = null;
 
     /**
@@ -107,162 +116,189 @@ public class PerUserPoolDataSource exten
     // Properties
 
     /**
-     * The maximum number of active connections that can be allocated from
-     * this pool at the same time, or negative for no limit.
-     * This value is used for any username which is not specified
-     * in perUserMaxConnections.
+     * Gets the user specific value for
+     * {@link GenericObjectPool#getBlockWhenExhausted()} for the
+     * specified user's pool or the default if no user specific value is defined.
      */
-    public int getDefaultMaxTotal() {
-        return (this.defaultMaxTotal);
+    public boolean getPerUserBlockWhenExhausted(String key) {
+        Boolean value = null;
+        if (perUserBlockWhenExhausted != null) {
+            value = perUserBlockWhenExhausted.get(key);
+        }
+        if (value == null) {
+            return getDefaultBlockWhenExhausted();
+        }
+        return value.booleanValue();
     }
 
     /**
-     * The maximum number of active connections that can be allocated from
-     * this pool at the same time, or negative for no limit.
-     * This value is used for any username which is not specified
-     * in perUserMaxConnections.  The default is 8.
+     * Sets a user specific value for
+     * {@link GenericObjectPool#getBlockWhenExhausted()} for the specified
+     * user's pool.
      */
-    public void setDefaultMaxTotal(int maxActive) {
+    public void setPerUserBlockWhenExhausted(String username,
+            Boolean value) {
         assertInitializationAllowed();
-        this.defaultMaxTotal = maxActive;
+        if (perUserBlockWhenExhausted == null) {
+            perUserBlockWhenExhausted = new HashMap<>();
+        }
+        perUserBlockWhenExhausted.put(username, value);
     }
 
-    /**
-     * The maximum number of active connections that can remain idle in the
-     * pool, without extra ones being released, or negative for no limit.
-     * This value is used for any username which is not specified
-     * in perUserMaxIdle.
-     */
-    public int getDefaultMaxIdle() {
-        return (this.defaultMaxIdle);
+    void setPerUserBlockWhenExhausted(
+            Map<String,Boolean> userDefaultBlockWhenExhausted) {
+        assertInitializationAllowed();
+        if (perUserBlockWhenExhausted == null) {
+            perUserBlockWhenExhausted = new HashMap<>();
+        } else {
+            perUserBlockWhenExhausted.clear();
+        }
+        perUserBlockWhenExhausted.putAll(userDefaultBlockWhenExhausted);
     }
 
+
     /**
-     * The maximum number of active connections that can remain idle in the
-     * pool, without extra ones being released, or negative for no limit.
-     * This value is used for any username which is not specified
-     * in perUserMaxIdle.  The default is 8.
+     * Gets the user specific value for
+     * {@link GenericObjectPool#getEvictionPolicyClassName()} for the
+     * specified user's pool or the default if no user specific value is defined.
      */
-    public void setDefaultMaxIdle(int defaultMaxIdle) {
-        assertInitializationAllowed();
-        this.defaultMaxIdle = defaultMaxIdle;
+    public String getPerUserEvictionPolicyClassName(String key) {
+        String value = null;
+        if (perUserEvictionPolicyClassName != null) {
+            value = perUserEvictionPolicyClassName.get(key);
+        }
+        if (value == null) {
+            return getDefaultEvictionPolicyClassName();
+        }
+        return value;
     }
 
     /**
-     * The maximum number of milliseconds that the pool will wait (when there
-     * are no available connections) for a connection to be returned before
-     * throwing an exception, or -1 to wait indefinitely.  Will fail
-     * immediately if value is 0.
-     * This value is used for any username which is not specified
-     * in perUserMaxWaitMillis.  The default is -1.
+     * Sets a user specific value for
+     * {@link GenericObjectPool#getEvictionPolicyClassName()} for the specified
+     * user's pool.
      */
-    public int getDefaultMaxWaitMillis() {
-        return (this.defaultMaxWaitMillis);
+    public void setPerUserEvictionPolicyClassName(String username,
+            String value) {
+        assertInitializationAllowed();
+        if (perUserEvictionPolicyClassName == null) {
+            perUserEvictionPolicyClassName = new HashMap<>();
+        }
+        perUserEvictionPolicyClassName.put(username, value);
     }
 
-    /**
-     * The maximum number of milliseconds that the pool will wait (when there
-     * are no available connections) for a connection to be returned before
-     * throwing an exception, or -1 to wait indefinitely.  Will fail
-     * immediately if value is 0.
-     * This value is used for any username which is not specified
-     * in perUserMaxWaitMillis.  The default is -1.
-     */
-    public void setDefaultMaxWaitMillis(int defaultMaxWaitMillis
-            ) {
+    void setPerUserEvictionPolicyClassName(
+            Map<String,String> userDefaultEvictionPolicyClassName) {
         assertInitializationAllowed();
-        this.defaultMaxWaitMillis = defaultMaxWaitMillis;
+        if (perUserEvictionPolicyClassName == null) {
+            perUserEvictionPolicyClassName = new HashMap<>();
+        } else {
+            perUserEvictionPolicyClassName.clear();
+        }
+        perUserEvictionPolicyClassName.putAll(userDefaultEvictionPolicyClassName);
     }
 
+
     /**
-     * The keys are usernames and the value is the --.  Any
-     * username specified here will override the value of defaultAutoCommit.
+     * Gets the user specific value for {@link GenericObjectPool#getLifo()} for
+     * the specified user's pool or the default if no user specific value is
+     * defined.
      */
-    public Boolean getPerUserDefaultAutoCommit(String key) {
+    public boolean getPerUserLifo(String key) {
         Boolean value = null;
-        if (perUserDefaultAutoCommit != null) {
-            value = perUserDefaultAutoCommit.get(key);
+        if (perUserLifo != null) {
+            value = perUserLifo.get(key);
         }
-        return value;
+        if (value == null) {
+            return getDefaultLifo();
+        }
+        return value.booleanValue();
     }
 
     /**
-     * The keys are usernames and the value is the --.  Any
-     * username specified here will override the value of defaultAutoCommit.
+     * Sets a user specific value for
+     * {@link GenericObjectPool#getLifo()} for the specified
+     * user's pool.
      */
-    public void setPerUserDefaultAutoCommit(String username, Boolean value) {
+    public void setPerUserLifo(String username, Boolean value) {
         assertInitializationAllowed();
-        if (perUserDefaultAutoCommit == null) {
-            perUserDefaultAutoCommit = new HashMap<>();
+        if (perUserLifo == null) {
+            perUserLifo = new HashMap<>();
         }
-        perUserDefaultAutoCommit.put(username, value);
+        perUserLifo.put(username, value);
     }
 
-    void setPerUserDefaultAutoCommit(Map<String,Boolean> userDefaultAutoCommit) {
+    void setPerUserLifo(Map<String,Boolean> userDefaultLifo) {
         assertInitializationAllowed();
-        if (perUserDefaultAutoCommit == null) {
-            perUserDefaultAutoCommit = new HashMap<>();
+        if (perUserLifo == null) {
+            perUserLifo = new HashMap<>();
         } else {
-            perUserDefaultAutoCommit.clear();
+            perUserLifo.clear();
         }
-        perUserDefaultAutoCommit.putAll(userDefaultAutoCommit);
+        perUserLifo.putAll(userDefaultLifo);
     }
 
+
     /**
-     * The isolation level of connections when returned from getConnection.
-     * If null, the username will use the value of defaultTransactionIsolation.
+     * Gets the user specific value for
+     * {@link GenericObjectPool#getMaxIdle()} for the
+     * specified user's pool or the default if no user specific value is defined.
      */
-    public Integer getPerUserDefaultTransactionIsolation(String username) {
+    public int getPerUserMaxIdle(String key) {
         Integer value = null;
-        if (perUserDefaultTransactionIsolation != null) {
-            value = perUserDefaultTransactionIsolation.get(username);
+        if (perUserMaxIdle != null) {
+            value = perUserMaxIdle.get(key);
         }
-        return value;
+        if (value == null) {
+            return getDefaultMaxIdle();
+        }
+        return value.intValue();
     }
 
     /**
-     * The isolation level of connections when returned from getConnection.
-     * Valid values are the constants defined in Connection.
+     * Sets a user specific value for
+     * {@link GenericObjectPool#getMaxIdle()} for the specified
+     * user's pool.
      */
-    public void setPerUserDefaultTransactionIsolation(String username,
-                                                      Integer value) {
+    public void setPerUserMaxIdle(String username, Integer value) {
         assertInitializationAllowed();
-        if (perUserDefaultTransactionIsolation == null) {
-            perUserDefaultTransactionIsolation = new HashMap<>();
+        if (perUserMaxIdle == null) {
+            perUserMaxIdle = new HashMap<>();
         }
-        perUserDefaultTransactionIsolation.put(username, value);
+        perUserMaxIdle.put(username, value);
     }
 
-    void setPerUserDefaultTransactionIsolation(
-            Map<String,Integer> userDefaultTransationIsolation) {
+    void setPerUserMaxIdle(Map<String,Integer> userDefaultMaxIdle) {
         assertInitializationAllowed();
-        if (perUserDefaultTransactionIsolation == null) {
-            perUserDefaultTransactionIsolation = new HashMap<>();
+        if (perUserMaxIdle == null) {
+            perUserMaxIdle = new HashMap<>();
         } else {
-            perUserDefaultTransactionIsolation.clear();
+            perUserMaxIdle.clear();
         }
-        perUserDefaultTransactionIsolation.putAll(userDefaultTransationIsolation);
+        perUserMaxIdle.putAll(userDefaultMaxIdle);
     }
 
+
     /**
-     * The maximum number of active connections that can be allocated from
-     * this pool at the same time, or negative for no limit.
-     * The keys are usernames and the value is the maximum connections.  Any
-     * username specified here will override the value of defaultMaxTotal.
+     * Gets the user specific value for
+     * {@link GenericObjectPool#getMaxTotal()} for the
+     * specified user's pool or the default if no user specific value is defined.
      */
-    public Integer getPerUserMaxTotal(String username) {
+    public int getPerUserMaxTotal(String key) {
         Integer value = null;
         if (perUserMaxTotal != null) {
-            value = perUserMaxTotal.get(username);
+            value = perUserMaxTotal.get(key);
         }
-        return value;
+        if (value == null) {
+            return getDefaultMaxTotal();
+        }
+        return value.intValue();
     }
 
     /**
-     * The maximum number of active connections that can be allocated from
-     * this pool at the same time, or negative for no limit.
-     * The keys are usernames and the value is the maximum connections.  Any
-     * username specified here will override the value of defaultMaxTotal.
+     * Sets a user specific value for
+     * {@link GenericObjectPool#getMaxTotal()} for the specified
+     * user's pool.
      */
     public void setPerUserMaxTotal(String username, Integer value) {
         assertInitializationAllowed();
@@ -272,111 +308,440 @@ public class PerUserPoolDataSource exten
         perUserMaxTotal.put(username, value);
     }
 
-    void setPerUserMaxTotal(Map<String,Integer> userMaxTotal) {
+    void setPerUserMaxTotal(Map<String,Integer> userDefaultMaxTotal) {
         assertInitializationAllowed();
         if (perUserMaxTotal == null) {
             perUserMaxTotal = new HashMap<>();
         } else {
             perUserMaxTotal.clear();
         }
-        perUserMaxTotal.putAll(userMaxTotal);
+        perUserMaxTotal.putAll(userDefaultMaxTotal);
     }
 
+
     /**
-     * The maximum number of active connections that can remain idle in the
-     * pool, without extra ones being released, or negative for no limit.
-     * The keys are usernames and the value is the maximum connections.  Any
-     * username specified here will override the value of defaultMaxIdle.
+     * Gets the user specific value for
+     * {@link GenericObjectPool#getMaxWaitMillis()} for the
+     * specified user's pool or the default if no user specific value is defined.
      */
-    public Integer getPerUserMaxIdle(String username) {
+    public long getPerUserMaxWaitMillis(String key) {
+        Long value = null;
+        if (perUserMaxWaitMillis != null) {
+            value = perUserMaxWaitMillis.get(key);
+        }
+        if (value == null) {
+            return getDefaultMaxWaitMillis();
+        }
+        return value.longValue();
+    }
+
+    /**
+     * Sets a user specific value for
+     * {@link GenericObjectPool#getMaxWaitMillis()} for the specified
+     * user's pool.
+     */
+    public void setPerUserMaxWaitMillis(String username, Long value) {
+        assertInitializationAllowed();
+        if (perUserMaxWaitMillis == null) {
+            perUserMaxWaitMillis = new HashMap<>();
+        }
+        perUserMaxWaitMillis.put(username, value);
+    }
+
+    void setPerUserMaxWaitMillis(
+            Map<String,Long> userDefaultMaxWaitMillis) {
+        assertInitializationAllowed();
+        if (perUserMaxWaitMillis == null) {
+            perUserMaxWaitMillis = new HashMap<>();
+        } else {
+            perUserMaxWaitMillis.clear();
+        }
+        perUserMaxWaitMillis.putAll(userDefaultMaxWaitMillis);
+    }
+
+
+    /**
+     * Gets the user specific value for
+     * {@link GenericObjectPool#getMinEvictableIdleTimeMillis()} for the
+     * specified user's pool or the default if no user specific value is defined.
+     */
+    public long getPerUserMinEvictableIdleTimeMillis(String key) {
+        Long value = null;
+        if (perUserMinEvictableIdleTimeMillis != null) {
+            value = perUserMinEvictableIdleTimeMillis.get(key);
+        }
+        if (value == null) {
+            return getDefaultMinEvictableIdleTimeMillis();
+        }
+        return value.longValue();
+    }
+
+    /**
+     * Sets a user specific value for
+     * {@link GenericObjectPool#getMinEvictableIdleTimeMillis()} for the
+     * specified user's pool.
+     */
+    public void setPerUserMinEvictableIdleTimeMillis(String username,
+            Long value) {
+        assertInitializationAllowed();
+        if (perUserMinEvictableIdleTimeMillis == null) {
+            perUserMinEvictableIdleTimeMillis = new HashMap<>();
+        }
+        perUserMinEvictableIdleTimeMillis.put(username, value);
+    }
+
+    void setPerUserMinEvictableIdleTimeMillis(
+            Map<String,Long> userDefaultMinEvictableIdleTimeMillis) {
+        assertInitializationAllowed();
+        if (perUserMinEvictableIdleTimeMillis == null) {
+            perUserMinEvictableIdleTimeMillis = new HashMap<>();
+        } else {
+            perUserMinEvictableIdleTimeMillis.clear();
+        }
+        perUserMinEvictableIdleTimeMillis.putAll(
+                userDefaultMinEvictableIdleTimeMillis);
+    }
+
+
+    /**
+     * Gets the user specific value for
+     * {@link GenericObjectPool#getMinIdle()} for the
+     * specified user's pool or the default if no user specific value is defined.
+     */
+    public int getPerUserMinIdle(String key) {
         Integer value = null;
-        if (perUserMaxIdle != null) {
-            value = perUserMaxIdle.get(username);
+        if (perUserMinIdle != null) {
+            value = perUserMinIdle.get(key);
         }
-        return value;
+        if (value == null) {
+            return getDefaultMinIdle();
+        }
+        return value.intValue();
     }
 
     /**
-     * The maximum number of active connections that can remain idle in the
-     * pool, without extra ones being released, or negative for no limit.
-     * The keys are usernames and the value is the maximum connections.  Any
-     * username specified here will override the value of defaultMaxIdle.
+     * Sets a user specific value for
+     * {@link GenericObjectPool#getMinIdle()} for the specified
+     * user's pool.
      */
-    public void setPerUserMaxIdle(String username, Integer value) {
+    public void setPerUserMinIdle(String username, Integer value) {
         assertInitializationAllowed();
-        if (perUserMaxIdle == null) {
-            perUserMaxIdle = new HashMap<>();
+        if (perUserMinIdle == null) {
+            perUserMinIdle = new HashMap<>();
         }
-        perUserMaxIdle.put(username, value);
+        perUserMinIdle.put(username, value);
     }
 
-    void setPerUserMaxIdle(Map<String,Integer> userMaxIdle) {
+    void setPerUserMinIdle(Map<String,Integer> userDefaultMinIdle) {
         assertInitializationAllowed();
-        if (perUserMaxIdle == null) {
-            perUserMaxIdle = new HashMap<>();
+        if (perUserMinIdle == null) {
+            perUserMinIdle = new HashMap<>();
         } else {
-            perUserMaxIdle.clear();
+            perUserMinIdle.clear();
         }
-        perUserMaxIdle.putAll(userMaxIdle);
+        perUserMinIdle.putAll(userDefaultMinIdle);
     }
 
+
     /**
-     * The maximum number of milliseconds that the pool will wait (when there
-     * are no available connections) for a connection to be returned before
-     * throwing an exception, or -1 to wait indefinitely.  Will fail
-     * immediately if value is 0.
-     * The keys are usernames and the value is the maximum connections.  Any
-     * username specified here will override the value of defaultMaxWaitMillis.
+     * Gets the user specific value for
+     * {@link GenericObjectPool#getNumTestsPerEvictionRun()} for the
+     * specified user's pool or the default if no user specific value is defined.
      */
-    public Integer getPerUserMaxWaitMillis(String username) {
+    public int getPerUserNumTestsPerEvictionRun(String key) {
         Integer value = null;
-        if (perUserMaxWaitMillis != null) {
-            value = perUserMaxWaitMillis.get(username);
+        if (perUserNumTestsPerEvictionRun != null) {
+            value = perUserNumTestsPerEvictionRun.get(key);
+        }
+        if (value == null) {
+            return getDefaultNumTestsPerEvictionRun();
+        }
+        return value.intValue();
+    }
+
+    /**
+     * Sets a user specific value for
+     * {@link GenericObjectPool#getNumTestsPerEvictionRun()} for the specified
+     * user's pool.
+     */
+    public void setPerUserNumTestsPerEvictionRun(String username,
+            Integer value) {
+        assertInitializationAllowed();
+        if (perUserNumTestsPerEvictionRun == null) {
+            perUserNumTestsPerEvictionRun = new HashMap<>();
+        }
+        perUserNumTestsPerEvictionRun.put(username, value);
+    }
+
+    void setPerUserNumTestsPerEvictionRun(
+            Map<String,Integer> userDefaultNumTestsPerEvictionRun) {
+        assertInitializationAllowed();
+        if (perUserNumTestsPerEvictionRun == null) {
+            perUserNumTestsPerEvictionRun = new HashMap<>();
+        } else {
+            perUserNumTestsPerEvictionRun.clear();
+        }
+        perUserNumTestsPerEvictionRun.putAll(userDefaultNumTestsPerEvictionRun);
+    }
+
+
+    /**
+     * Gets the user specific value for
+     * {@link GenericObjectPool#getSoftMinEvictableIdleTimeMillis()} for the
+     * specified user's pool or the default if no user specific value is defined.
+     */
+    public long getPerUserSoftMinEvictableIdleTimeMillis(String key) {
+        Long value = null;
+        if (perUserSoftMinEvictableIdleTimeMillis != null) {
+            value = perUserSoftMinEvictableIdleTimeMillis.get(key);
+        }
+        if (value == null) {
+            return getDefaultSoftMinEvictableIdleTimeMillis();
+        }
+        return value.longValue();
+    }
+
+    /**
+     * Sets a user specific value for
+     * {@link GenericObjectPool#getSoftMinEvictableIdleTimeMillis()} for the
+     * specified user's pool.
+     */
+    public void setPerUserSoftMinEvictableIdleTimeMillis(String username,
+            Long value) {
+        assertInitializationAllowed();
+        if (perUserSoftMinEvictableIdleTimeMillis == null) {
+            perUserSoftMinEvictableIdleTimeMillis = new HashMap<>();
+        }
+        perUserSoftMinEvictableIdleTimeMillis.put(username, value);
+    }
+
+    void setPerUserSoftMinEvictableIdleTimeMillis(
+            Map<String,Long> userDefaultSoftMinEvictableIdleTimeMillis) {
+        assertInitializationAllowed();
+        if (perUserSoftMinEvictableIdleTimeMillis == null) {
+            perUserSoftMinEvictableIdleTimeMillis = new HashMap<>();
+        } else {
+            perUserSoftMinEvictableIdleTimeMillis.clear();
+        }
+        perUserSoftMinEvictableIdleTimeMillis.putAll(userDefaultSoftMinEvictableIdleTimeMillis);
+    }
+
+
+    /**
+     * Gets the user specific value for
+     * {@link GenericObjectPool#getTestOnBorrow()} for the
+     * specified user's pool or the default if no user specific value is defined.
+     */
+    public boolean getPerUserTestOnBorrow(String key) {
+        Boolean value = null;
+        if (perUserTestOnBorrow != null) {
+            value = perUserTestOnBorrow.get(key);
+        }
+        if (value == null) {
+            return getDefaultTestOnBorrow();
+        }
+        return value.booleanValue();
+    }
+
+    /**
+     * Sets a user specific value for
+     * {@link GenericObjectPool#getTestOnBorrow()} for the specified
+     * user's pool.
+     */
+    public void setPerUserTestOnBorrow(String username, Boolean value) {
+        assertInitializationAllowed();
+        if (perUserTestOnBorrow == null) {
+            perUserTestOnBorrow = new HashMap<>();
+        }
+        perUserTestOnBorrow.put(username, value);
+    }
+
+    void setPerUserTestOnBorrow(Map<String,Boolean> userDefaultTestOnBorrow) {
+        assertInitializationAllowed();
+        if (perUserTestOnBorrow == null) {
+            perUserTestOnBorrow = new HashMap<>();
+        } else {
+            perUserTestOnBorrow.clear();
+        }
+        perUserTestOnBorrow.putAll(userDefaultTestOnBorrow);
+    }
+
+
+    /**
+     * Gets the user specific value for
+     * {@link GenericObjectPool#getTestOnReturn()} for the
+     * specified user's pool or the default if no user specific value is defined.
+     */
+    public boolean getPerUserTestOnReturn(String key) {
+        Boolean value = null;
+        if (perUserTestOnReturn != null) {
+            value = perUserTestOnReturn.get(key);
+        }
+        if (value == null) {
+            return getDefaultTestOnReturn();
+        }
+        return value.booleanValue();
+    }
+
+    /**
+     * Sets a user specific value for
+     * {@link GenericObjectPool#getTestOnReturn()} for the specified
+     * user's pool.
+     */
+    public void setPerUserTestOnReturn(String username, Boolean value) {
+        assertInitializationAllowed();
+        if (perUserTestOnReturn == null) {
+            perUserTestOnReturn = new HashMap<>();
+        }
+        perUserTestOnReturn.put(username, value);
+    }
+
+    void setPerUserTestOnReturn(
+            Map<String,Boolean> userDefaultTestOnReturn) {
+        assertInitializationAllowed();
+        if (perUserTestOnReturn == null) {
+            perUserTestOnReturn = new HashMap<>();
+        } else {
+            perUserTestOnReturn.clear();
+        }
+        perUserTestOnReturn.putAll(userDefaultTestOnReturn);
+    }
+
+
+    /**
+     * Gets the user specific value for
+     * {@link GenericObjectPool#getTestWhileIdle()} for the
+     * specified user's pool or the default if no user specific value is defined.
+     */
+    public boolean getPerUserTestWhileIdle(String key) {
+        Boolean value = null;
+        if (perUserTestWhileIdle != null) {
+            value = perUserTestWhileIdle.get(key);
+        }
+        if (value == null) {
+            return getDefaultTestWhileIdle();
+        }
+        return value.booleanValue();
+    }
+
+    /**
+     * Sets a user specific value for
+     * {@link GenericObjectPool#getTestWhileIdle()} for the specified
+     * user's pool.
+     */
+    public void setPerUserTestWhileIdle(String username, Boolean value) {
+        assertInitializationAllowed();
+        if (perUserTestWhileIdle == null) {
+            perUserTestWhileIdle = new HashMap<>();
+        }
+        perUserTestWhileIdle.put(username, value);
+    }
+
+    void setPerUserTestWhileIdle(
+            Map<String,Boolean> userDefaultTestWhileIdle) {
+        assertInitializationAllowed();
+        if (perUserTestWhileIdle == null) {
+            perUserTestWhileIdle = new HashMap<>();
+        } else {
+            perUserTestWhileIdle.clear();
+        }
+        perUserTestWhileIdle.putAll(userDefaultTestWhileIdle);
+    }
+
+
+    /**
+     * Gets the user specific value for
+     * {@link GenericObjectPool#getTimeBetweenEvictionRunsMillis()} for the
+     * specified user's pool or the default if no user specific value is defined.
+     */
+    public long getPerUserTimeBetweenEvictionRunsMillis(String key) {
+        Long value = null;
+        if (perUserTimeBetweenEvictionRunsMillis != null) {
+            value = perUserTimeBetweenEvictionRunsMillis.get(key);
+        }
+        if (value == null) {
+            return getDefaultTimeBetweenEvictionRunsMillis();
+        }
+        return value.longValue();
+    }
+
+    /**
+     * Sets a user specific value for
+     * {@link GenericObjectPool#getTimeBetweenEvictionRunsMillis ()} for the specified
+     * user's pool.
+     */
+    public void setPerUserTimeBetweenEvictionRunsMillis(String username,
+            Long value) {
+        assertInitializationAllowed();
+        if (perUserTimeBetweenEvictionRunsMillis == null) {
+            perUserTimeBetweenEvictionRunsMillis = new HashMap<>();
+        }
+        perUserTimeBetweenEvictionRunsMillis.put(username, value);
+    }
+
+    void setPerUserTimeBetweenEvictionRunsMillis(
+            Map<String,Long> userDefaultTimeBetweenEvictionRunsMillis ) {
+        assertInitializationAllowed();
+        if (perUserTimeBetweenEvictionRunsMillis == null) {
+            perUserTimeBetweenEvictionRunsMillis = new HashMap<>();
+        } else {
+            perUserTimeBetweenEvictionRunsMillis.clear();
+        }
+        perUserTimeBetweenEvictionRunsMillis.putAll(
+                userDefaultTimeBetweenEvictionRunsMillis );
+    }
+
+
+    /**
+     * Gets the user specific default value for
+     * {@link Connection#setAutoCommit(boolean)} for the specified user's pool.
+     */
+    public Boolean getPerUserDefaultAutoCommit(String key) {
+        Boolean value = null;
+        if (perUserDefaultAutoCommit != null) {
+            value = perUserDefaultAutoCommit.get(key);
         }
         return value;
     }
 
     /**
-     * The maximum number of milliseconds that the pool will wait (when there
-     * are no available connections) for a connection to be returned before
-     * throwing an exception, or -1 to wait indefinitely.  Will fail
-     * immediately if value is 0.
-     * The keys are usernames and the value is the maximum connections.  Any
-     * username specified here will override the value of defaultMaxWaitMillis.
+     * Sets a user specific default value for
+     * {@link Connection#setAutoCommit(boolean)} for the specified user's pool.
      */
-    public void setPerUserMaxWaitMillis(String username, Integer value) {
+    public void setPerUserDefaultAutoCommit(String username, Boolean value) {
         assertInitializationAllowed();
-        if (perUserMaxWaitMillis == null) {
-            perUserMaxWaitMillis = new HashMap<>();
+        if (perUserDefaultAutoCommit == null) {
+            perUserDefaultAutoCommit = new HashMap<>();
         }
-        perUserMaxWaitMillis.put(username, value);
+        perUserDefaultAutoCommit.put(username, value);
     }
 
-    void setPerUserMaxWaitMillis(Map<String,Integer> userMaxWaitMillis) {
+    void setPerUserDefaultAutoCommit(Map<String,Boolean> userDefaultAutoCommit) {
         assertInitializationAllowed();
-        if (perUserMaxWaitMillis == null) {
-            perUserMaxWaitMillis = new HashMap<>();
+        if (perUserDefaultAutoCommit == null) {
+            perUserDefaultAutoCommit = new HashMap<>();
         } else {
-            perUserMaxWaitMillis.clear();
+            perUserDefaultAutoCommit.clear();
         }
-        perUserMaxWaitMillis.putAll(userMaxWaitMillis);
+        perUserDefaultAutoCommit.putAll(userDefaultAutoCommit);
     }
 
+
     /**
-     * The keys are usernames and the value is the --.  Any
-     * username specified here will override the value of defaultReadOnly.
+     * Gets the user specific default value for
+     * {@link Connection#setReadOnly(boolean)} for the specified user's pool.
      */
-    public Boolean getPerUserDefaultReadOnly(String username) {
+    public Boolean getPerUserDefaultReadOnly(String key) {
         Boolean value = null;
         if (perUserDefaultReadOnly != null) {
-            value = perUserDefaultReadOnly.get(username);
+            value = perUserDefaultReadOnly.get(key);
         }
         return value;
     }
 
     /**
-     * The keys are usernames and the value is the --.  Any
-     * username specified here will override the value of defaultReadOnly.
+     * Sets a user specific default value for
+     * {@link Connection#setReadOnly(boolean)} for the specified user's pool.
      */
     public void setPerUserDefaultReadOnly(String username, Boolean value) {
         assertInitializationAllowed();
@@ -396,6 +761,44 @@ public class PerUserPoolDataSource exten
         perUserDefaultReadOnly.putAll(userDefaultReadOnly);
     }
 
+
+    /**
+     * Gets the user specific default value for
+     * {@link Connection#setTransactionIsolation(int)} for the specified user's pool.
+     */
+    public Integer getPerUserDefaultTransactionIsolation(String key) {
+        Integer value = null;
+        if (perUserDefaultTransactionIsolation != null) {
+            value = perUserDefaultTransactionIsolation.get(key);
+        }
+        return value;
+    }
+
+    /**
+     * Sets a user specific default value for
+     * {@link Connection#setTransactionIsolation(int)} for the specified user's pool.
+     */
+    public void setPerUserDefaultTransactionIsolation(String username,
+            Integer value) {
+        assertInitializationAllowed();
+        if (perUserDefaultTransactionIsolation == null) {
+            perUserDefaultTransactionIsolation = new HashMap<>();
+        }
+        perUserDefaultTransactionIsolation.put(username, value);
+    }
+
+    void setPerUserDefaultTransactionIsolation(
+            Map<String,Integer> userDefaultTransactionIsolation) {
+        assertInitializationAllowed();
+        if (perUserDefaultTransactionIsolation == null) {
+            perUserDefaultTransactionIsolation = new HashMap<>();
+        } else {
+            perUserDefaultTransactionIsolation.clear();
+        }
+        perUserDefaultTransactionIsolation.putAll(userDefaultTransactionIsolation);
+    }
+
+
     // ----------------------------------------------------------------------
     // Instrumentation Methods
 
@@ -565,22 +968,11 @@ public class PerUserPoolDataSource exten
         return new PoolKey(getDataSourceName(), username);
     }
 
-    private synchronized void registerPool(
-        String username, String password)
-        throws javax.naming.NamingException, SQLException {
+    private synchronized void registerPool(String username, String password)
+            throws NamingException, SQLException {
 
         ConnectionPoolDataSource cpds = testCPDS(username, password);
 
-        Integer userMax = getPerUserMaxTotal(username);
-        int maxTotal = (userMax == null) ?
-            getDefaultMaxTotal() : userMax.intValue();
-        userMax = getPerUserMaxIdle(username);
-        int maxIdle =  (userMax == null) ?
-            getDefaultMaxIdle() : userMax.intValue();
-        userMax = getPerUserMaxWaitMillis(username);
-        int maxWaitMillis = (userMax == null) ?
-            getDefaultMaxWaitMillis() : userMax.intValue();
-
         // Set up the factory we will use (passing the pool associates
         // the factory with the pool, so we do not have to do so
         // explicitly)
@@ -593,30 +985,31 @@ public class PerUserPoolDataSource exten
         GenericObjectPool<PooledConnectionAndInfo> pool =
                 new GenericObjectPool<>(factory);
         factory.setPool(pool);
-        pool.setMaxTotal(maxTotal);
-        pool.setMaxIdle(maxIdle);
-        pool.setMaxWaitMillis(maxWaitMillis);
-        if (maxTotal <= 0) {
-            pool.setBlockWhenExhausted(false);
-            pool.setMaxTotal(Integer.MAX_VALUE);
-        }
-        if (maxWaitMillis == 0) {
-            pool.setBlockWhenExhausted(false);
-        }
-
-        pool.setTestOnBorrow(getTestOnBorrow());
-        pool.setTestOnReturn(getTestOnReturn());
+        pool.setBlockWhenExhausted(getPerUserBlockWhenExhausted(username));
+        pool.setEvictionPolicyClassName(
+                getPerUserEvictionPolicyClassName(username));
+        pool.setLifo(getPerUserLifo(username));
+        pool.setMaxIdle(getPerUserMaxIdle(username));
+        pool.setMaxTotal(getPerUserMaxTotal(username));
+        pool.setMaxWaitMillis(getPerUserMaxWaitMillis(username));
+        pool.setMinEvictableIdleTimeMillis(
+                getPerUserMinEvictableIdleTimeMillis(username));
+        pool.setMinIdle(getPerUserMinIdle(username));
+        pool.setNumTestsPerEvictionRun(
+                getPerUserNumTestsPerEvictionRun(username));
+        pool.setSoftMinEvictableIdleTimeMillis(
+                getPerUserSoftMinEvictableIdleTimeMillis(username));
+        pool.setTestOnBorrow(getPerUserTestOnBorrow(username));
+        pool.setTestOnReturn(getPerUserTestOnReturn(username));
+        pool.setTestWhileIdle(getPerUserTestWhileIdle(username));
         pool.setTimeBetweenEvictionRunsMillis(
-            getTimeBetweenEvictionRunsMillis());
-        pool.setNumTestsPerEvictionRun(getNumTestsPerEvictionRun());
-        pool.setMinEvictableIdleTimeMillis(getMinEvictableIdleTimeMillis());
-        pool.setEvictionPolicyClassName(getEvictionPolicyClassName());
-        pool.setTestWhileIdle(getTestWhileIdle());
+                getPerUserTimeBetweenEvictionRunsMillis(username));
+
         pool.setSwallowedExceptionListener(new SwallowedExceptionLogger(log));
 
         Object old = managers.put(getPoolKey(username,password), factory);
         if (old != null) {
-            throw new IllegalStateException("Pool already contains an entry for this user/password: "+username);
+            throw new IllegalStateException("Pool already contains an entry for this user/password: " + username);
         }
     }
 

Modified: commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/PerUserPoolDataSourceFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/PerUserPoolDataSourceFactory.java?rev=1568055&r1=1568054&r2=1568055&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/PerUserPoolDataSourceFactory.java (original)
+++ commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/PerUserPoolDataSourceFactory.java Thu Feb 13 21:53:12 2014
@@ -5,9 +5,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -25,7 +25,7 @@ import javax.naming.Reference;
 
 /**
  * A JNDI ObjectFactory which creates <code>SharedPoolDataSource</code>s
- * 
+ *
  * @version $Revision$ $Date$
  */
 public class PerUserPoolDataSourceFactory
@@ -39,9 +39,9 @@ public class PerUserPoolDataSourceFactor
         return PER_USER_POOL_CLASSNAME.equals(className);
     }
 
-    @SuppressWarnings("unchecked") // TODO is this needed? If so, why?
+    @SuppressWarnings("unchecked") // Avoid warnings on deserialization
     @Override
-    protected InstanceKeyDataSource getNewInstance(Reference ref) 
+    protected InstanceKeyDataSource getNewInstance(Reference ref)
         throws IOException, ClassNotFoundException {
         PerUserPoolDataSource pupds =  new PerUserPoolDataSource();
         RefAddr ra = ref.get("defaultMaxTotal");
@@ -72,7 +72,7 @@ public class PerUserPoolDataSourceFactor
         ra = ref.get("perUserDefaultTransactionIsolation");
         if (ra != null  && ra.getContent() != null) {
             byte[] serialized = (byte[]) ra.getContent();
-            pupds.setPerUserDefaultTransactionIsolation( 
+            pupds.setPerUserDefaultTransactionIsolation(
                     (Map<String,Integer>) deserialize(serialized));
         }
 
@@ -82,21 +82,21 @@ public class PerUserPoolDataSourceFactor
             pupds.setPerUserMaxTotal(
                     (Map<String,Integer>) deserialize(serialized));
         }
-        
+
         ra = ref.get("perUserMaxIdle");
         if (ra != null  && ra.getContent() != null) {
             byte[] serialized = (byte[]) ra.getContent();
             pupds.setPerUserMaxIdle(
                     (Map<String,Integer>) deserialize(serialized));
         }
-        
+
         ra = ref.get("perUserMaxWaitMillis");
         if (ra != null  && ra.getContent() != null) {
             byte[] serialized = (byte[]) ra.getContent();
             pupds.setPerUserMaxWaitMillis(
-                    (Map<String,Integer>) deserialize(serialized));
+                    (Map<String,Long>) deserialize(serialized));
         }
-                
+
         ra = ref.get("perUserDefaultReadOnly");
         if (ra != null  && ra.getContent() != null) {
             byte[] serialized = (byte[]) ra.getContent();
@@ -104,6 +104,6 @@ public class PerUserPoolDataSourceFactor
                     (Map<String,Boolean>) deserialize(serialized));
         }
         return pupds;
-    }            
+    }
 }
 

Modified: commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/SharedPoolDataSource.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/SharedPoolDataSource.java?rev=1568055&r1=1568054&r2=1568055&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/SharedPoolDataSource.java (original)
+++ commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/SharedPoolDataSource.java Thu Feb 13 21:53:12 2014
@@ -30,7 +30,6 @@ import javax.sql.ConnectionPoolDataSourc
 import org.apache.commons.pool2.KeyedObjectPool;
 import org.apache.commons.pool2.impl.GenericKeyedObjectPool;
 import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;
-import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
 
 /**
  * <p>A pooling <code>DataSource</code> appropriate for deployment within
@@ -49,15 +48,15 @@ import org.apache.commons.pool2.impl.Gen
  * @author John D. McNally
  * @version $Revision$ $Date$
  */
-public class SharedPoolDataSource
-    extends InstanceKeyDataSource {
+public class SharedPoolDataSource extends InstanceKeyDataSource {
 
+    // TODO Re-calculate this
     private static final long serialVersionUID = -8132305535403690372L;
 
-    private int maxTotal = GenericObjectPoolConfig.DEFAULT_MAX_TOTAL;
-    private int maxIdle = GenericObjectPoolConfig.DEFAULT_MAX_IDLE;
-    private int maxWaitMillis = (int)Math.min(Integer.MAX_VALUE,
-            GenericObjectPoolConfig.DEFAULT_MAX_WAIT_MILLIS);
+    // Pool properties
+    private int maxTotal = GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL;
+
+
     private transient KeyedObjectPool<UserPassKey,PooledConnectionAndInfo> pool = null;
     private transient KeyedCPDSConnectionFactory factory = null;
 
@@ -78,67 +77,25 @@ public class SharedPoolDataSource
         InstanceKeyDataSourceFactory.removeInstance(getInstanceKey());
     }
 
+
     // -------------------------------------------------------------------
     // Properties
 
     /**
-     * The maximum number of active connections that can be allocated from
-     * this pool at the same time, or negative for no limit.
+     * Set {@link GenericKeyedObjectPool#getMaxTotal()} for this pool.
      */
     public int getMaxTotal() {
         return (this.maxTotal);
     }
 
     /**
-     * The maximum number of active connections that can be allocated from
-     * this pool at the same time, or negative for no limit.
-     * The default is 8.
+     * Get {@link GenericKeyedObjectPool#getMaxTotal()} for this pool.
      */
     public void setMaxTotal(int maxTotal) {
         assertInitializationAllowed();
         this.maxTotal = maxTotal;
     }
 
-    /**
-     * The maximum number of active connections that can remain idle in the
-     * pool, without extra ones being released, or negative for no limit.
-     */
-    public int getMaxIdle() {
-        return (this.maxIdle);
-    }
-
-    /**
-     * The maximum number of active connections that can remain idle in the
-     * pool, without extra ones being released, or negative for no limit.
-     * The default is 8.
-     */
-    public void setMaxIdle(int maxIdle) {
-        assertInitializationAllowed();
-        this.maxIdle = maxIdle;
-    }
-
-    /**
-     * The maximum number of milliseconds that the pool will wait (when there
-     * are no available connections) for a connection to be returned before
-     * throwing an exception, or -1 to wait indefinitely.  Will fail
-     * immediately if value is 0.
-     * The default is -1.
-     */
-    public int getMaxWaitMillis() {
-        return (this.maxWaitMillis);
-    }
-
-    /**
-     * The maximum number of milliseconds that the pool will wait (when there
-     * are no available connections) for a connection to be returned before
-     * throwing an exception, or -1 to wait indefinitely.  Will fail
-     * immediately if value is 0.
-     * The default is -1.
-     */
-    public void setMaxWaitMillis(int maxWaitMillis) {
-        assertInitializationAllowed();
-        this.maxWaitMillis = maxWaitMillis;
-    }
 
     // ----------------------------------------------------------------------
     // Instrumentation Methods
@@ -217,26 +174,28 @@ public class SharedPoolDataSource
         factory = new KeyedCPDSConnectionFactory(cpds, getValidationQuery(),
                 isRollbackAfterValidation());
         factory.setMaxConnLifetimeMillis(getMaxConnLifetimeMillis());
-        GenericKeyedObjectPoolConfig config = new GenericKeyedObjectPoolConfig();
-        config.setMaxTotalPerKey(getMaxTotal());
-        config.setMaxIdlePerKey(getMaxIdle());
-        config.setMaxWaitMillis(getMaxWaitMillis());
-        config.setBlockWhenExhausted(true);
-        if (maxTotal <= 0) {
-            config.setBlockWhenExhausted(false);
-            config.setMaxTotalPerKey(Integer.MAX_VALUE);
-        }
-        if (maxWaitMillis == 0) {
-            config.setBlockWhenExhausted(false);
-        }
-        config.setTestOnBorrow(getTestOnBorrow());
-        config.setTestOnReturn(getTestOnReturn());
+
+        GenericKeyedObjectPoolConfig config =
+                new GenericKeyedObjectPoolConfig();
+        config.setBlockWhenExhausted(getDefaultBlockWhenExhausted());
+        config.setEvictionPolicyClassName(getDefaultEvictionPolicyClassName());
+        config.setLifo(getDefaultLifo());
+        config.setMaxIdlePerKey(getDefaultMaxIdle());
+        config.setMaxTotal(getMaxTotal());
+        config.setMaxTotalPerKey(getDefaultMaxTotal());
+        config.setMaxWaitMillis(getDefaultMaxWaitMillis());
+        config.setMinEvictableIdleTimeMillis(
+                getDefaultMinEvictableIdleTimeMillis());
+        config.setMinIdlePerKey(getDefaultMinIdle());
+        config.setNumTestsPerEvictionRun(getDefaultNumTestsPerEvictionRun());
+        config.setSoftMinEvictableIdleTimeMillis(
+                getDefaultSoftMinEvictableIdleTimeMillis());
+        config.setTestOnBorrow(getDefaultTestOnBorrow());
+        config.setTestOnReturn(getDefaultTestOnReturn());
+        config.setTestWhileIdle(getDefaultTestWhileIdle());
         config.setTimeBetweenEvictionRunsMillis(
-            getTimeBetweenEvictionRunsMillis());
-        config.setNumTestsPerEvictionRun(getNumTestsPerEvictionRun());
-        config.setMinEvictableIdleTimeMillis(getMinEvictableIdleTimeMillis());
-        config.setEvictionPolicyClassName(getEvictionPolicyClassName());
-        config.setTestWhileIdle(getTestWhileIdle());
+                getDefaultTimeBetweenEvictionRunsMillis());
+
         KeyedObjectPool<UserPassKey,PooledConnectionAndInfo> tmpPool =
                 new GenericKeyedObjectPool<>(factory, config);
         factory.setPool(tmpPool);

Modified: commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/SharedPoolDataSourceFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/SharedPoolDataSourceFactory.java?rev=1568055&r1=1568054&r2=1568055&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/SharedPoolDataSourceFactory.java (original)
+++ commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2/datasources/SharedPoolDataSourceFactory.java Thu Feb 13 21:53:12 2014
@@ -5,9 +5,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -38,25 +38,12 @@ public class SharedPoolDataSourceFactory
     @Override
     protected InstanceKeyDataSource getNewInstance(Reference ref) {
         SharedPoolDataSource spds = new SharedPoolDataSource();
-        RefAddr ra = ref.get("maxActive");
+        RefAddr ra = ref.get("maxTotal");
         if (ra != null && ra.getContent() != null) {
             spds.setMaxTotal(
                 Integer.parseInt(ra.getContent().toString()));
         }
-
-        ra = ref.get("maxIdle");
-        if (ra != null && ra.getContent() != null) {
-            spds.setMaxIdle(
-                Integer.parseInt(ra.getContent().toString()));
-        }
-
-        ra = ref.get("maxWaitMillis");
-        if (ra != null && ra.getContent() != null) {
-            spds.setMaxWaitMillis(
-                Integer.parseInt(ra.getContent().toString()));
-        }
-        
         return spds;
-    }            
+    }
 }
 

Modified: commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/cpdsadapter/TestDriverAdapterCPDS.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/cpdsadapter/TestDriverAdapterCPDS.java?rev=1568055&r1=1568054&r2=1568055&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/cpdsadapter/TestDriverAdapterCPDS.java (original)
+++ commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/cpdsadapter/TestDriverAdapterCPDS.java Thu Feb 13 21:53:12 2014
@@ -174,16 +174,16 @@ public class TestDriverAdapterCPDS exten
         SharedPoolDataSource spds = new SharedPoolDataSource();
         spds.setConnectionPoolDataSource(pcds);
         spds.setMaxTotal(threads.length + 10);
-        spds.setMaxWaitMillis(-1);
-        spds.setMaxIdle(10);
+        spds.setDefaultMaxWaitMillis(-1);
+        spds.setDefaultMaxIdle(10);
         spds.setDefaultAutoCommit(Boolean.FALSE);
 
         spds.setValidationQuery("SELECT 1");
-        spds.setTimeBetweenEvictionRunsMillis(10000);
-        spds.setNumTestsPerEvictionRun(-1);
-        spds.setTestWhileIdle(true);
-        spds.setTestOnBorrow(true);
-        spds.setTestOnReturn(false);
+        spds.setDefaultTimeBetweenEvictionRunsMillis(10000);
+        spds.setDefaultNumTestsPerEvictionRun(-1);
+        spds.setDefaultTestWhileIdle(true);
+        spds.setDefaultTestOnBorrow(true);
+        spds.setDefaultTestOnReturn(false);
 
         for (int i = 0; i < threads.length; i++) {
             threads[i] = new ThreadDbcp367(spds);

Modified: commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestCPDSConnectionFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestCPDSConnectionFactory.java?rev=1568055&r1=1568054&r2=1568055&view=diff
==============================================================================
--- commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestCPDSConnectionFactory.java (original)
+++ commons/proper/dbcp/trunk/src/test/java/org/apache/commons/dbcp2/datasources/TestCPDSConnectionFactory.java Thu Feb 13 21:53:12 2014
@@ -66,7 +66,7 @@ public class TestCPDSConnectionFactory e
        PerUserPoolDataSource ds = new PerUserPoolDataSource();
        ds.setConnectionPoolDataSource(cpds);
        ds.setPerUserMaxTotal("username", Integer.valueOf(10));
-       ds.setPerUserMaxWaitMillis("username", Integer.valueOf(50));
+       ds.setPerUserMaxWaitMillis("username", Long.valueOf(50));
        ds.setPerUserMaxIdle("username", Integer.valueOf(2));
        Connection conn1 = ds.getConnection("username", "password");
        Connection conn2 = ds.getConnection("username", "password");