Modified: tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PerUserPoolDataSource.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PerUserPoolDataSource.java?rev=1833816&r1=1833815&r2=1833816&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PerUserPoolDataSource.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PerUserPoolDataSource.java Tue Jun 19 11:21:13 2018 @@ -36,94 +36,167 @@ import org.apache.tomcat.dbcp.pool2.Obje import org.apache.tomcat.dbcp.pool2.impl.GenericObjectPool; /** - * <p>A pooling <code>DataSource</code> appropriate for deployment within - * J2EE environment. There are many configuration options, most of which are - * defined in the parent class. This datasource uses individual pools per - * user, and some properties can be set specifically for a given user, if the - * deployment environment can support initialization of mapped properties. - * So for example, a pool of admin or write-access Connections can be - * guaranteed a certain number of connections, separate from a maximum - * set for users with read-only connections.</p> + * <p> + * A pooling <code>DataSource</code> appropriate for deployment within J2EE environment. There are many configuration + * options, most of which are defined in the parent class. This datasource uses individual pools per user, and some + * properties can be set specifically for a given user, if the deployment environment can support initialization of + * mapped properties. So for example, a pool of admin or write-access Connections can be guaranteed a certain number of + * connections, separate from a maximum set for users with read-only connections. + * </p> * - * <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> + * <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> * - * @author John D. McNally * @since 2.0 */ public class PerUserPoolDataSource extends InstanceKeyDataSource { private static final long serialVersionUID = 7872747993848065028L; - private static final Log log = - LogFactory.getLog(PerUserPoolDataSource.class); + private static final Log log = LogFactory.getLog(PerUserPoolDataSource.class); // 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> perUserTestOnCreate = 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; + private Map<String, Boolean> perUserBlockWhenExhausted; + private Map<String, String> perUserEvictionPolicyClassName; + private Map<String, Boolean> perUserLifo; + private Map<String, Integer> perUserMaxIdle; + private Map<String, Integer> perUserMaxTotal; + private Map<String, Long> perUserMaxWaitMillis; + private Map<String, Long> perUserMinEvictableIdleTimeMillis; + private Map<String, Integer> perUserMinIdle; + private Map<String, Integer> perUserNumTestsPerEvictionRun; + private Map<String, Long> perUserSoftMinEvictableIdleTimeMillis; + private Map<String, Boolean> perUserTestOnCreate; + private Map<String, Boolean> perUserTestOnBorrow; + private Map<String, Boolean> perUserTestOnReturn; + private Map<String, Boolean> perUserTestWhileIdle; + private Map<String, Long> perUserTimeBetweenEvictionRunsMillis; // Per user connection properties - private Map<String,Boolean> perUserDefaultAutoCommit = null; - private Map<String,Integer> perUserDefaultTransactionIsolation = null; - private Map<String,Boolean> perUserDefaultReadOnly = null; + private Map<String, Boolean> perUserDefaultAutoCommit; + private Map<String, Integer> perUserDefaultTransactionIsolation; + private Map<String, Boolean> perUserDefaultReadOnly; /** - * Map to keep track of Pools for a given user + * Map to keep track of Pools for a given user. */ - private transient Map<PoolKey, PooledConnectionManager> managers = - new HashMap<>(); + private transient Map<PoolKey, PooledConnectionManager> managers = new HashMap<>(); /** - * Default no-arg constructor for Serialization + * Default no-arg constructor for Serialization. */ public PerUserPoolDataSource() { } /** - * Close pool(s) being maintained by this datasource. + * Clears pool(s) maintained by this data source. + * + * @see org.apache.tomcat.dbcp.pool2.ObjectPool#clear() + * @since 2.3.0 + */ + public void clear() { + for (final PooledConnectionManager manager : managers.values()) { + try { + getCPDSConnectionFactoryPool(manager).clear(); + } catch (final Exception closePoolException) { + // ignore and try to close others. + } + } + InstanceKeyDataSourceFactory.removeInstance(getInstanceKey()); + } + + /** + * Closes pool(s) maintained by this data source. + * + * @see org.apache.tomcat.dbcp.pool2.ObjectPool#close() */ @Override public void close() { for (final PooledConnectionManager manager : managers.values()) { try { - ((CPDSConnectionFactory) manager).getPool().close(); + getCPDSConnectionFactoryPool(manager).close(); } catch (final Exception closePoolException) { - //ignore and try to close others. + // ignore and try to close others. } } InstanceKeyDataSourceFactory.removeInstance(getInstanceKey()); } - // ------------------------------------------------------------------- - // Properties + private HashMap<String, Boolean> createMap() { + // Should there be a default size different than what this ctor provides? + return new HashMap<>(); + } + + @Override + protected PooledConnectionManager getConnectionManager(final UserPassKey upKey) { + return managers.get(getPoolKey(upKey.getUsername())); + } + + private ObjectPool<PooledConnectionAndInfo> getCPDSConnectionFactoryPool(final PooledConnectionManager manager) { + return ((CPDSConnectionFactory) manager).getPool(); + } + + /** + * Gets the number of active connections in the default pool. + * + * @return The number of active connections in the default pool. + */ + public int getNumActive() { + return getNumActive(null); + } + + /** + * Gets the number of active connections in the pool for a given user. + * + * @param userName + * The user name key. + * @return The user specific value. + */ + @SuppressWarnings("resource") + public int getNumActive(final String userName) { + final ObjectPool<PooledConnectionAndInfo> pool = getPool(getPoolKey(userName)); + return pool == null ? 0 : pool.getNumActive(); + } + + /** + * Gets the number of idle connections in the default pool. + * + * @return The number of idle connections in the default pool. + */ + public int getNumIdle() { + return getNumIdle(null); + } + + /** + * Gets the number of idle connections in the pool for a given user. + * + * @param userName + * The user name key. + * @return The user specific value. + */ + @SuppressWarnings("resource") + public int getNumIdle(final String userName) { + final ObjectPool<PooledConnectionAndInfo> pool = getPool(getPoolKey(userName)); + return pool == null ? 0 : pool.getNumIdle(); + } /** - * 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. + * 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. + * + * @param userName + * The user name key. + * @return The user specific value. */ - public boolean getPerUserBlockWhenExhausted(final String key) { + public boolean getPerUserBlockWhenExhausted(final String userName) { Boolean value = null; if (perUserBlockWhenExhausted != null) { - value = perUserBlockWhenExhausted.get(key); + value = perUserBlockWhenExhausted.get(userName); } if (value == null) { return getDefaultBlockWhenExhausted(); @@ -132,82 +205,82 @@ public class PerUserPoolDataSource exten } /** - * Sets a user specific value for - * {@link GenericObjectPool#getBlockWhenExhausted()} for the specified - * user's pool. + * Gets the user specific default value for {@link Connection#setAutoCommit(boolean)} for the specified user's pool. + * + * @param userName + * The user name key. + * @return The user specific value. */ - public void setPerUserBlockWhenExhausted(final String username, - final Boolean value) { - assertInitializationAllowed(); - if (perUserBlockWhenExhausted == null) { - perUserBlockWhenExhausted = new HashMap<>(); + public Boolean getPerUserDefaultAutoCommit(final String userName) { + Boolean value = null; + if (perUserDefaultAutoCommit != null) { + value = perUserDefaultAutoCommit.get(userName); } - perUserBlockWhenExhausted.put(username, value); + return value; } - void setPerUserBlockWhenExhausted( - final Map<String,Boolean> userDefaultBlockWhenExhausted) { - assertInitializationAllowed(); - if (perUserBlockWhenExhausted == null) { - perUserBlockWhenExhausted = new HashMap<>(); - } else { - perUserBlockWhenExhausted.clear(); + /** + * Gets the user specific default value for {@link Connection#setReadOnly(boolean)} for the specified user's pool. + * + * @param userName + * The user name key. + * @return The user specific value. + */ + public Boolean getPerUserDefaultReadOnly(final String userName) { + Boolean value = null; + if (perUserDefaultReadOnly != null) { + value = perUserDefaultReadOnly.get(userName); } - perUserBlockWhenExhausted.putAll(userDefaultBlockWhenExhausted); + return value; } - /** - * 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. + * Gets the user specific default value for {@link Connection#setTransactionIsolation(int)} for the specified user's + * pool. + * + * @param userName + * The user name key. + * @return The user specific value. */ - public String getPerUserEvictionPolicyClassName(final String key) { - String value = null; - if (perUserEvictionPolicyClassName != null) { - value = perUserEvictionPolicyClassName.get(key); - } - if (value == null) { - return getDefaultEvictionPolicyClassName(); + public Integer getPerUserDefaultTransactionIsolation(final String userName) { + Integer value = null; + if (perUserDefaultTransactionIsolation != null) { + value = perUserDefaultTransactionIsolation.get(userName); } return value; } /** - * Sets a user specific value for - * {@link GenericObjectPool#getEvictionPolicyClassName()} for the specified - * user's pool. + * 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. + * + * @param userName + * The user name key. + * @return The user specific value. */ - public void setPerUserEvictionPolicyClassName(final String username, - final String value) { - assertInitializationAllowed(); - if (perUserEvictionPolicyClassName == null) { - perUserEvictionPolicyClassName = new HashMap<>(); + public String getPerUserEvictionPolicyClassName(final String userName) { + String value = null; + if (perUserEvictionPolicyClassName != null) { + value = perUserEvictionPolicyClassName.get(userName); } - perUserEvictionPolicyClassName.put(username, value); - } - - void setPerUserEvictionPolicyClassName( - final Map<String,String> userDefaultEvictionPolicyClassName) { - assertInitializationAllowed(); - if (perUserEvictionPolicyClassName == null) { - perUserEvictionPolicyClassName = new HashMap<>(); - } else { - perUserEvictionPolicyClassName.clear(); + if (value == null) { + return getDefaultEvictionPolicyClassName(); } - perUserEvictionPolicyClassName.putAll(userDefaultEvictionPolicyClassName); + return value; } - /** - * 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. + * 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. + * + * @param userName + * The user name key. + * @return The user specific value. */ - public boolean getPerUserLifo(final String key) { + public boolean getPerUserLifo(final String userName) { Boolean value = null; if (perUserLifo != null) { - value = perUserLifo.get(key); + value = perUserLifo.get(userName); } if (value == null) { return getDefaultLifo(); @@ -216,38 +289,17 @@ public class PerUserPoolDataSource exten } /** - * Sets a user specific value for - * {@link GenericObjectPool#getLifo()} for the specified - * user's pool. - */ - public void setPerUserLifo(final String username, final Boolean value) { - assertInitializationAllowed(); - if (perUserLifo == null) { - perUserLifo = new HashMap<>(); - } - perUserLifo.put(username, value); - } - - void setPerUserLifo(final Map<String,Boolean> userDefaultLifo) { - assertInitializationAllowed(); - if (perUserLifo == null) { - perUserLifo = new HashMap<>(); - } else { - perUserLifo.clear(); - } - perUserLifo.putAll(userDefaultLifo); - } - - - /** - * 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. + * 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. + * + * @param userName + * The user name key. + * @return The user specific value. */ - public int getPerUserMaxIdle(final String key) { + public int getPerUserMaxIdle(final String userName) { Integer value = null; if (perUserMaxIdle != null) { - value = perUserMaxIdle.get(key); + value = perUserMaxIdle.get(userName); } if (value == null) { return getDefaultMaxIdle(); @@ -256,38 +308,17 @@ public class PerUserPoolDataSource exten } /** - * Sets a user specific value for - * {@link GenericObjectPool#getMaxIdle()} for the specified - * user's pool. - */ - public void setPerUserMaxIdle(final String username, final Integer value) { - assertInitializationAllowed(); - if (perUserMaxIdle == null) { - perUserMaxIdle = new HashMap<>(); - } - perUserMaxIdle.put(username, value); - } - - void setPerUserMaxIdle(final Map<String,Integer> userDefaultMaxIdle) { - assertInitializationAllowed(); - if (perUserMaxIdle == null) { - perUserMaxIdle = new HashMap<>(); - } else { - perUserMaxIdle.clear(); - } - perUserMaxIdle.putAll(userDefaultMaxIdle); - } - - - /** - * 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. + * 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. + * + * @param userName + * The user name key. + * @return The user specific value. */ - public int getPerUserMaxTotal(final String key) { + public int getPerUserMaxTotal(final String userName) { Integer value = null; if (perUserMaxTotal != null) { - value = perUserMaxTotal.get(key); + value = perUserMaxTotal.get(userName); } if (value == null) { return getDefaultMaxTotal(); @@ -296,38 +327,17 @@ public class PerUserPoolDataSource exten } /** - * Sets a user specific value for - * {@link GenericObjectPool#getMaxTotal()} for the specified - * user's pool. - */ - public void setPerUserMaxTotal(final String username, final Integer value) { - assertInitializationAllowed(); - if (perUserMaxTotal == null) { - perUserMaxTotal = new HashMap<>(); - } - perUserMaxTotal.put(username, value); - } - - void setPerUserMaxTotal(final Map<String,Integer> userDefaultMaxTotal) { - assertInitializationAllowed(); - if (perUserMaxTotal == null) { - perUserMaxTotal = new HashMap<>(); - } else { - perUserMaxTotal.clear(); - } - perUserMaxTotal.putAll(userDefaultMaxTotal); - } - - - /** - * 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. + * 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. + * + * @param userName + * The user name key. + * @return The user specific value. */ - public long getPerUserMaxWaitMillis(final String key) { + public long getPerUserMaxWaitMillis(final String userName) { Long value = null; if (perUserMaxWaitMillis != null) { - value = perUserMaxWaitMillis.get(key); + value = perUserMaxWaitMillis.get(userName); } if (value == null) { return getDefaultMaxWaitMillis(); @@ -336,39 +346,17 @@ public class PerUserPoolDataSource exten } /** - * Sets a user specific value for - * {@link GenericObjectPool#getMaxWaitMillis()} for the specified - * user's pool. - */ - public void setPerUserMaxWaitMillis(final String username, final Long value) { - assertInitializationAllowed(); - if (perUserMaxWaitMillis == null) { - perUserMaxWaitMillis = new HashMap<>(); - } - perUserMaxWaitMillis.put(username, value); - } - - void setPerUserMaxWaitMillis( - final 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. + * 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. + * + * @param userName + * The user name key. + * @return The user specific value. */ - public long getPerUserMinEvictableIdleTimeMillis(final String key) { + public long getPerUserMinEvictableIdleTimeMillis(final String userName) { Long value = null; if (perUserMinEvictableIdleTimeMillis != null) { - value = perUserMinEvictableIdleTimeMillis.get(key); + value = perUserMinEvictableIdleTimeMillis.get(userName); } if (value == null) { return getDefaultMinEvictableIdleTimeMillis(); @@ -377,41 +365,17 @@ public class PerUserPoolDataSource exten } /** - * Sets a user specific value for - * {@link GenericObjectPool#getMinEvictableIdleTimeMillis()} for the - * specified user's pool. - */ - public void setPerUserMinEvictableIdleTimeMillis(final String username, - final Long value) { - assertInitializationAllowed(); - if (perUserMinEvictableIdleTimeMillis == null) { - perUserMinEvictableIdleTimeMillis = new HashMap<>(); - } - perUserMinEvictableIdleTimeMillis.put(username, value); - } - - void setPerUserMinEvictableIdleTimeMillis( - final 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. + * 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. + * + * @param userName + * The user name key. + * @return The user specific value. */ - public int getPerUserMinIdle(final String key) { + public int getPerUserMinIdle(final String userName) { Integer value = null; if (perUserMinIdle != null) { - value = perUserMinIdle.get(key); + value = perUserMinIdle.get(userName); } if (value == null) { return getDefaultMinIdle(); @@ -420,38 +384,17 @@ public class PerUserPoolDataSource exten } /** - * Sets a user specific value for - * {@link GenericObjectPool#getMinIdle()} for the specified - * user's pool. - */ - public void setPerUserMinIdle(final String username, final Integer value) { - assertInitializationAllowed(); - if (perUserMinIdle == null) { - perUserMinIdle = new HashMap<>(); - } - perUserMinIdle.put(username, value); - } - - void setPerUserMinIdle(final Map<String,Integer> userDefaultMinIdle) { - assertInitializationAllowed(); - if (perUserMinIdle == null) { - perUserMinIdle = new HashMap<>(); - } else { - perUserMinIdle.clear(); - } - perUserMinIdle.putAll(userDefaultMinIdle); - } - - - /** - * 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. + * 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. + * + * @param userName + * The user name key. + * @return The user specific value. */ - public int getPerUserNumTestsPerEvictionRun(final String key) { + public int getPerUserNumTestsPerEvictionRun(final String userName) { Integer value = null; if (perUserNumTestsPerEvictionRun != null) { - value = perUserNumTestsPerEvictionRun.get(key); + value = perUserNumTestsPerEvictionRun.get(userName); } if (value == null) { return getDefaultNumTestsPerEvictionRun(); @@ -460,40 +403,17 @@ public class PerUserPoolDataSource exten } /** - * Sets a user specific value for - * {@link GenericObjectPool#getNumTestsPerEvictionRun()} for the specified - * user's pool. - */ - public void setPerUserNumTestsPerEvictionRun(final String username, - final Integer value) { - assertInitializationAllowed(); - if (perUserNumTestsPerEvictionRun == null) { - perUserNumTestsPerEvictionRun = new HashMap<>(); - } - perUserNumTestsPerEvictionRun.put(username, value); - } - - void setPerUserNumTestsPerEvictionRun( - final 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. + * 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. + * + * @param userName + * The user name key. + * @return The user specific value. */ - public long getPerUserSoftMinEvictableIdleTimeMillis(final String key) { + public long getPerUserSoftMinEvictableIdleTimeMillis(final String userName) { Long value = null; if (perUserSoftMinEvictableIdleTimeMillis != null) { - value = perUserSoftMinEvictableIdleTimeMillis.get(key); + value = perUserSoftMinEvictableIdleTimeMillis.get(userName); } if (value == null) { return getDefaultSoftMinEvictableIdleTimeMillis(); @@ -502,40 +422,36 @@ public class PerUserPoolDataSource exten } /** - * Sets a user specific value for - * {@link GenericObjectPool#getSoftMinEvictableIdleTimeMillis()} for the - * specified user's pool. + * 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. + * + * @param userName + * The user name key. + * @return The user specific value. */ - public void setPerUserSoftMinEvictableIdleTimeMillis(final String username, - final Long value) { - assertInitializationAllowed(); - if (perUserSoftMinEvictableIdleTimeMillis == null) { - perUserSoftMinEvictableIdleTimeMillis = new HashMap<>(); + public boolean getPerUserTestOnBorrow(final String userName) { + Boolean value = null; + if (perUserTestOnBorrow != null) { + value = perUserTestOnBorrow.get(userName); } - perUserSoftMinEvictableIdleTimeMillis.put(username, value); - } - - void setPerUserSoftMinEvictableIdleTimeMillis( - final Map<String,Long> userDefaultSoftMinEvictableIdleTimeMillis) { - assertInitializationAllowed(); - if (perUserSoftMinEvictableIdleTimeMillis == null) { - perUserSoftMinEvictableIdleTimeMillis = new HashMap<>(); - } else { - perUserSoftMinEvictableIdleTimeMillis.clear(); + if (value == null) { + return getDefaultTestOnBorrow(); } - perUserSoftMinEvictableIdleTimeMillis.putAll(userDefaultSoftMinEvictableIdleTimeMillis); + return value.booleanValue(); } - /** - * Gets the user specific value for - * {@link GenericObjectPool#getTestOnCreate()} for the - * specified user's pool or the default if no user specific value is defined. + * Gets the user specific value for {@link GenericObjectPool#getTestOnCreate()} for the specified user's pool or the + * default if no user specific value is defined. + * + * @param userName + * The user name key. + * @return The user specific value. */ - public boolean getPerUserTestOnCreate(final String key) { + public boolean getPerUserTestOnCreate(final String userName) { Boolean value = null; if (perUserTestOnCreate != null) { - value = perUserTestOnCreate.get(key); + value = perUserTestOnCreate.get(userName); } if (value == null) { return getDefaultTestOnCreate(); @@ -544,427 +460,708 @@ public class PerUserPoolDataSource exten } /** - * Sets a user specific value for - * {@link GenericObjectPool#getTestOnCreate()} for the specified - * user's pool. + * 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. + * + * @param userName + * The user name key. + * @return The user specific value. */ - public void setPerUserTestOnCreate(final String username, final Boolean value) { - assertInitializationAllowed(); - if (perUserTestOnCreate == null) { - perUserTestOnCreate = new HashMap<>(); + public boolean getPerUserTestOnReturn(final String userName) { + Boolean value = null; + if (perUserTestOnReturn != null) { + value = perUserTestOnReturn.get(userName); + } + if (value == null) { + return getDefaultTestOnReturn(); } - perUserTestOnCreate.put(username, value); + return value.booleanValue(); } - void setPerUserTestOnCreate(final Map<String,Boolean> userDefaultTestOnCreate) { - assertInitializationAllowed(); - if (perUserTestOnCreate == null) { - perUserTestOnCreate = new HashMap<>(); - } else { - perUserTestOnCreate.clear(); - } - perUserTestOnCreate.putAll(userDefaultTestOnCreate); - } - - /** - * 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. + * 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. + * + * @param userName + * The user name key. + * @return The user specific value. */ - public boolean getPerUserTestOnBorrow(final String key) { + public boolean getPerUserTestWhileIdle(final String userName) { Boolean value = null; - if (perUserTestOnBorrow != null) { - value = perUserTestOnBorrow.get(key); + if (perUserTestWhileIdle != null) { + value = perUserTestWhileIdle.get(userName); } if (value == null) { - return getDefaultTestOnBorrow(); + return getDefaultTestWhileIdle(); } return value.booleanValue(); } /** - * Sets a user specific value for - * {@link GenericObjectPool#getTestOnBorrow()} for the specified - * user's pool. + * 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. + * + * @param userName + * The user name key. + * @return The user specific value. */ - public void setPerUserTestOnBorrow(final String username, final Boolean value) { - assertInitializationAllowed(); - if (perUserTestOnBorrow == null) { - perUserTestOnBorrow = new HashMap<>(); + public long getPerUserTimeBetweenEvictionRunsMillis(final String userName) { + Long value = null; + if (perUserTimeBetweenEvictionRunsMillis != null) { + value = perUserTimeBetweenEvictionRunsMillis.get(userName); + } + if (value == null) { + return getDefaultTimeBetweenEvictionRunsMillis(); } - perUserTestOnBorrow.put(username, value); + return value.longValue(); } - void setPerUserTestOnBorrow(final Map<String,Boolean> userDefaultTestOnBorrow) { - assertInitializationAllowed(); - if (perUserTestOnBorrow == null) { - perUserTestOnBorrow = new HashMap<>(); - } else { - perUserTestOnBorrow.clear(); + /** + * Returns the object pool associated with the given PoolKey. + * + * @param poolKey + * PoolKey identifying the pool + * @return the GenericObjectPool pooling connections for the userName and datasource specified by the PoolKey + */ + private ObjectPool<PooledConnectionAndInfo> getPool(final PoolKey poolKey) { + final CPDSConnectionFactory mgr = (CPDSConnectionFactory) managers.get(poolKey); + return mgr == null ? null : mgr.getPool(); + } + + @Override + protected PooledConnectionAndInfo getPooledConnectionAndInfo(final String userName, final String password) + throws SQLException { + + final PoolKey key = getPoolKey(userName); + ObjectPool<PooledConnectionAndInfo> pool; + PooledConnectionManager manager; + synchronized (this) { + manager = managers.get(key); + if (manager == null) { + try { + registerPool(userName, password); + manager = managers.get(key); + } catch (final NamingException e) { + throw new SQLException("RegisterPool failed", e); + } + } + pool = getCPDSConnectionFactoryPool(manager); } - perUserTestOnBorrow.putAll(userDefaultTestOnBorrow); + + PooledConnectionAndInfo info = null; + try { + info = pool.borrowObject(); + } catch (final NoSuchElementException ex) { + throw new SQLException("Could not retrieve connection info from pool", ex); + } catch (final Exception e) { + // See if failure is due to CPDSConnectionFactory authentication failure + try { + testCPDS(userName, password); + } catch (final Exception ex) { + throw new SQLException("Could not retrieve connection info from pool", ex); + } + // New password works, so kill the old pool, create a new one, and borrow + manager.closePool(userName); + synchronized (this) { + managers.remove(key); + } + try { + registerPool(userName, password); + pool = getPool(key); + } catch (final NamingException ne) { + throw new SQLException("RegisterPool failed", ne); + } + try { + info = pool.borrowObject(); + } catch (final Exception ex) { + throw new SQLException("Could not retrieve connection info from pool", ex); + } + } + return info; } + /** + * Creates a pool key from the provided parameters. + * + * @param userName + * User name + * @return The pool key + */ + private PoolKey getPoolKey(final String userName) { + return new PoolKey(getDataSourceName(), userName); + } /** - * 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. + * Returns a <code>PerUserPoolDataSource</code> {@link Reference}. */ - public boolean getPerUserTestOnReturn(final String key) { - Boolean value = null; - if (perUserTestOnReturn != null) { - value = perUserTestOnReturn.get(key); + @Override + public Reference getReference() throws NamingException { + final Reference ref = new Reference(getClass().getName(), PerUserPoolDataSourceFactory.class.getName(), null); + ref.add(new StringRefAddr("instanceKey", getInstanceKey())); + return ref; + } + + /** + * Supports Serialization interface. + * + * @param in + * a <code>java.io.ObjectInputStream</code> value + * @throws IOException + * if an error occurs + * @throws ClassNotFoundException + * if an error occurs + */ + private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { + try { + in.defaultReadObject(); + final PerUserPoolDataSource oldDS = (PerUserPoolDataSource) new PerUserPoolDataSourceFactory() + .getObjectInstance(getReference(), null, null, null); + this.managers = oldDS.managers; + } catch (final NamingException e) { + throw new IOException("NamingException: " + e); } - if (value == null) { - return getDefaultTestOnReturn(); + } + + private synchronized void registerPool(final String userName, final String password) + throws NamingException, SQLException { + + final ConnectionPoolDataSource cpds = testCPDS(userName, password); + + // 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) + final CPDSConnectionFactory factory = new CPDSConnectionFactory(cpds, getValidationQuery(), + getValidationQueryTimeout(), isRollbackAfterValidation(), userName, password); + factory.setMaxConnLifetimeMillis(getMaxConnLifetimeMillis()); + + // Create an object pool to contain our PooledConnections + final GenericObjectPool<PooledConnectionAndInfo> pool = new GenericObjectPool<>(factory); + factory.setPool(pool); + 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.setTestOnCreate(getPerUserTestOnCreate(userName)); + pool.setTestOnBorrow(getPerUserTestOnBorrow(userName)); + pool.setTestOnReturn(getPerUserTestOnReturn(userName)); + pool.setTestWhileIdle(getPerUserTestWhileIdle(userName)); + pool.setTimeBetweenEvictionRunsMillis(getPerUserTimeBetweenEvictionRunsMillis(userName)); + + pool.setSwallowedExceptionListener(new SwallowedExceptionLogger(log)); + + final Object old = managers.put(getPoolKey(userName), factory); + if (old != null) { + throw new IllegalStateException("Pool already contains an entry for this user/password: " + userName); } - return value.booleanValue(); + } + + void setPerUserBlockWhenExhausted(final Map<String, Boolean> userDefaultBlockWhenExhausted) { + assertInitializationAllowed(); + if (perUserBlockWhenExhausted == null) { + perUserBlockWhenExhausted = createMap(); + } else { + perUserBlockWhenExhausted.clear(); + } + perUserBlockWhenExhausted.putAll(userDefaultBlockWhenExhausted); } /** - * Sets a user specific value for - * {@link GenericObjectPool#getTestOnReturn()} for the specified - * user's pool. + * Sets a user specific value for {@link GenericObjectPool#getBlockWhenExhausted()} for the specified user's pool. + * + * @param userName + * The user name key. + * @param value + * The user specific value. */ - public void setPerUserTestOnReturn(final String username, final Boolean value) { + public void setPerUserBlockWhenExhausted(final String userName, final Boolean value) { assertInitializationAllowed(); - if (perUserTestOnReturn == null) { - perUserTestOnReturn = new HashMap<>(); + if (perUserBlockWhenExhausted == null) { + perUserBlockWhenExhausted = createMap(); } - perUserTestOnReturn.put(username, value); + perUserBlockWhenExhausted.put(userName, value); } - void setPerUserTestOnReturn( - final Map<String,Boolean> userDefaultTestOnReturn) { + void setPerUserDefaultAutoCommit(final Map<String, Boolean> userDefaultAutoCommit) { assertInitializationAllowed(); - if (perUserTestOnReturn == null) { - perUserTestOnReturn = new HashMap<>(); + if (perUserDefaultAutoCommit == null) { + perUserDefaultAutoCommit = createMap(); } else { - perUserTestOnReturn.clear(); + perUserDefaultAutoCommit.clear(); } - perUserTestOnReturn.putAll(userDefaultTestOnReturn); + perUserDefaultAutoCommit.putAll(userDefaultAutoCommit); } - /** - * 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. + * Sets a user specific default value for {@link Connection#setAutoCommit(boolean)} for the specified user's pool. + * + * @param userName + * The user name key. + * @param value + * The user specific value. */ - public boolean getPerUserTestWhileIdle(final String key) { - Boolean value = null; - if (perUserTestWhileIdle != null) { - value = perUserTestWhileIdle.get(key); + public void setPerUserDefaultAutoCommit(final String userName, final Boolean value) { + assertInitializationAllowed(); + if (perUserDefaultAutoCommit == null) { + perUserDefaultAutoCommit = createMap(); } - if (value == null) { - return getDefaultTestWhileIdle(); + perUserDefaultAutoCommit.put(userName, value); + } + + void setPerUserDefaultReadOnly(final Map<String, Boolean> userDefaultReadOnly) { + assertInitializationAllowed(); + if (perUserDefaultReadOnly == null) { + perUserDefaultReadOnly = createMap(); + } else { + perUserDefaultReadOnly.clear(); } - return value.booleanValue(); + perUserDefaultReadOnly.putAll(userDefaultReadOnly); } /** - * Sets a user specific value for - * {@link GenericObjectPool#getTestWhileIdle()} for the specified - * user's pool. + * Sets a user specific default value for {@link Connection#setReadOnly(boolean)} for the specified user's pool. + * + * @param userName + * The user name key. + * @param value + * The user specific value. */ - public void setPerUserTestWhileIdle(final String username, final Boolean value) { + public void setPerUserDefaultReadOnly(final String userName, final Boolean value) { assertInitializationAllowed(); - if (perUserTestWhileIdle == null) { - perUserTestWhileIdle = new HashMap<>(); + if (perUserDefaultReadOnly == null) { + perUserDefaultReadOnly = createMap(); } - perUserTestWhileIdle.put(username, value); + perUserDefaultReadOnly.put(userName, value); } - void setPerUserTestWhileIdle( - final Map<String,Boolean> userDefaultTestWhileIdle) { + void setPerUserDefaultTransactionIsolation(final Map<String, Integer> userDefaultTransactionIsolation) { assertInitializationAllowed(); - if (perUserTestWhileIdle == null) { - perUserTestWhileIdle = new HashMap<>(); + if (perUserDefaultTransactionIsolation == null) { + perUserDefaultTransactionIsolation = new HashMap<>(); } else { - perUserTestWhileIdle.clear(); + perUserDefaultTransactionIsolation.clear(); } - perUserTestWhileIdle.putAll(userDefaultTestWhileIdle); + perUserDefaultTransactionIsolation.putAll(userDefaultTransactionIsolation); } - /** - * 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. + * Sets a user specific default value for {@link Connection#setTransactionIsolation(int)} for the specified user's + * pool. + * + * @param userName + * The user name key. + * @param value + * The user specific value. */ - public long getPerUserTimeBetweenEvictionRunsMillis(final String key) { - Long value = null; - if (perUserTimeBetweenEvictionRunsMillis != null) { - value = perUserTimeBetweenEvictionRunsMillis.get(key); + public void setPerUserDefaultTransactionIsolation(final String userName, final Integer value) { + assertInitializationAllowed(); + if (perUserDefaultTransactionIsolation == null) { + perUserDefaultTransactionIsolation = new HashMap<>(); } - if (value == null) { - return getDefaultTimeBetweenEvictionRunsMillis(); + perUserDefaultTransactionIsolation.put(userName, value); + } + + void setPerUserEvictionPolicyClassName(final Map<String, String> userDefaultEvictionPolicyClassName) { + assertInitializationAllowed(); + if (perUserEvictionPolicyClassName == null) { + perUserEvictionPolicyClassName = new HashMap<>(); + } else { + perUserEvictionPolicyClassName.clear(); } - return value.longValue(); + perUserEvictionPolicyClassName.putAll(userDefaultEvictionPolicyClassName); } /** - * Sets a user specific value for - * {@link GenericObjectPool#getTimeBetweenEvictionRunsMillis ()} for the specified - * user's pool. + * Sets a user specific value for {@link GenericObjectPool#getEvictionPolicyClassName()} for the specified user's + * pool. + * + * @param userName + * The user name key. + * @param value + * The user specific value. */ - public void setPerUserTimeBetweenEvictionRunsMillis(final String username, - final Long value) { + public void setPerUserEvictionPolicyClassName(final String userName, final String value) { assertInitializationAllowed(); - if (perUserTimeBetweenEvictionRunsMillis == null) { - perUserTimeBetweenEvictionRunsMillis = new HashMap<>(); + if (perUserEvictionPolicyClassName == null) { + perUserEvictionPolicyClassName = new HashMap<>(); } - perUserTimeBetweenEvictionRunsMillis.put(username, value); + perUserEvictionPolicyClassName.put(userName, value); } - void setPerUserTimeBetweenEvictionRunsMillis( - final Map<String,Long> userDefaultTimeBetweenEvictionRunsMillis ) { + void setPerUserLifo(final Map<String, Boolean> userDefaultLifo) { assertInitializationAllowed(); - if (perUserTimeBetweenEvictionRunsMillis == null) { - perUserTimeBetweenEvictionRunsMillis = new HashMap<>(); + if (perUserLifo == null) { + perUserLifo = createMap(); } else { - perUserTimeBetweenEvictionRunsMillis.clear(); + perUserLifo.clear(); } - perUserTimeBetweenEvictionRunsMillis.putAll( - userDefaultTimeBetweenEvictionRunsMillis ); + perUserLifo.putAll(userDefaultLifo); } - /** - * Gets the user specific default value for - * {@link Connection#setAutoCommit(boolean)} for the specified user's pool. + * Sets a user specific value for {@link GenericObjectPool#getLifo()} for the specified user's pool. + * + * @param userName + * The user name key. + * @param value + * The user specific value. */ - public Boolean getPerUserDefaultAutoCommit(final String key) { - Boolean value = null; - if (perUserDefaultAutoCommit != null) { - value = perUserDefaultAutoCommit.get(key); + public void setPerUserLifo(final String userName, final Boolean value) { + assertInitializationAllowed(); + if (perUserLifo == null) { + perUserLifo = createMap(); } - return value; + perUserLifo.put(userName, value); + } + + void setPerUserMaxIdle(final Map<String, Integer> userDefaultMaxIdle) { + assertInitializationAllowed(); + if (perUserMaxIdle == null) { + perUserMaxIdle = new HashMap<>(); + } else { + perUserMaxIdle.clear(); + } + perUserMaxIdle.putAll(userDefaultMaxIdle); } /** - * Sets a user specific default value for - * {@link Connection#setAutoCommit(boolean)} for the specified user's pool. + * Sets a user specific value for {@link GenericObjectPool#getMaxIdle()} for the specified user's pool. + * + * @param userName + * The user name key. + * @param value + * The user specific value. */ - public void setPerUserDefaultAutoCommit(final String username, final Boolean value) { + public void setPerUserMaxIdle(final String userName, final Integer value) { assertInitializationAllowed(); - if (perUserDefaultAutoCommit == null) { - perUserDefaultAutoCommit = new HashMap<>(); + if (perUserMaxIdle == null) { + perUserMaxIdle = new HashMap<>(); } - perUserDefaultAutoCommit.put(username, value); + perUserMaxIdle.put(userName, value); } - void setPerUserDefaultAutoCommit(final Map<String,Boolean> userDefaultAutoCommit) { + void setPerUserMaxTotal(final Map<String, Integer> userDefaultMaxTotal) { assertInitializationAllowed(); - if (perUserDefaultAutoCommit == null) { - perUserDefaultAutoCommit = new HashMap<>(); + if (perUserMaxTotal == null) { + perUserMaxTotal = new HashMap<>(); } else { - perUserDefaultAutoCommit.clear(); + perUserMaxTotal.clear(); } - perUserDefaultAutoCommit.putAll(userDefaultAutoCommit); + perUserMaxTotal.putAll(userDefaultMaxTotal); } - /** - * Gets the user specific default value for - * {@link Connection#setReadOnly(boolean)} for the specified user's pool. + * Sets a user specific value for {@link GenericObjectPool#getMaxTotal()} for the specified user's pool. + * + * @param userName + * The user name key. + * @param value + * The user specific value. */ - public Boolean getPerUserDefaultReadOnly(final String key) { - Boolean value = null; - if (perUserDefaultReadOnly != null) { - value = perUserDefaultReadOnly.get(key); + public void setPerUserMaxTotal(final String userName, final Integer value) { + assertInitializationAllowed(); + if (perUserMaxTotal == null) { + perUserMaxTotal = new HashMap<>(); } - return value; + perUserMaxTotal.put(userName, value); + } + + void setPerUserMaxWaitMillis(final Map<String, Long> userDefaultMaxWaitMillis) { + assertInitializationAllowed(); + if (perUserMaxWaitMillis == null) { + perUserMaxWaitMillis = new HashMap<>(); + } else { + perUserMaxWaitMillis.clear(); + } + perUserMaxWaitMillis.putAll(userDefaultMaxWaitMillis); } /** - * Sets a user specific default value for - * {@link Connection#setReadOnly(boolean)} for the specified user's pool. + * Sets a user specific value for {@link GenericObjectPool#getMaxWaitMillis()} for the specified user's pool. + * + * @param userName + * The user name key. + * @param value + * The user specific value. */ - public void setPerUserDefaultReadOnly(final String username, final Boolean value) { + public void setPerUserMaxWaitMillis(final String userName, final Long value) { assertInitializationAllowed(); - if (perUserDefaultReadOnly == null) { - perUserDefaultReadOnly = new HashMap<>(); + if (perUserMaxWaitMillis == null) { + perUserMaxWaitMillis = new HashMap<>(); } - perUserDefaultReadOnly.put(username, value); + perUserMaxWaitMillis.put(userName, value); } - void setPerUserDefaultReadOnly(final Map<String,Boolean> userDefaultReadOnly) { + void setPerUserMinEvictableIdleTimeMillis(final Map<String, Long> userDefaultMinEvictableIdleTimeMillis) { assertInitializationAllowed(); - if (perUserDefaultReadOnly == null) { - perUserDefaultReadOnly = new HashMap<>(); + if (perUserMinEvictableIdleTimeMillis == null) { + perUserMinEvictableIdleTimeMillis = new HashMap<>(); } else { - perUserDefaultReadOnly.clear(); + perUserMinEvictableIdleTimeMillis.clear(); } - perUserDefaultReadOnly.putAll(userDefaultReadOnly); + perUserMinEvictableIdleTimeMillis.putAll(userDefaultMinEvictableIdleTimeMillis); } - /** - * Gets the user specific default value for - * {@link Connection#setTransactionIsolation(int)} for the specified user's pool. + * Sets a user specific value for {@link GenericObjectPool#getMinEvictableIdleTimeMillis()} for the specified user's + * pool. + * + * @param userName + * The user name key. + * @param value + * The user specific value. */ - public Integer getPerUserDefaultTransactionIsolation(final String key) { - Integer value = null; - if (perUserDefaultTransactionIsolation != null) { - value = perUserDefaultTransactionIsolation.get(key); + public void setPerUserMinEvictableIdleTimeMillis(final String userName, final Long value) { + assertInitializationAllowed(); + if (perUserMinEvictableIdleTimeMillis == null) { + perUserMinEvictableIdleTimeMillis = new HashMap<>(); } - return value; + perUserMinEvictableIdleTimeMillis.put(userName, value); + } + + void setPerUserMinIdle(final Map<String, Integer> userDefaultMinIdle) { + assertInitializationAllowed(); + if (perUserMinIdle == null) { + perUserMinIdle = new HashMap<>(); + } else { + perUserMinIdle.clear(); + } + perUserMinIdle.putAll(userDefaultMinIdle); } /** - * Sets a user specific default value for - * {@link Connection#setTransactionIsolation(int)} for the specified user's pool. + * Sets a user specific value for {@link GenericObjectPool#getMinIdle()} for the specified user's pool. + * + * @param userName + * The user name key. + * @param value + * The user specific value. */ - public void setPerUserDefaultTransactionIsolation(final String username, - final Integer value) { + public void setPerUserMinIdle(final String userName, final Integer value) { assertInitializationAllowed(); - if (perUserDefaultTransactionIsolation == null) { - perUserDefaultTransactionIsolation = new HashMap<>(); + if (perUserMinIdle == null) { + perUserMinIdle = new HashMap<>(); } - perUserDefaultTransactionIsolation.put(username, value); + perUserMinIdle.put(userName, value); } - void setPerUserDefaultTransactionIsolation( - final Map<String,Integer> userDefaultTransactionIsolation) { + void setPerUserNumTestsPerEvictionRun(final Map<String, Integer> userDefaultNumTestsPerEvictionRun) { assertInitializationAllowed(); - if (perUserDefaultTransactionIsolation == null) { - perUserDefaultTransactionIsolation = new HashMap<>(); + if (perUserNumTestsPerEvictionRun == null) { + perUserNumTestsPerEvictionRun = new HashMap<>(); } else { - perUserDefaultTransactionIsolation.clear(); + perUserNumTestsPerEvictionRun.clear(); } - perUserDefaultTransactionIsolation.putAll(userDefaultTransactionIsolation); + perUserNumTestsPerEvictionRun.putAll(userDefaultNumTestsPerEvictionRun); } - - // ---------------------------------------------------------------------- - // Instrumentation Methods - /** - * Get the number of active connections in the default pool. + * Sets a user specific value for {@link GenericObjectPool#getNumTestsPerEvictionRun()} for the specified user's + * pool. + * + * @param userName + * The user name key. + * @param value + * The user specific value. */ - public int getNumActive() { - return getNumActive(null); + public void setPerUserNumTestsPerEvictionRun(final String userName, final Integer value) { + assertInitializationAllowed(); + if (perUserNumTestsPerEvictionRun == null) { + perUserNumTestsPerEvictionRun = new HashMap<>(); + } + perUserNumTestsPerEvictionRun.put(userName, value); + } + + void setPerUserSoftMinEvictableIdleTimeMillis(final Map<String, Long> userDefaultSoftMinEvictableIdleTimeMillis) { + assertInitializationAllowed(); + if (perUserSoftMinEvictableIdleTimeMillis == null) { + perUserSoftMinEvictableIdleTimeMillis = new HashMap<>(); + } else { + perUserSoftMinEvictableIdleTimeMillis.clear(); + } + perUserSoftMinEvictableIdleTimeMillis.putAll(userDefaultSoftMinEvictableIdleTimeMillis); } /** - * Get the number of active connections in the pool for a given user. + * Sets a user specific value for {@link GenericObjectPool#getSoftMinEvictableIdleTimeMillis()} for the specified + * user's pool. + * + * @param userName + * The user name key. + * @param value + * The user specific value. */ - public int getNumActive(final String username) { - final ObjectPool<PooledConnectionAndInfo> pool = - getPool(getPoolKey(username)); - return pool == null ? 0 : pool.getNumActive(); + public void setPerUserSoftMinEvictableIdleTimeMillis(final String userName, final Long value) { + assertInitializationAllowed(); + if (perUserSoftMinEvictableIdleTimeMillis == null) { + perUserSoftMinEvictableIdleTimeMillis = new HashMap<>(); + } + perUserSoftMinEvictableIdleTimeMillis.put(userName, value); + } + + void setPerUserTestOnBorrow(final Map<String, Boolean> userDefaultTestOnBorrow) { + assertInitializationAllowed(); + if (perUserTestOnBorrow == null) { + perUserTestOnBorrow = createMap(); + } else { + perUserTestOnBorrow.clear(); + } + perUserTestOnBorrow.putAll(userDefaultTestOnBorrow); } /** - * Get the number of idle connections in the default pool. + * Sets a user specific value for {@link GenericObjectPool#getTestOnBorrow()} for the specified user's pool. + * + * @param userName + * The user name key. + * @param value + * The user specific value. */ - public int getNumIdle() { - return getNumIdle(null); + public void setPerUserTestOnBorrow(final String userName, final Boolean value) { + assertInitializationAllowed(); + if (perUserTestOnBorrow == null) { + perUserTestOnBorrow = createMap(); + } + perUserTestOnBorrow.put(userName, value); + } + + void setPerUserTestOnCreate(final Map<String, Boolean> userDefaultTestOnCreate) { + assertInitializationAllowed(); + if (perUserTestOnCreate == null) { + perUserTestOnCreate = createMap(); + } else { + perUserTestOnCreate.clear(); + } + perUserTestOnCreate.putAll(userDefaultTestOnCreate); } /** - * Get the number of idle connections in the pool for a given user. + * Sets a user specific value for {@link GenericObjectPool#getTestOnCreate()} for the specified user's pool. + * + * @param userName + * The user name key. + * @param value + * The user specific value. */ - public int getNumIdle(final String username) { - final ObjectPool<PooledConnectionAndInfo> pool = - getPool(getPoolKey(username)); - return pool == null ? 0 : pool.getNumIdle(); + public void setPerUserTestOnCreate(final String userName, final Boolean value) { + assertInitializationAllowed(); + if (perUserTestOnCreate == null) { + perUserTestOnCreate = createMap(); + } + perUserTestOnCreate.put(userName, value); } + void setPerUserTestOnReturn(final Map<String, Boolean> userDefaultTestOnReturn) { + assertInitializationAllowed(); + if (perUserTestOnReturn == null) { + perUserTestOnReturn = createMap(); + } else { + perUserTestOnReturn.clear(); + } + perUserTestOnReturn.putAll(userDefaultTestOnReturn); + } - // ---------------------------------------------------------------------- - // Inherited abstract methods - - @Override - protected PooledConnectionAndInfo - getPooledConnectionAndInfo(final String username, final String password) - throws SQLException { + /** + * Sets a user specific value for {@link GenericObjectPool#getTestOnReturn()} for the specified user's pool. + * + * @param userName + * The user name key. + * @param value + * The user specific value. + */ + public void setPerUserTestOnReturn(final String userName, final Boolean value) { + assertInitializationAllowed(); + if (perUserTestOnReturn == null) { + perUserTestOnReturn = createMap(); + } + perUserTestOnReturn.put(userName, value); + } - final PoolKey key = getPoolKey(username); - ObjectPool<PooledConnectionAndInfo> pool; - PooledConnectionManager manager; - synchronized(this) { - manager = managers.get(key); - if (manager == null) { - try { - registerPool(username, password); - manager = managers.get(key); - } catch (final NamingException e) { - throw new SQLException("RegisterPool failed", e); - } - } - pool = ((CPDSConnectionFactory) manager).getPool(); + void setPerUserTestWhileIdle(final Map<String, Boolean> userDefaultTestWhileIdle) { + assertInitializationAllowed(); + if (perUserTestWhileIdle == null) { + perUserTestWhileIdle = createMap(); + } else { + perUserTestWhileIdle.clear(); } + perUserTestWhileIdle.putAll(userDefaultTestWhileIdle); + } - PooledConnectionAndInfo info = null; - try { - info = pool.borrowObject(); + /** + * Sets a user specific value for {@link GenericObjectPool#getTestWhileIdle()} for the specified user's pool. + * + * @param userName + * The user name key. + * @param value + * The user specific value. + */ + public void setPerUserTestWhileIdle(final String userName, final Boolean value) { + assertInitializationAllowed(); + if (perUserTestWhileIdle == null) { + perUserTestWhileIdle = createMap(); } - catch (final NoSuchElementException ex) { - throw new SQLException( - "Could not retrieve connection info from pool", ex); + perUserTestWhileIdle.put(userName, value); + } + + void setPerUserTimeBetweenEvictionRunsMillis(final Map<String, Long> userDefaultTimeBetweenEvictionRunsMillis) { + assertInitializationAllowed(); + if (perUserTimeBetweenEvictionRunsMillis == null) { + perUserTimeBetweenEvictionRunsMillis = new HashMap<>(); + } else { + perUserTimeBetweenEvictionRunsMillis.clear(); } - catch (final Exception e) { - // See if failure is due to CPDSConnectionFactory authentication failure - try { - testCPDS(username, password); - } catch (final Exception ex) { - throw new SQLException( - "Could not retrieve connection info from pool", ex); - } - // New password works, so kill the old pool, create a new one, and borrow - manager.closePool(username); - synchronized (this) { - managers.remove(key); - } - try { - registerPool(username, password); - pool = getPool(key); - } catch (final NamingException ne) { - throw new SQLException("RegisterPool failed", ne); - } - try { - info = pool.borrowObject(); - } catch (final Exception ex) { - throw new SQLException( - "Could not retrieve connection info from pool", ex); - } + perUserTimeBetweenEvictionRunsMillis.putAll(userDefaultTimeBetweenEvictionRunsMillis); + } + + /** + * Sets a user specific value for {@link GenericObjectPool#getTimeBetweenEvictionRunsMillis ()} for the specified + * user's pool. + * + * @param userName + * The user name key. + * @param value + * The user specific value. + */ + public void setPerUserTimeBetweenEvictionRunsMillis(final String userName, final Long value) { + assertInitializationAllowed(); + if (perUserTimeBetweenEvictionRunsMillis == null) { + perUserTimeBetweenEvictionRunsMillis = new HashMap<>(); } - return info; + perUserTimeBetweenEvictionRunsMillis.put(userName, value); } @Override - protected void setupDefaults(final Connection con, final String username) - throws SQLException { + protected void setupDefaults(final Connection con, final String userName) throws SQLException { Boolean defaultAutoCommit = isDefaultAutoCommit(); - if (username != null) { - final Boolean userMax = getPerUserDefaultAutoCommit(username); + if (userName != null) { + final Boolean userMax = getPerUserDefaultAutoCommit(userName); if (userMax != null) { defaultAutoCommit = userMax; } } Boolean defaultReadOnly = isDefaultReadOnly(); - if (username != null) { - final Boolean userMax = getPerUserDefaultReadOnly(username); + if (userName != null) { + final Boolean userMax = getPerUserDefaultReadOnly(userName); if (userMax != null) { defaultReadOnly = userMax; } } int defaultTransactionIsolation = getDefaultTransactionIsolation(); - if (username != null) { - final Integer userMax = getPerUserDefaultTransactionIsolation(username); + if (userName != null) { + final Integer userMax = getPerUserDefaultTransactionIsolation(userName); if (userMax != null) { defaultTransactionIsolation = userMax.intValue(); } } - if (defaultAutoCommit != null && - con.getAutoCommit() != defaultAutoCommit.booleanValue()) { + if (defaultAutoCommit != null && con.getAutoCommit() != defaultAutoCommit.booleanValue()) { con.setAutoCommit(defaultAutoCommit.booleanValue()); } @@ -972,116 +1169,8 @@ public class PerUserPoolDataSource exten con.setTransactionIsolation(defaultTransactionIsolation); } - if (defaultReadOnly != null && - con.isReadOnly() != defaultReadOnly.booleanValue()) { + if (defaultReadOnly != null && con.isReadOnly() != defaultReadOnly.booleanValue()) { con.setReadOnly(defaultReadOnly.booleanValue()); } } - - @Override - protected PooledConnectionManager getConnectionManager(final UserPassKey upkey) { - return managers.get(getPoolKey(upkey.getUsername())); - } - - /** - * Returns a <code>PerUserPoolDataSource</code> {@link Reference}. - */ - @Override - public Reference getReference() throws NamingException { - final Reference ref = new Reference(getClass().getName(), - PerUserPoolDataSourceFactory.class.getName(), null); - ref.add(new StringRefAddr("instanceKey", getInstanceKey())); - return ref; - } - - /** - * Create a pool key from the provided parameters. - * - * @param username User name - * @return The pool key - */ - private PoolKey getPoolKey(final String username) { - return new PoolKey(getDataSourceName(), username); - } - - private synchronized void registerPool(final String username, final String password) - throws NamingException, SQLException { - - final ConnectionPoolDataSource cpds = testCPDS(username, password); - - // 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) - final CPDSConnectionFactory factory = new CPDSConnectionFactory(cpds, - getValidationQuery(), getValidationQueryTimeout(), - isRollbackAfterValidation(), username, password); - factory.setMaxConnLifetimeMillis(getMaxConnLifetimeMillis()); - - // Create an object pool to contain our PooledConnections - final GenericObjectPool<PooledConnectionAndInfo> pool = - new GenericObjectPool<>(factory); - factory.setPool(pool); - 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.setTestOnCreate(getPerUserTestOnCreate(username)); - pool.setTestOnBorrow(getPerUserTestOnBorrow(username)); - pool.setTestOnReturn(getPerUserTestOnReturn(username)); - pool.setTestWhileIdle(getPerUserTestWhileIdle(username)); - pool.setTimeBetweenEvictionRunsMillis( - getPerUserTimeBetweenEvictionRunsMillis(username)); - - pool.setSwallowedExceptionListener(new SwallowedExceptionLogger(log)); - - final Object old = managers.put(getPoolKey(username), factory); - if (old != null) { - throw new IllegalStateException("Pool already contains an entry for this user/password: " + username); - } - } - - /** - * Supports Serialization interface. - * - * @param in a <code>java.io.ObjectInputStream</code> value - * @throws IOException if an error occurs - * @throws ClassNotFoundException if an error occurs - */ - private void readObject(final ObjectInputStream in) - throws IOException, ClassNotFoundException { - try - { - in.defaultReadObject(); - final PerUserPoolDataSource oldDS = (PerUserPoolDataSource) - new PerUserPoolDataSourceFactory() - .getObjectInstance(getReference(), null, null, null); - this.managers = oldDS.managers; - } - catch (final NamingException e) - { - throw new IOException("NamingException: " + e); - } - } - - /** - * Returns the object pool associated with the given PoolKey. - * - * @param key PoolKey identifying the pool - * @return the GenericObjectPool pooling connections for the username and datasource - * specified by the PoolKey - */ - private ObjectPool<PooledConnectionAndInfo> getPool(final PoolKey key) { - final CPDSConnectionFactory mgr = (CPDSConnectionFactory) managers.get(key); - return mgr == null ? null : mgr.getPool(); - } }
Modified: tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PerUserPoolDataSourceFactory.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PerUserPoolDataSourceFactory.java?rev=1833816&r1=1833815&r2=1833816&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PerUserPoolDataSourceFactory.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PerUserPoolDataSourceFactory.java Tue Jun 19 11:21:13 2018 @@ -28,11 +28,8 @@ import javax.naming.Reference; * * @since 2.0 */ -public class PerUserPoolDataSourceFactory - extends InstanceKeyDataSourceFactory -{ - private static final String PER_USER_POOL_CLASSNAME = - PerUserPoolDataSource.class.getName(); +public class PerUserPoolDataSourceFactory extends InstanceKeyDataSourceFactory { + private static final String PER_USER_POOL_CLASSNAME = PerUserPoolDataSource.class.getName(); @Override protected boolean isCorrectClass(final String className) { @@ -41,69 +38,58 @@ public class PerUserPoolDataSourceFactor @SuppressWarnings("unchecked") // Avoid warnings on deserialization @Override - protected InstanceKeyDataSource getNewInstance(final Reference ref) - throws IOException, ClassNotFoundException { - final PerUserPoolDataSource pupds = new PerUserPoolDataSource(); + protected InstanceKeyDataSource getNewInstance(final Reference ref) throws IOException, ClassNotFoundException { + final PerUserPoolDataSource pupds = new PerUserPoolDataSource(); RefAddr ra = ref.get("defaultMaxTotal"); if (ra != null && ra.getContent() != null) { - pupds.setDefaultMaxTotal( - Integer.parseInt(ra.getContent().toString())); + pupds.setDefaultMaxTotal(Integer.parseInt(ra.getContent().toString())); } ra = ref.get("defaultMaxIdle"); if (ra != null && ra.getContent() != null) { - pupds.setDefaultMaxIdle( - Integer.parseInt(ra.getContent().toString())); + pupds.setDefaultMaxIdle(Integer.parseInt(ra.getContent().toString())); } ra = ref.get("defaultMaxWaitMillis"); if (ra != null && ra.getContent() != null) { - pupds.setDefaultMaxWaitMillis( - Integer.parseInt(ra.getContent().toString())); + pupds.setDefaultMaxWaitMillis(Integer.parseInt(ra.getContent().toString())); } ra = ref.get("perUserDefaultAutoCommit"); - if (ra != null && ra.getContent() != null) { + if (ra != null && ra.getContent() != null) { final byte[] serialized = (byte[]) ra.getContent(); - pupds.setPerUserDefaultAutoCommit( - (Map<String,Boolean>) deserialize(serialized)); + pupds.setPerUserDefaultAutoCommit((Map<String, Boolean>) deserialize(serialized)); } ra = ref.get("perUserDefaultTransactionIsolation"); - if (ra != null && ra.getContent() != null) { + if (ra != null && ra.getContent() != null) { final byte[] serialized = (byte[]) ra.getContent(); - pupds.setPerUserDefaultTransactionIsolation( - (Map<String,Integer>) deserialize(serialized)); + pupds.setPerUserDefaultTransactionIsolation((Map<String, Integer>) deserialize(serialized)); } ra = ref.get("perUserMaxTotal"); - if (ra != null && ra.getContent() != null) { + if (ra != null && ra.getContent() != null) { final byte[] serialized = (byte[]) ra.getContent(); - pupds.setPerUserMaxTotal( - (Map<String,Integer>) deserialize(serialized)); + pupds.setPerUserMaxTotal((Map<String, Integer>) deserialize(serialized)); } ra = ref.get("perUserMaxIdle"); - if (ra != null && ra.getContent() != null) { + if (ra != null && ra.getContent() != null) { final byte[] serialized = (byte[]) ra.getContent(); - pupds.setPerUserMaxIdle( - (Map<String,Integer>) deserialize(serialized)); + pupds.setPerUserMaxIdle((Map<String, Integer>) deserialize(serialized)); } ra = ref.get("perUserMaxWaitMillis"); - if (ra != null && ra.getContent() != null) { + if (ra != null && ra.getContent() != null) { final byte[] serialized = (byte[]) ra.getContent(); - pupds.setPerUserMaxWaitMillis( - (Map<String,Long>) deserialize(serialized)); + pupds.setPerUserMaxWaitMillis((Map<String, Long>) deserialize(serialized)); } ra = ref.get("perUserDefaultReadOnly"); - if (ra != null && ra.getContent() != null) { + if (ra != null && ra.getContent() != null) { final byte[] serialized = (byte[]) ra.getContent(); - pupds.setPerUserDefaultReadOnly( - (Map<String,Boolean>) deserialize(serialized)); + pupds.setPerUserDefaultReadOnly((Map<String, Boolean>) deserialize(serialized)); } return pupds; } } - Modified: tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PoolKey.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PoolKey.java?rev=1833816&r1=1833815&r2=1833816&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PoolKey.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PoolKey.java Tue Jun 19 11:21:13 2018 @@ -25,41 +25,57 @@ import java.io.Serializable; class PoolKey implements Serializable { private static final long serialVersionUID = 2252771047542484533L; - private final String datasourceName; - private final String username; + private final String dataSourceName; + private final String userName; - PoolKey(final String datasourceName, final String username) { - this.datasourceName = datasourceName; - this.username = username; + PoolKey(final String dataSourceName, final String userName) { + this.dataSourceName = dataSourceName; + this.userName = userName; } @Override public boolean equals(final Object obj) { - if (obj instanceof PoolKey) { - final PoolKey pk = (PoolKey)obj; - return (null == datasourceName ? null == pk.datasourceName : datasourceName.equals(pk.datasourceName)) && - (null == username ? null == pk.username : username.equals(pk.username)); + if (this == obj) { + return true; } - return false; + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final PoolKey other = (PoolKey) obj; + if (dataSourceName == null) { + if (other.dataSourceName != null) { + return false; + } + } else if (!dataSourceName.equals(other.dataSourceName)) { + return false; + } + if (userName == null) { + if (other.userName != null) { + return false; + } + } else if (!userName.equals(other.userName)) { + return false; + } + return true; } @Override public int hashCode() { - int h = 0; - if (datasourceName != null) { - h += datasourceName.hashCode(); - } - if (username != null) { - h = 29 * h + username.hashCode(); - } - return h; + final int prime = 31; + int result = 1; + result = prime * result + ((dataSourceName == null) ? 0 : dataSourceName.hashCode()); + result = prime * result + ((userName == null) ? 0 : userName.hashCode()); + return result; } @Override public String toString() { final StringBuffer sb = new StringBuffer(50); sb.append("PoolKey("); - sb.append(username).append(", ").append(datasourceName); + sb.append(userName).append(", ").append(dataSourceName); sb.append(')'); return sb.toString(); } Modified: tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PooledConnectionAndInfo.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PooledConnectionAndInfo.java?rev=1833816&r1=1833815&r2=1833816&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PooledConnectionAndInfo.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PooledConnectionAndInfo.java Tue Jun 19 11:21:13 2018 @@ -19,23 +19,36 @@ package org.apache.tomcat.dbcp.dbcp2.dat import javax.sql.PooledConnection; +import org.apache.tomcat.dbcp.dbcp2.Utils; + /** - * Immutable poolable object holding a PooledConnection along with the username and password - * used to create the connection. + * Immutable poolable object holding a PooledConnection along with the user name and password used to create the + * connection. * * @since 2.0 */ final class PooledConnectionAndInfo { private final PooledConnection pooledConnection; - private final String password; - private final String username; - private final UserPassKey upkey; + private final char[] userPassword; + private final String userName; + private final UserPassKey upKey; - PooledConnectionAndInfo(final PooledConnection pc, final String username, final String password) { + /** + * @since 2.4.0 + */ + PooledConnectionAndInfo(final PooledConnection pc, final String userName, final char[] userPassword) { this.pooledConnection = pc; - this.username = username; - this.password = password; - upkey = new UserPassKey(username, password); + this.userName = userName; + this.userPassword = userPassword; + this.upKey = new UserPassKey(userName, userPassword); + } + + /** + * @deprecated Since 2.4.0 + */ + @Deprecated + PooledConnectionAndInfo(final PooledConnection pc, final String userName, final String userPassword) { + this(pc, userName, Utils.toCharArray(userPassword)); } PooledConnection getPooledConnection() { @@ -43,22 +56,34 @@ final class PooledConnectionAndInfo { } UserPassKey getUserPassKey() { - return upkey; + return upKey; } /** - * Get the value of password. + * Gets the value of password. + * * @return value of password. */ String getPassword() { - return password; + return Utils.toString(userPassword); + } + + /** + * Gets the value of password. + * + * @return value of password. + * @since 2.4.0 + */ + char[] getPasswordCharArray() { + return userPassword; } /** - * Get the value of username. - * @return value of username. + * Gets the value of userName. + * + * @return value of userName. */ String getUsername() { - return username; + return userName; } } Modified: tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PooledConnectionManager.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PooledConnectionManager.java?rev=1833816&r1=1833815&r2=1833816&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PooledConnectionManager.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/PooledConnectionManager.java Tue Jun 19 11:21:13 2018 @@ -27,29 +27,41 @@ import javax.sql.PooledConnection; * @since 2.0 */ interface PooledConnectionManager { + /** - * Close the PooledConnection and remove it from the connection pool - * to which it belongs, adjusting pool counters. + * Closes the PooledConnection and remove it from the connection pool to which it belongs, adjusting pool counters. * - * @param pc PooledConnection to be invalidated - * @throws SQLException if an SQL error occurs closing the connection + * @param pc + * PooledConnection to be invalidated + * @throws SQLException + * if an SQL error occurs closing the connection */ void invalidate(PooledConnection pc) throws SQLException; + // /** + // * Sets the database password used when creating connections. + // * + // * @param password password used when authenticating to the database + // * @since 3.0.0 + // */ + // void setPassword(char[] password); + /** * Sets the database password used when creating connections. * - * @param password password used when authenticating to the database + * @param password + * password used when authenticating to the database */ void setPassword(String password); - /** * Closes the connection pool associated with the given user. * - * @param username user name - * @throws SQLException if an error occurs closing idle connections in the pool + * @param userName + * user name + * @throws SQLException + * if an error occurs closing idle connections in the pool */ - void closePool(String username) throws SQLException; + void closePool(String userName) throws SQLException; } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org