You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by sa...@apache.org on 2006/03/15 23:28:22 UTC
svn commit: r386186 [1/2] - in /jakarta/commons/proper/pool/trunk:
src/java/org/apache/commons/pool/ src/java/org/apache/commons/pool/impl/
src/test/org/apache/commons/pool/ src/test/org/apache/commons/pool/impl/
xdocs/
Author: sandymac
Date: Wed Mar 15 14:28:20 2006
New Revision: 386186
URL: http://svn.apache.org/viewcvs?rev=386186&view=rev
Log:
Created unit tests to verify KeyedObjectPools conform to new contracts.
Refactored KeyedObjectPool implementations to comply with new contracts.
Improved JavaDocs for KeyedObjectPools.
Added:
jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/MethodCall.java (with props)
jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/PrivateException.java (with props)
Modified:
jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/BaseKeyedObjectPool.java
jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/KeyedObjectPool.java
jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/ObjectPool.java
jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/StackKeyedObjectPool.java
jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/TestKeyedObjectPool.java
jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/TestObjectPool.java
jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/impl/TestGenericKeyedObjectPool.java
jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/impl/TestStackKeyedObjectPool.java
jakarta/commons/proper/pool/trunk/xdocs/changes.xml
Modified: jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/BaseKeyedObjectPool.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/BaseKeyedObjectPool.java?rev=386186&r1=386185&r2=386186&view=diff
==============================================================================
--- jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/BaseKeyedObjectPool.java (original)
+++ jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/BaseKeyedObjectPool.java Wed Mar 15 14:28:20 2006
@@ -17,7 +17,7 @@
package org.apache.commons.pool;
/**
- * A simple base implementation of {@link ObjectPool}.
+ * A simple base implementation of <code>KeyedObjectPool</code>.
* Optional operations are implemented to either do nothing, return a value
* indicating it is unsupported or throw {@link UnsupportedOperationException}.
*
Modified: jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/KeyedObjectPool.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/KeyedObjectPool.java?rev=386186&r1=386185&r2=386186&view=diff
==============================================================================
--- jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/KeyedObjectPool.java (original)
+++ jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/KeyedObjectPool.java Wed Mar 15 14:28:20 2006
@@ -124,8 +124,8 @@
/**
* Create an object using the {@link KeyedPoolableObjectFactory factory} or other
- * implementation dependent mechanism, passivated, and then placed in the idle object pool.
- * addObject() is useful for "pre-loading" a pool with idle objects.
+ * implementation dependent mechanism, passivate it, and then place it in the idle object pool.
+ * <code>addObject</code> is useful for "pre-loading" a pool with idle objects
* (Optional operation).
*
* @param key the key a new instance should be added to
Modified: jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/ObjectPool.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/ObjectPool.java?rev=386186&r1=386185&r2=386186&view=diff
==============================================================================
--- jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/ObjectPool.java (original)
+++ jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/ObjectPool.java Wed Mar 15 14:28:20 2006
@@ -112,8 +112,8 @@
/**
* Create an object using the {@link PoolableObjectFactory factory} or other
- * implementation dependent mechanism, passivated, and then placed in the idle object pool.
- * addObject() is useful for "pre-loading" a pool with idle objects.
+ * implementation dependent mechanism, passivate it, and then place it in the idle object pool.
+ * <code>addObject</code> is useful for "pre-loading" a pool with idle objects.
* (Optional operation).
*
* @throws Exception when {@link PoolableObjectFactory#makeObject} fails.
Modified: jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java?rev=386186&r1=386185&r2=386186&view=diff
==============================================================================
--- jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java (original)
+++ jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java Wed Mar 15 14:28:20 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2004,2006 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,65 +32,65 @@
import org.apache.commons.pool.KeyedPoolableObjectFactory;
/**
- * A configurable {@link KeyedObjectPool} implementation.
+ * A configurable <code>KeyedObjectPool</code> implementation.
* <p>
* When coupled with the appropriate {@link KeyedPoolableObjectFactory},
- * <tt>GenericKeyedObjectPool</tt> provides robust pooling functionality for
+ * <code>GenericKeyedObjectPool</code> provides robust pooling functionality for
* arbitrary objects.
- * <p>
- * A <tt>GenericKeyedObjectPool</tt> provides a number of configurable parameters:
+ * </p>
+ * <p>A <code>GenericKeyedObjectPool</code> provides a number of configurable parameters:</p>
* <ul>
* <li>
- * {@link #setMaxActive <i>maxActive</i>} controls the maximum number of objects (per key)
+ * {@link #setMaxActive maxActive} controls the maximum number of objects (per key)
* that can be borrowed from the pool at one time. When non-positive, there
* is no limit to the number of objects that may be active at one time.
- * When {@link #setMaxActive <i>maxActive</i>} is exceeded, the pool is said to be exhausted.
+ * When {@link #setMaxActive maxActive} is exceeded, the pool is said to be exhausted.
* </li>
* <li>
- * {@link #setMaxIdle <i>maxIdle</i>} controls the maximum number of objects that can
+ * {@link #setMaxIdle maxIdle} controls the maximum number of objects that can
* sit idle in the pool (per key) at any time. When negative, there
* is no limit to the number of objects that may be idle at one time.
* </li>
* <li>
- * {@link #setWhenExhaustedAction <i>whenExhaustedAction</i>} specifies the
- * behaviour of the {@link #borrowObject} method when the pool is exhausted:
+ * {@link #setWhenExhaustedAction whenExhaustedAction} specifies the
+ * behaviour of the {@link #borrowObject borrowObject} method when the pool is exhausted:
* <ul>
* <li>
- * When {@link #setWhenExhaustedAction <i>whenExhaustedAction</i>} is
- * {@link #WHEN_EXHAUSTED_FAIL}, {@link #borrowObject} will throw
+ * When {@link #setWhenExhaustedAction whenExhaustedAction} is
+ * {@link #WHEN_EXHAUSTED_FAIL}, {@link #borrowObject borrowObject} will throw
* a {@link NoSuchElementException}
* </li>
* <li>
- * When {@link #setWhenExhaustedAction <i>whenExhaustedAction</i>} is
- * {@link #WHEN_EXHAUSTED_GROW}, {@link #borrowObject} will create a new
- * object and return it(essentially making {@link #setMaxActive <i>maxActive</i>}
+ * When {@link #setWhenExhaustedAction whenExhaustedAction} is
+ * {@link #WHEN_EXHAUSTED_GROW}, {@link #borrowObject borrowObject} will create a new
+ * object and return it (essentially making {@link #setMaxActive maxActive}
* meaningless.)
* </li>
* <li>
- * When {@link #setWhenExhaustedAction <i>whenExhaustedAction</i>}
- * is {@link #WHEN_EXHAUSTED_BLOCK}, {@link #borrowObject} will block
- * (invoke {@link Object#wait} until a new or idle object is available.
- * If a positive {@link #setMaxWait <i>maxWait</i>}
- * value is supplied, the {@link #borrowObject} will block for at
+ * When {@link #setWhenExhaustedAction whenExhaustedAction}
+ * is {@link #WHEN_EXHAUSTED_BLOCK}, {@link #borrowObject borrowObject} will block
+ * (invoke {@link Object#wait wait} until a new or idle object is available.
+ * If a positive {@link #setMaxWait maxWait}
+ * value is supplied, the {@link #borrowObject borrowObject} will block for at
* most that many milliseconds, after which a {@link NoSuchElementException}
- * will be thrown. If {@link #setMaxWait <i>maxWait</i>} is non-positive,
- * the {@link #borrowObject} method will block indefinitely.
+ * will be thrown. If {@link #setMaxWait maxWait} is non-positive,
+ * the {@link #borrowObject borrowObject} method will block indefinitely.
* </li>
* </ul>
* </li>
* <li>
- * When {@link #setTestOnBorrow <i>testOnBorrow</i>} is set, the pool will
+ * When {@link #setTestOnBorrow testOnBorrow} is set, the pool will
* attempt to validate each object before it is returned from the
- * {@link #borrowObject} method. (Using the provided factory's
- * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject} method.) Objects that fail
+ * {@link #borrowObject borrowObject} method. (Using the provided factory's
+ * {@link KeyedPoolableObjectFactory#validateObject validateObject} method.) Objects that fail
* to validate will be dropped from the pool, and a different object will
* be borrowed.
* </li>
* <li>
- * When {@link #setTestOnReturn <i>testOnReturn</i>} is set, the pool will
+ * When {@link #setTestOnReturn testOnReturn} is set, the pool will
* attempt to validate each object before it is returned to the pool in the
- * {@link #returnObject} method. (Using the provided factory's
- * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject}
+ * {@link #returnObject returnObject} method. (Using the provided factory's
+ * {@link KeyedPoolableObjectFactory#validateObject validateObject}
* method.) Objects that fail to validate will be dropped from the pool.
* </li>
* </ul>
@@ -101,31 +101,32 @@
* following attributes:
* <ul>
* <li>
- * {@link #setTimeBetweenEvictionRunsMillis <i>timeBetweenEvictionRunsMillis</i>}
+ * {@link #setTimeBetweenEvictionRunsMillis timeBetweenEvictionRunsMillis}
* indicates how long the eviction thread should sleep before "runs" of examining
* idle objects. When non-positive, no eviction thread will be launched.
* </li>
* <li>
- * {@link #setMinEvictableIdleTimeMillis <i>minEvictableIdleTimeMillis</i>}
+ * {@link #setMinEvictableIdleTimeMillis minEvictableIdleTimeMillis}
* specifies the minimum amount of time that an object may sit idle in the pool
* before it is eligable for eviction due to idle time. When non-positive, no object
* will be dropped from the pool due to idle time alone.
* </li>
* <li>
- * {@link #setTestWhileIdle <i>testWhileIdle</i>} indicates whether or not idle
+ * {@link #setTestWhileIdle testWhileIdle} indicates whether or not idle
* objects should be validated using the factory's
- * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject} method. Objects
+ * {@link KeyedPoolableObjectFactory#validateObject validateObject} method. Objects
* that fail to validate will be dropped from the pool.
* </li>
* </ul>
* <p>
* GenericKeyedObjectPool is not usable without a {@link KeyedPoolableObjectFactory}. A
* non-<code>null</code> factory must be provided either as a constructor argument
- * or via a call to {@link #setFactory} before the pool is used.
+ * or via a call to {@link #setFactory setFactory} before the pool is used.
* </p>
* @see GenericObjectPool
* @author Rodney Waldhoff
* @author Dirk Verbeeck
+ * @author Sandy McArthur
* @version $Revision$ $Date$
*/
public class GenericKeyedObjectPool extends BaseKeyedObjectPool implements KeyedObjectPool {
@@ -216,7 +217,7 @@
* @see #getTestOnBorrow
* @see #setTestOnBorrow
*/
- public static final boolean DEFAULT_TEST_ON_BORROW = false;
+ public static final boolean DEFAULT_TEST_ON_BORROW = true;
/**
* The default "test on return" value.
@@ -268,32 +269,35 @@
//--- constructors -----------------------------------------------
/**
- * Create a new <tt>GenericKeyedObjectPool</tt>..
+ * Create a new <code>GenericKeyedObjectPool</code> with no factory.
+ *
+ * @see #GenericKeyedObjectPool(KeyedPoolableObjectFactory)
+ * @see #setFactory(KeyedPoolableObjectFactory)
*/
public GenericKeyedObjectPool() {
this(null,DEFAULT_MAX_ACTIVE,DEFAULT_WHEN_EXHAUSTED_ACTION,DEFAULT_MAX_WAIT,DEFAULT_MAX_IDLE,DEFAULT_TEST_ON_BORROW,DEFAULT_TEST_ON_RETURN,DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,DEFAULT_NUM_TESTS_PER_EVICTION_RUN,DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,DEFAULT_TEST_WHILE_IDLE);
}
/**
- * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
- * @param factory the (possibly <tt>null</tt>)KeyedPoolableObjectFactory to use to create, validate and destroy objects
+ * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
+ * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
*/
public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory) {
this(factory,DEFAULT_MAX_ACTIVE,DEFAULT_WHEN_EXHAUSTED_ACTION,DEFAULT_MAX_WAIT,DEFAULT_MAX_IDLE,DEFAULT_TEST_ON_BORROW,DEFAULT_TEST_ON_RETURN,DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,DEFAULT_NUM_TESTS_PER_EVICTION_RUN,DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,DEFAULT_TEST_WHILE_IDLE);
}
/**
- * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
- * @param factory the (possibly <tt>null</tt>)KeyedPoolableObjectFactory to use to create, validate and destroy objects
- * @param config a non-<tt>null</tt> {@link GenericKeyedObjectPool.Config} describing my configuration
+ * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
+ * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
+ * @param config a non-<code>null</code> {@link GenericKeyedObjectPool.Config} describing the configuration
*/
public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, GenericKeyedObjectPool.Config config) {
this(factory,config.maxActive,config.whenExhaustedAction,config.maxWait,config.maxIdle,config.maxTotal,config.testOnBorrow,config.testOnReturn,config.timeBetweenEvictionRunsMillis,config.numTestsPerEvictionRun,config.minEvictableIdleTimeMillis,config.testWhileIdle);
}
/**
- * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
- * @param factory the (possibly <tt>null</tt>)KeyedPoolableObjectFactory to use to create, validate and destroy objects
+ * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
+ * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
* @param maxActive the maximum number of objects that can be borrowed from me at one time (per key) (see {@link #setMaxActive})
*/
public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive) {
@@ -301,21 +305,21 @@
}
/**
- * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
- * @param factory the (possibly <tt>null</tt>)KeyedPoolableObjectFactory to use to create, validate and destroy objects
+ * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
+ * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
* @param maxActive the maximum number of objects that can be borrowed from me at one time (per key) (see {@link #setMaxActive})
* @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
- * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
+ * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
*/
public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait) {
this(factory,maxActive,whenExhaustedAction,maxWait,DEFAULT_MAX_IDLE,DEFAULT_TEST_ON_BORROW,DEFAULT_TEST_ON_RETURN,DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,DEFAULT_NUM_TESTS_PER_EVICTION_RUN,DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,DEFAULT_TEST_WHILE_IDLE);
}
/**
- * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
- * @param factory the (possibly <tt>null</tt>)KeyedPoolableObjectFactory to use to create, validate and destroy objects
+ * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
+ * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
* @param maxActive the maximum number of objects that can be borrowed from me at one time (per key) (see {@link #setMaxActive})
- * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
+ * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
* @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
* @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
* @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
@@ -325,11 +329,11 @@
}
/**
- * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
- * @param factory the (possibly <tt>null</tt>)KeyedPoolableObjectFactory to use to create, validate and destroy objects
+ * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
+ * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
* @param maxActive the maximum number of objects that can be borrowed from me at one time (per key) (see {@link #setMaxActive})
* @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
- * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
+ * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
* @param maxIdle the maximum number of idle objects in my pool (per key) (see {@link #setMaxIdle})
*/
public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle) {
@@ -337,11 +341,11 @@
}
/**
- * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
- * @param factory the (possibly <tt>null</tt>)KeyedPoolableObjectFactory to use to create, validate and destroy objects
+ * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
+ * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
* @param maxActive the maximum number of objects that can be borrowed from me at one time (per key) (see {@link #setMaxActive})
* @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
- * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #getMaxWait})
+ * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #getMaxWait})
* @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
* @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
* @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
@@ -351,11 +355,11 @@
}
/**
- * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
- * @param factory the (possibly <tt>null</tt>)PoolableObjectFactory to use to create, validate and destroy objects
+ * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
+ * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
* @param maxActive the maximum number of objects that can be borrowed from me at one time (per key) (see {@link #setMaxActive})
* @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
- * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
+ * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
* @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
* @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
* @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
@@ -369,11 +373,11 @@
}
/**
- * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
- * @param factory the (possibly <tt>null</tt>)PoolableObjectFactory to use to create, validate and destroy objects
+ * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
+ * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
* @param maxActive the maximum number of objects that can be borrowed from me at one time (per key) (see {@link #setMaxActive})
* @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
- * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
+ * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
* @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
* @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal})
* @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
@@ -384,15 +388,15 @@
* @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see {@link #setTestWhileIdle})
*/
public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, int maxTotal, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle) {
- this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, GenericKeyedObjectPool.DEFAULT_MIN_IDLE, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle);
+ this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, maxTotal, GenericKeyedObjectPool.DEFAULT_MIN_IDLE, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle);
}
/**
- * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
- * @param factory the (possibly <tt>null</tt>)PoolableObjectFactory to use to create, validate and destroy objects
+ * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
+ * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
* @param maxActive the maximum number of objects that can be borrowed from me at one time (per key) (see {@link #setMaxActive})
* @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
- * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
+ * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
* @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
* @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal})
* @param minIdle the minimum number of idle objects to have in the pool at any one time (see {@link #setMinIdle})
@@ -588,7 +592,7 @@
}
/**
- * When <tt>true</tt>, objects will be
+ * When <code>true</code>, objects will be
* {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
* before being returned by the {@link #borrowObject}
* method. If the object fails to validate,
@@ -602,7 +606,7 @@
}
/**
- * When <tt>true</tt>, objects will be
+ * When <code>true</code>, objects will be
* {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
* before being returned by the {@link #borrowObject}
* method. If the object fails to validate,
@@ -616,7 +620,7 @@
}
/**
- * When <tt>true</tt>, objects will be
+ * When <code>true</code>, objects will be
* {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
* before being returned to the pool within the
* {@link #returnObject}.
@@ -628,7 +632,7 @@
}
/**
- * When <tt>true</tt>, objects will be
+ * When <code>true</code>, objects will be
* {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
* before being returned to the pool within the
* {@link #returnObject}.
@@ -679,8 +683,8 @@
* 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 #getNumIdle})/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
+ * When a negative value is supplied, <code>ceil({@link #getNumIdle})/abs({@link #getNumTestsPerEvictionRun})</code>
+ * tests will be run. I.e., when the value is <code>-n</code>, roughly one <code>n</code>th of the
* idle objects will be tested per run.
*
* @see #getNumTestsPerEvictionRun
@@ -717,7 +721,7 @@
}
/**
- * When <tt>true</tt>, objects will be
+ * When <code>true</code>, objects will be
* {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
* by the idle object evictor (if any). If an object
* fails to validate, it will be dropped from the pool.
@@ -730,7 +734,7 @@
}
/**
- * When <tt>true</tt>, objects will be
+ * When <code>true</code>, objects will be
* {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
* by the idle object evictor (if any). If an object
* fails to validate, it will be dropped from the pool.
@@ -764,6 +768,7 @@
//-- ObjectPool methods ------------------------------------------
public synchronized Object borrowObject(Object key) throws Exception {
+ assertOpen();
long starttime = System.currentTimeMillis();
boolean newlyCreated = false;
for(;;) {
@@ -833,19 +838,48 @@
}
}
}
- _factory.activateObject(key,pair.value);
- if(_testOnBorrow && !_factory.validateObject(key,pair.value)) {
- _factory.destroyObject(key,pair.value);
- if(newlyCreated) {
- throw new NoSuchElementException("Could not create a validated object");
- } // else keep looping
- } else {
+ if (newlyCreated) {
incrementActiveCount(key);
return pair.value;
+ } else {
+ try {
+ _factory.activateObject(key, pair.value);
+ } catch (Exception e) {
+ try {
+ _factory.destroyObject(key,pair.value);
+ } catch (Exception e2) {
+ // swallowed
+ }
+ continue;
+ }
+
+ boolean invalid = true;
+ try {
+ invalid = _testOnBorrow && !_factory.validateObject(key, pair.value);
+ } catch (Exception e) {
+ // swallowed
+ }
+ if (invalid) {
+ try {
+ _factory.destroyObject(key,pair.value);
+ } catch (Exception e) {
+ // swallowed
+ }
+ if(newlyCreated) {
+ throw new NoSuchElementException("Could not create a validated object");
+ } // else keep looping
+ } else {
+ incrementActiveCount(key);
+ return pair.value;
+ }
+
}
}
}
+ /**
+ * Clears the pool, removing all pooled instances.
+ */
public synchronized void clear() {
for(Iterator keyiter = _poolMap.keySet().iterator(); keyiter.hasNext(); ) {
Object key = keyiter.next();
@@ -916,6 +950,11 @@
notifyAll();
}
+ /**
+ * Clears the specified pool, removing all pooled instances corresponding to the given <code>key</code>.
+ *
+ * @param key the key to clear
+ */
public synchronized void clear(Object key) {
LinkedList pool = (LinkedList)(_poolMap.remove(key));
if(null == pool) {
@@ -934,18 +973,41 @@
notifyAll();
}
+ /**
+ * Returns the total number of instances current borrowed from this pool but not yet returned.
+ *
+ * @return the total number of instances currently borrowed from this pool
+ */
public synchronized int getNumActive() {
return _totalActive;
}
+ /**
+ * Returns the total number of instances currently idle in this pool.
+ *
+ * @return the total number of instances currently idle in this pool
+ */
public synchronized int getNumIdle() {
return _totalIdle;
}
+ /**
+ * Returns the number of instances currently borrowed from but not yet returned
+ * to the pool corresponding to the given <code>key</code>.
+ *
+ * @param key the key to query
+ * @return the number of instances corresponding to the given <code>key</code> currently borrowed in this pool
+ */
public synchronized int getNumActive(Object key) {
return getActiveCount(key);
}
+ /**
+ * Returns the number of instances corresponding to the given <code>key</code> currently idle in this pool.
+ *
+ * @param key the key to query
+ * @return the number of instances corresponding to the given <code>key</code> currently idle in this pool
+ */
public synchronized int getNumIdle(Object key) {
try {
return((LinkedList)(_poolMap.get(key))).size();
@@ -973,6 +1035,15 @@
}
}
+ if (isClosed()) {
+ try {
+ _factory.destroyObject(key, obj);
+ } catch(Exception e) {
+ // ignored
+ }
+ return;
+ }
+
boolean shouldDestroy = false;
// grab the pool (list) of objects associated with the given key
LinkedList pool = (LinkedList) (_poolMap.get(key));
@@ -1004,24 +1075,67 @@
public synchronized void invalidateObject(Object key, Object obj) throws Exception {
try {
_factory.destroyObject(key, obj);
- }
- finally {
+ } catch (Exception e) {
+ // swallowed
+ } finally {
decrementActiveCount(key);
notifyAll(); // _totalActive has changed
}
}
+ /**
+ * Create an object using the {@link KeyedPoolableObjectFactory#makeObject factory},
+ * passivate it, and then place it in the idle object pool.
+ * <code>addObject</code> is useful for "pre-loading" a pool with idle objects.
+ *
+ * @param key the key a new instance should be added to
+ * @throws Exception when {@link KeyedPoolableObjectFactory#makeObject} fails.
+ * @throws IllegalStateException when no {@link #setFactory factory} has been set or after {@link #close} has been called on this pool.
+ */
public synchronized void addObject(Object key) throws Exception {
+ assertOpen();
+ if (_factory == null) {
+ throw new IllegalStateException("Cannot add objects without a factory.");
+ }
Object obj = _factory.makeObject(key);
- incrementActiveCount(key); // returnObject will decrement this
- returnObject(key,obj);
+
+ // if we need to validate this object, do so
+ boolean success = true; // whether or not this object passed validation
+ if(_testOnReturn && !_factory.validateObject(key, obj)) {
+ success = false;
+ _factory.destroyObject(key, obj);
+ } else {
+ _factory.passivateObject(key, obj);
+ }
+
+ boolean shouldDestroy = false;
+ // grab the pool (list) of objects associated with the given key
+ LinkedList pool = (LinkedList) (_poolMap.get(key));
+ // if it doesn't exist, create it
+ if(null == pool) {
+ pool = new LinkedList();
+ _poolMap.put(key, pool);
+ }
+ // if there's no space in the pool, flag the object for destruction
+ // else if we passivated succesfully, return it to the pool
+ if(_maxIdle >= 0 && (pool.size() >= _maxIdle)) {
+ shouldDestroy = true;
+ } else if(success) {
+ pool.addLast(new ObjectTimestampPair(obj));
+ _totalIdle++;
+ }
+ notifyAll();
+
+ if(shouldDestroy) {
+ _factory.destroyObject(key, obj);
+ }
}
/**
* Registers a key for pool control.
*
- * If <i>populateImmediately</i> is <code>true</code>, the pool will immediately commence
- * a sustain cycle. If <i>populateImmediately</i> is <code>false</code>, the pool will be
+ * If <code>populateImmediately</code> is <code>true</code>, the pool will immediately commence
+ * a sustain cycle. If <code>populateImmediately</code> is <code>false</code>, the pool will be
* populated when the next schedules sustain task is run.
*
* @param key - The key to register for pool control.
@@ -1048,16 +1162,15 @@
public synchronized void close() throws Exception {
clear();
- _poolMap = null;
- _activeMap = null;
- _recentlyEvictedKeys = null;
- if(null != _evictor) {
+ if (null != _evictor) {
_evictor.cancel();
_evictor = null;
}
+ super.close();
}
public synchronized void setFactory(KeyedPoolableObjectFactory factory) throws IllegalStateException {
+ assertOpen();
if(0 < getNumActive()) {
throw new IllegalStateException("Objects are already active");
} else {
@@ -1066,6 +1179,9 @@
}
}
+ /**
+ * Remove any idle object that meet the criteria for eviction.
+ */
public synchronized void evict() throws Exception {
Object key = null;
if (_recentlyEvictedKeys == null) {
@@ -1138,7 +1254,7 @@
// Do not remove the key from the _poolList or _poolmap, even if the list
// stored in the _poolMap for this key is empty when the
- // {@link #getMinIdle <i>minIdle</i>} is > 0.
+ // {@link #getMinIdle <code>minIdle</code>} is > 0.
//
// Otherwise if it was the last object for that key, drop that pool
if ((_minIdle == 0) && (((LinkedList)(_poolMap.get(key))).isEmpty())) {
@@ -1207,7 +1323,7 @@
/**
* Start the eviction thread or service, or when
- * <i>delay</i> is non-positive, stop it
+ * <code>delay</code> is non-positive, stop it
* if it is already running.
*/
protected synchronized void startEvictor(long delay) {
@@ -1362,7 +1478,7 @@
/**
* A simple "struct" encapsulating the
- * configuration information for a {@link GenericKeyedObjectPool}.
+ * configuration information for a <code>GenericKeyedObjectPool</code>.
* @see GenericKeyedObjectPool#GenericKeyedObjectPool(KeyedPoolableObjectFactory,GenericKeyedObjectPool.Config)
* @see GenericKeyedObjectPool#setConfig
*/
@@ -1444,7 +1560,7 @@
private byte _whenExhaustedAction = DEFAULT_WHEN_EXHAUSTED_ACTION;
/**
- * When <tt>true</tt>, objects will be
+ * When <code>true</code>, objects will be
* {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
* before being returned by the {@link #borrowObject}
* method. If the object fails to validate,
@@ -1457,7 +1573,7 @@
private boolean _testOnBorrow = DEFAULT_TEST_ON_BORROW;
/**
- * When <tt>true</tt>, objects will be
+ * When <code>true</code>, objects will be
* {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
* before being returned to the pool within the
* {@link #returnObject}.
@@ -1468,7 +1584,7 @@
private boolean _testOnReturn = DEFAULT_TEST_ON_RETURN;
/**
- * When <tt>true</tt>, objects will be
+ * When <code>true</code>, objects will be
* {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
* by the idle object evictor (if any). If an object
* fails to validate, it will be dropped from the pool.
@@ -1495,8 +1611,8 @@
* 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 #getNumIdle})/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
+ * When a negative value is supplied, <code>ceil({@link #getNumIdle})/abs({@link #getNumTestsPerEvictionRun})</code>
+ * tests will be run. I.e., when the value is <code>-n</code>, roughly one <code>n</code>th of the
* idle objects will be tested per run.
*
* @see #setNumTestsPerEvictionRun
Modified: jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/StackKeyedObjectPool.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/StackKeyedObjectPool.java?rev=386186&r1=386185&r2=386186&view=diff
==============================================================================
--- jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/StackKeyedObjectPool.java (original)
+++ jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/StackKeyedObjectPool.java Wed Mar 15 14:28:20 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2004,2006 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,17 +16,17 @@
package org.apache.commons.pool.impl;
+import org.apache.commons.pool.BaseKeyedObjectPool;
+import org.apache.commons.pool.KeyedObjectPool;
+import org.apache.commons.pool.KeyedPoolableObjectFactory;
+
import java.util.HashMap;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Stack;
-import org.apache.commons.pool.BaseKeyedObjectPool;
-import org.apache.commons.pool.KeyedObjectPool;
-import org.apache.commons.pool.KeyedPoolableObjectFactory;
-
/**
- * A simple, {@link java.util.Stack Stack}-based {@link KeyedObjectPool} implementation.
+ * A simple, <code>Stack</code>-based <code>KeyedObjectPool</code> implementation.
* <p>
* Given a {@link KeyedPoolableObjectFactory}, this class will maintain
* a simple pool of instances. A finite number of "sleeping"
@@ -34,52 +34,62 @@
* empty, new instances are created to support the new load.
* Hence this class places no limit on the number of "active"
* instances created by the pool, but is quite useful for
- * re-using <tt>Object</tt>s without introducing
+ * re-using <code>Object</code>s without introducing
* artificial limits.
+ * </p>
*
* @author Rodney Waldhoff
- * @version $Revision$ $Date$
+ * @author Sandy McArthur
+ * @version $Revision$ $Date$
+ * @see Stack
*/
public class StackKeyedObjectPool extends BaseKeyedObjectPool implements KeyedObjectPool {
/**
- * Create a new pool using
- * no factory. Clients must first populate the pool
- * using {@link #returnObject(java.lang.Object,java.lang.Object)}
- * before they can be {@link #borrowObject(java.lang.Object) borrowed}.
+ * Create a new pool using no factory.
+ * Clients must first set the {@link #setFactory factory} or
+ * may populate the pool using {@link #returnObject returnObject}
+ * before they can be {@link #borrowObject borrowed}.
+ *
+ * @see #StackKeyedObjectPool(KeyedPoolableObjectFactory)
+ * @see #setFactory(KeyedPoolableObjectFactory)
*/
public StackKeyedObjectPool() {
this((KeyedPoolableObjectFactory)null,DEFAULT_MAX_SLEEPING,DEFAULT_INIT_SLEEPING_CAPACITY);
}
/**
- * Create a new pool using
- * no factory. Clients must first populate the pool
- * using {@link #returnObject(java.lang.Object,java.lang.Object)}
- * before they can be {@link #borrowObject(java.lang.Object) borrowed}.
+ * Create a new pool using no factory.
+ * Clients must first set the {@link #setFactory factory} or
+ * may populate the pool using {@link #returnObject returnObject}
+ * before they can be {@link #borrowObject borrowed}.
*
* @param max cap on the number of "sleeping" instances in the pool
+ * @see #StackKeyedObjectPool(KeyedPoolableObjectFactory, int)
+ * @see #setFactory(KeyedPoolableObjectFactory)
*/
public StackKeyedObjectPool(int max) {
this((KeyedPoolableObjectFactory)null,max,DEFAULT_INIT_SLEEPING_CAPACITY);
}
/**
- * Create a new pool using
- * no factory. Clients must first populate the pool
- * using {@link #returnObject(java.lang.Object,java.lang.Object)}
- * before they can be {@link #borrowObject(java.lang.Object) borrowed}.
+ * Create a new pool using no factory.
+ * Clients must first set the {@link #setFactory factory} or
+ * may populate the pool using {@link #returnObject returnObject}
+ * before they can be {@link #borrowObject borrowed}.
*
* @param max cap on the number of "sleeping" instances in the pool
* @param init initial size of the pool (this specifies the size of the container,
* it does not cause the pool to be pre-populated.)
+ * @see #StackKeyedObjectPool(KeyedPoolableObjectFactory, int, int)
+ * @see #setFactory(KeyedPoolableObjectFactory)
*/
public StackKeyedObjectPool(int max, int init) {
this((KeyedPoolableObjectFactory)null,max,init);
}
/**
- * Create a new <tt>SimpleKeyedObjectPool</tt> using
- * the specified <i>factory</i> to create new instances.
+ * Create a new <code>SimpleKeyedObjectPool</code> using
+ * the specified <code>factory</code> to create new instances.
*
* @param factory the {@link KeyedPoolableObjectFactory} used to populate the pool
*/
@@ -88,9 +98,9 @@
}
/**
- * Create a new <tt>SimpleKeyedObjectPool</tt> using
- * the specified <i>factory</i> to create new instances.
- * capping the number of "sleeping" instances to <i>max</i>
+ * Create a new <code>SimpleKeyedObjectPool</code> using
+ * the specified <code>factory</code> to create new instances.
+ * capping the number of "sleeping" instances to <code>max</code>
*
* @param factory the {@link KeyedPoolableObjectFactory} used to populate the pool
* @param max cap on the number of "sleeping" instances in the pool
@@ -100,11 +110,11 @@
}
/**
- * Create a new <tt>SimpleKeyedObjectPool</tt> using
- * the specified <i>factory</i> to create new instances.
- * capping the number of "sleeping" instances to <i>max</i>,
+ * Create a new <code>SimpleKeyedObjectPool</code> using
+ * the specified <code>factory</code> to create new instances.
+ * capping the number of "sleeping" instances to <code>max</code>,
* and initially allocating a container capable of containing
- * at least <i>init</i> instances.
+ * at least <code>init</code> instances.
*
* @param factory the {@link KeyedPoolableObjectFactory} used to populate the pool
* @param max cap on the number of "sleeping" instances in the pool
@@ -120,88 +130,203 @@
}
public synchronized Object borrowObject(Object key) throws Exception {
- Object obj = null;
+ assertOpen();
Stack stack = (Stack)(_pools.get(key));
if(null == stack) {
stack = new Stack();
stack.ensureCapacity( _initSleepingCapacity > _maxSleeping ? _maxSleeping : _initSleepingCapacity);
_pools.put(key,stack);
}
- try {
- obj = stack.pop();
- _totIdle--;
- } catch(Exception e) {
- if(null == _factory) {
- throw new NoSuchElementException();
+ Object obj = null;
+ do {
+ boolean newlyMade = false;
+ // TODO: Don't use exception, test size.
+ if (!stack.empty()) {
+ obj = stack.pop();
+ _totIdle--;
} else {
- obj = _factory.makeObject(key);
+ if(null == _factory) {
+ throw new NoSuchElementException("pools without a factory cannot create new objects as needed.");
+ } else {
+ obj = _factory.makeObject(key);
+ newlyMade = true;
+ }
}
- }
- if(null != obj && null != _factory) {
- _factory.activateObject(key,obj);
- }
+ if(!newlyMade && null != obj && null != _factory) {
+ try {
+ _factory.activateObject(key, obj);
+ if (!_factory.validateObject(key, obj)) {
+ try {
+ _factory.destroyObject(key, obj);
+ } catch (Exception e2) {
+ // swallowed
+ }
+ obj = null;
+ }
+ } catch (Exception e) {
+ try {
+ _factory.destroyObject(key, obj);
+ } catch (Exception e2) {
+ // swallowed
+ }
+ obj = null;
+ }
+ }
+ } while (obj == null);
incrementActiveCount(key);
return obj;
}
public synchronized void returnObject(Object key, Object obj) throws Exception {
decrementActiveCount(key);
- if(null == _factory || _factory.validateObject(key,obj)) {
- Stack stack = (Stack)(_pools.get(key));
- if(null == stack) {
- stack = new Stack();
- stack.ensureCapacity( _initSleepingCapacity > _maxSleeping ? _maxSleeping : _initSleepingCapacity);
- _pools.put(key,stack);
+ if (null != _factory) {
+ try {
+ _factory.passivateObject(key, obj);
+ } catch (Exception e) {
+ try {
+ _factory.destroyObject(key, obj);
+ } catch (Exception e2) {
+ // swallowed
+ }
+ return;
}
- if(null != _factory) {
+ }
+
+ if (isClosed()) {
+ if (null != _factory) {
try {
- _factory.passivateObject(key,obj);
- } catch(Exception e) {
- _factory.destroyObject(key,obj);
- return;
+ _factory.destroyObject(key, obj);
+ } catch (Exception e) {
+ // swallowed
}
}
- if(stack.size() < _maxSleeping) {
- stack.push(obj);
- _totIdle++;
+ return;
+ }
+
+ Stack stack = (Stack)_pools.get(key);
+ if(null == stack) {
+ stack = new Stack();
+ stack.ensureCapacity( _initSleepingCapacity > _maxSleeping ? _maxSleeping : _initSleepingCapacity);
+ _pools.put(key,stack);
+ }
+ final int stackSize = stack.size();
+ if (stackSize >= _maxSleeping) {
+ final Object staleObj;
+ if (stackSize > 0) {
+ staleObj = stack.remove(0);
+ _totIdle--;
} else {
- if(null != _factory) {
- _factory.destroyObject(key,obj);
- }
+ staleObj = obj;
}
- } else {
if(null != _factory) {
- _factory.destroyObject(key,obj);
+ try {
+ _factory.destroyObject(key, staleObj);
+ } catch (Exception e) {
+ // swallowed
+ }
}
}
+ stack.push(obj);
+ _totIdle++;
}
public synchronized void invalidateObject(Object key, Object obj) throws Exception {
decrementActiveCount(key);
if(null != _factory) {
+ try {
_factory.destroyObject(key,obj);
+ } catch (Exception e) {
+ // swallowed
+ }
}
notifyAll(); // _totalActive has changed
}
+ /**
+ * Create an object using the {@link KeyedPoolableObjectFactory#makeObject factory},
+ * passivate it, and then placed in the idle object pool.
+ * <code>addObject</code> is useful for "pre-loading" a pool with idle objects.
+ *
+ * @param key the key a new instance should be added to
+ * @throws Exception when {@link KeyedPoolableObjectFactory#makeObject} fails.
+ * @throws IllegalStateException when no {@link #setFactory factory} has been set or after {@link #close} has been called on this pool.
+ */
public synchronized void addObject(Object key) throws Exception {
+ assertOpen();
+ if (_factory == null) {
+ throw new IllegalStateException("Cannot add objects without a factory.");
+ }
Object obj = _factory.makeObject(key);
- incrementActiveCount(key); // returnObject will decrement this
- returnObject(key,obj);
+
+ _factory.passivateObject(key, obj);
+
+ Stack stack = (Stack)_pools.get(key);
+ if(null == stack) {
+ stack = new Stack();
+ stack.ensureCapacity( _initSleepingCapacity > _maxSleeping ? _maxSleeping : _initSleepingCapacity);
+ _pools.put(key,stack);
+ }
+
+ final int stackSize = stack.size();
+ if (stackSize >= _maxSleeping) {
+ final Object staleObj;
+ if (stackSize > 0) {
+ staleObj = stack.remove(0);
+ _totIdle--;
+ } else {
+ staleObj = obj;
+ }
+ if(null != _factory) {
+ try {
+ _factory.destroyObject(key, staleObj);
+ } catch (Exception e) {
+ // Don't swallow destroying the newly created object.
+ if (obj == staleObj) {
+ throw e;
+ }
+ }
+ }
+ } else {
+ stack.push(obj);
+ _totIdle++;
+ }
}
+ /**
+ * Returns the total number of instances currently idle in this pool.
+ *
+ * @return the total number of instances currently idle in this pool
+ */
public int getNumIdle() {
return _totIdle;
}
+ /**
+ * Returns the total number of instances current borrowed from this pool but not yet returned.
+ *
+ * @return the total number of instances currently borrowed from this pool
+ */
public int getNumActive() {
return _totActive;
}
+ /**
+ * Returns the number of instances currently borrowed from but not yet returned
+ * to the pool corresponding to the given <code>key</code>.
+ *
+ * @param key the key to query
+ * @return the number of instances corresponding to the given <code>key</code> currently borrowed in this pool
+ */
public synchronized int getNumActive(Object key) {
return getActiveCount(key);
}
+ /**
+ * Returns the number of instances corresponding to the given <code>key</code> currently idle in this pool.
+ *
+ * @param key the key to query
+ * @return the number of instances corresponding to the given <code>key</code> currently idle in this pool
+ */
public synchronized int getNumIdle(Object key) {
try {
return((Stack)(_pools.get(key))).size();
@@ -210,6 +335,9 @@
}
}
+ /**
+ * Clears the pool, removing all pooled instances.
+ */
public synchronized void clear() {
Iterator it = _pools.keySet().iterator();
while(it.hasNext()) {
@@ -222,6 +350,11 @@
_activeCount.clear();
}
+ /**
+ * Clears the specified pool, removing all pooled instances corresponding to the given <code>key</code>.
+ *
+ * @param key the key to clear
+ */
public synchronized void clear(Object key) {
Stack stack = (Stack)(_pools.remove(key));
destroyStack(key,stack);
@@ -261,13 +394,29 @@
return buf.toString();
}
+ /**
+ * Close this pool, and free any resources associated with it.
+ * <p>
+ * Calling {@link #addObject addObject} or {@link #borrowObject borrowObject} after invoking
+ * this method on a pool will cause them to throw an {@link IllegalStateException}.
+ * </p>
+ *
+ * @throws Exception <strong>deprecated</strong>: implementations should silently fail if not all resources can be freed.
+ */
public synchronized void close() throws Exception {
clear();
- _pools = null;
- _factory = null;
- _activeCount = null;
+ super.close();
}
+ /**
+ * Sets the {@link KeyedPoolableObjectFactory factory} the pool uses
+ * to create new instances.
+ * Trying to change the <code>factory</code> after a pool has been used will frequently
+ * throw an {@link UnsupportedOperationException}.
+ *
+ * @param factory the {@link KeyedPoolableObjectFactory} used to create new instances.
+ * @throws IllegalStateException when the factory cannot be set at this time
+ */
public synchronized void setFactory(KeyedPoolableObjectFactory factory) throws IllegalStateException {
if(0 < getNumActive()) {
throw new IllegalStateException("Objects are already active");
@@ -325,7 +474,7 @@
/** My {@link KeyedPoolableObjectFactory}. */
protected KeyedPoolableObjectFactory _factory = null;
- /** The cap on the number of "sleeping" instances in <i>each</i> pool. */
+ /** The cap on the number of "sleeping" instances in <code>each</code> pool. */
protected int _maxSleeping = DEFAULT_MAX_SLEEPING;
/** The initial capacity of each pool. */
Added: jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/MethodCall.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/MethodCall.java?rev=386186&view=auto
==============================================================================
--- jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/MethodCall.java (added)
+++ jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/MethodCall.java Wed Mar 15 14:28:20 2006
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.pool;
+
+import java.util.List;
+import java.util.Collections;
+import java.util.Arrays;
+
+/**
+ * Holds method names, parameters, and return values for tracing method calls.
+ *
+ * @author Sandy McArthur
+ * @version $Revision$ $Date$
+ */
+class MethodCall {
+ private final String name;
+ private final List params;
+ private Object returned;
+
+ MethodCall(final String name) {
+ this(name, null);
+ }
+
+ MethodCall(final String name, final Object param) {
+ this(name, Collections.singletonList(param));
+ }
+
+ MethodCall(final String name, final Object param1, final Object param2) {
+ this(name, Arrays.asList(new Object[] {param1, param2}));
+ }
+
+ MethodCall(final String name, final List params) {
+ if (name == null) {
+ throw new IllegalArgumentException("name must not be null.");
+ }
+ this.name = name;
+ if (params != null) {
+ this.params = params;
+ } else {
+ this.params = Collections.EMPTY_LIST;
+ }
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public List getParams() {
+ return params;
+ }
+
+ public Object getReturned() {
+ return returned;
+ }
+
+ public void setReturned(final Object returned) {
+ this.returned = returned;
+ }
+
+ public MethodCall returned(Object obj) {
+ setReturned(obj);
+ return this;
+ }
+
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ final MethodCall that = (MethodCall)o;
+
+ if (name != null ? !name.equals(that.name) : that.name != null) return false;
+ if (params != null ? !params.equals(that.params) : that.params != null) return false;
+ if (returned != null ? !returned.equals(that.returned) : that.returned != null) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = (name != null ? name.hashCode() : 0);
+ result = 29 * result + (params != null ? params.hashCode() : 0);
+ result = 29 * result + (returned != null ? returned.hashCode() : 0);
+ return result;
+ }
+
+ public String toString() {
+ final StringBuffer sb = new StringBuffer();
+ sb.append("MethodCall");
+ sb.append("{name='").append(name).append('\'');
+ if (!params.isEmpty()) {
+ sb.append(", params=").append(params);
+ }
+ if (returned != null) {
+ sb.append(", returned=").append(returned);
+ }
+ sb.append('}');
+ return sb.toString();
+ }
+}
Propchange: jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/MethodCall.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/MethodCall.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/PrivateException.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/PrivateException.java?rev=386186&view=auto
==============================================================================
--- jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/PrivateException.java (added)
+++ jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/PrivateException.java Wed Mar 15 14:28:20 2006
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.pool;
+
+/**
+ * An exception that only is thrown by this test.
+ */
+class PrivateException extends RuntimeException {
+ PrivateException(final String message) {
+ super(message);
+ }
+}
Propchange: jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/PrivateException.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/PrivateException.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Modified: jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/TestKeyedObjectPool.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/TestKeyedObjectPool.java?rev=386186&r1=386185&r2=386186&view=diff
==============================================================================
--- jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/TestKeyedObjectPool.java (original)
+++ jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/TestKeyedObjectPool.java Wed Mar 15 14:28:20 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2004,2006 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,13 @@
import junit.framework.TestCase;
+import java.util.List;
+import java.util.ArrayList;
+
/**
* Abstract {@link TestCase} for {@link ObjectPool} implementations.
* @author Rodney Waldhoff
+ * @author Sandy McArthur
* @version $Revision$ $Date$
*/
public abstract class TestKeyedObjectPool extends TestCase {
@@ -27,7 +31,7 @@
super(testName);
}
- /**
+ /**
* Create an {@link KeyedObjectPool} instance
* that can contain at least <i>mincapacity</i>
* idle and active objects, or
@@ -37,6 +41,14 @@
protected abstract KeyedObjectPool makeEmptyPool(int mincapacity);
/**
+ * Create an <code>KeyedObjectPool</code> with the specified factory.
+ * The pool should be in a default configuration and conform to the expected
+ * behaviors described in {@link KeyedObjectPool}.
+ * Generally speaking there should be no limits on the various object counts.
+ */
+ protected abstract KeyedObjectPool makeEmptyPool(KeyedPoolableObjectFactory factory);
+
+ /**
* Return what we expect to be the n<sup>th</sup>
* object (zero indexed) created by the pool
* for the given key.
@@ -44,26 +56,24 @@
protected abstract Object getNthObject(Object key, int n);
protected abstract Object makeKey(int n);
-
+
/**
* Is the implementations LIFO?
- * @return
*/
protected abstract boolean isLifo();
-
+
/**
* Is the implementationn FIFO?
- * @return
*/
protected abstract boolean isFifo();
public void setUp() throws Exception {
}
-
+
public void tearDown() throws Exception {
_pool = null;
}
-
+
public void testBaseBorrow() throws Exception {
try {
_pool = makeEmptyPool(3);
@@ -138,7 +148,7 @@
_pool.returnObject(keya,obj0);
assertEquals(0,_pool.getNumActive(keya));
assertEquals(2,_pool.getNumIdle(keya));
-
+
assertEquals(0,_pool.getNumActive("xyzzy12345"));
assertEquals(0,_pool.getNumIdle("xyzzy12345"));
}
@@ -277,5 +287,377 @@
}
}
+ private final String KEY = "key";
+
+ public void testClosedPoolBehavior() throws Exception {
+ final KeyedObjectPool pool = makeEmptyPool(new BaseKeyedPoolableObjectFactory() {
+ public Object makeObject(final Object key) throws Exception {
+ return new Object();
+ }
+ });
+ Object o1 = pool.borrowObject(KEY);
+ Object o2 = pool.borrowObject(KEY);
+
+ pool.close();
+
+ try {
+ pool.addObject(KEY);
+ fail("A closed pool must throw an IllegalStateException when addObject is called.");
+ } catch (IllegalStateException ise) {
+ // expected
+ }
+
+ try {
+ pool.borrowObject(KEY);
+ fail("A closed pool must throw an IllegalStateException when borrowObject is called.");
+ } catch (IllegalStateException ise) {
+ // expected
+ }
+
+ // The following should not throw exceptions just because the pool is closed.
+ assertEquals("A closed pool shouldn't have any idle objects.", 0, pool.getNumIdle(KEY));
+ assertEquals("A closed pool shouldn't have any idle objects.", 0, pool.getNumIdle());
+ pool.getNumActive();
+ pool.getNumActive(KEY);
+ pool.returnObject(KEY, o1);
+ assertEquals("returnObject should not add items back into the idle object pool for a closed pool.", 0, pool.getNumIdle(KEY));
+ assertEquals("returnObject should not add items back into the idle object pool for a closed pool.", 0, pool.getNumIdle());
+ pool.invalidateObject(KEY, o2);
+ pool.clear(KEY);
+ pool.clear();
+ pool.close();
+ }
+
+ private final Integer ZERO = new Integer(0);
+ private final Integer ONE = new Integer(1);
+
+ public void testKPOFAddObjectUsage() throws Exception {
+ final FailingKeyedPoolableObjectFactory factory = new FailingKeyedPoolableObjectFactory();
+ final KeyedObjectPool pool = makeEmptyPool(factory);
+ final List expectedMethods = new ArrayList();
+
+ // addObject should make a new object, pasivate it and put it in the pool
+ pool.addObject(KEY);
+ expectedMethods.add(new MethodCall("makeObject", KEY).returned(ZERO));
+ expectedMethods.add(new MethodCall("passivateObject", KEY, ZERO));
+ assertEquals(expectedMethods, factory.getMethodCalls());
+
+ //// Test exception handling of addObject
+ reset(pool, factory, expectedMethods);
+
+ // makeObject Exceptions should be propagated to client code from addObject
+ factory.setMakeObjectFail(true);
+ try {
+ pool.addObject(KEY);
+ fail("Expected addObject to propagate makeObject exception.");
+ } catch (PrivateException pe) {
+ // expected
+ }
+ expectedMethods.add(new MethodCall("makeObject", KEY));
+ assertEquals(expectedMethods, factory.getMethodCalls());
+
+ clear(factory, expectedMethods);
+
+ // passivateObject Exceptions should be propagated to client code from addObject
+ factory.setMakeObjectFail(false);
+ factory.setPassivateObjectFail(true);
+ try {
+ pool.addObject(KEY);
+ fail("Expected addObject to propagate passivateObject exception.");
+ } catch (PrivateException pe) {
+ // expected
+ }
+ expectedMethods.add(new MethodCall("makeObject", KEY).returned(ONE));
+ expectedMethods.add(new MethodCall("passivateObject", KEY, ONE));
+ assertEquals(expectedMethods, factory.getMethodCalls());
+ }
+
+ public void testKPOFBorrowObjectUsages() throws Exception {
+ final FailingKeyedPoolableObjectFactory factory = new FailingKeyedPoolableObjectFactory();
+ final KeyedObjectPool pool = makeEmptyPool(factory);
+ final List expectedMethods = new ArrayList();
+ Object obj;
+
+ /// Test correct behavior code paths
+
+ // existing idle object should be activated and validated
+ pool.addObject(KEY);
+ clear(factory, expectedMethods);
+ obj = pool.borrowObject(KEY);
+ expectedMethods.add(new MethodCall("activateObject", KEY, ZERO));
+ expectedMethods.add(new MethodCall("validateObject", KEY, ZERO).returned(Boolean.TRUE));
+ assertEquals(expectedMethods, factory.getMethodCalls());
+ pool.returnObject(KEY, obj);
+
+ //// Test exception handling of borrowObject
+ reset(pool, factory, expectedMethods);
+
+ // makeObject Exceptions should be propagated to client code from borrowObject
+ factory.setMakeObjectFail(true);
+ try {
+ obj = pool.borrowObject(KEY);
+ fail("Expected borrowObject to propagate makeObject exception.");
+ } catch (PrivateException pe) {
+ // expected
+ }
+ expectedMethods.add(new MethodCall("makeObject", KEY));
+ assertEquals(expectedMethods, factory.getMethodCalls());
+
+
+ // when activateObject fails in borrowObject, a new object should be borrowed/created
+ reset(pool, factory, expectedMethods);
+ pool.addObject(KEY);
+ clear(factory, expectedMethods);
+
+ factory.setActivateObjectFail(true);
+ expectedMethods.add(new MethodCall("activateObject", KEY, obj));
+ obj = pool.borrowObject(KEY);
+ expectedMethods.add(new MethodCall("makeObject", KEY).returned(ONE));
+ TestObjectPool.removeDestroyObjectCall(factory.getMethodCalls()); // The exact timing of destroyObject is flexible here.
+ assertEquals(expectedMethods, factory.getMethodCalls());
+ pool.returnObject(KEY, obj);
+
+ // when validateObject fails in borrowObject, a new object should be borrowed/created
+ reset(pool, factory, expectedMethods);
+ pool.addObject(KEY);
+ clear(factory, expectedMethods);
+
+ factory.setValidateObjectFail(true);
+ expectedMethods.add(new MethodCall("activateObject", KEY, ZERO));
+ expectedMethods.add(new MethodCall("validateObject", KEY, ZERO));
+ obj = pool.borrowObject(KEY);
+ expectedMethods.add(new MethodCall("makeObject", KEY).returned(ONE));
+ TestObjectPool.removeDestroyObjectCall(factory.getMethodCalls()); // The exact timing of destroyObject is flexible here.
+ assertEquals(expectedMethods, factory.getMethodCalls());
+ pool.returnObject(KEY, obj);
+ }
+
+ public void testKPOFReturnObjectUsages() throws Exception {
+ final FailingKeyedPoolableObjectFactory factory = new FailingKeyedPoolableObjectFactory();
+ final KeyedObjectPool pool = makeEmptyPool(factory);
+ final List expectedMethods = new ArrayList();
+ Object obj;
+ int idleCount;
+
+ /// Test correct behavior code paths
+ obj = pool.borrowObject(KEY);
+ clear(factory, expectedMethods);
+
+ // returned object should be passivated
+ pool.returnObject(KEY, obj);
+ expectedMethods.add(new MethodCall("passivateObject", KEY, obj));
+ assertEquals(expectedMethods, factory.getMethodCalls());
+
+ //// Test exception handling of returnObject
+ reset(pool, factory, expectedMethods);
+
+ // passivateObject should swallow exceptions and not add the object to the pool
+ idleCount = pool.getNumIdle();
+ obj = pool.borrowObject(KEY);
+ clear(factory, expectedMethods);
+ factory.setPassivateObjectFail(true);
+ pool.returnObject(KEY, obj);
+ expectedMethods.add(new MethodCall("passivateObject", KEY, obj));
+ TestObjectPool.removeDestroyObjectCall(factory.getMethodCalls()); // The exact timing of destroyObject is flexible here.
+ assertEquals(expectedMethods, factory.getMethodCalls());
+ assertEquals(idleCount, pool.getNumIdle());
+
+ // destroyObject should swallow exceptions too
+ reset(pool, factory, expectedMethods);
+ obj = pool.borrowObject(KEY);
+ clear(factory, expectedMethods);
+ factory.setPassivateObjectFail(true);
+ factory.setDestroyObjectFail(true);
+ pool.returnObject(KEY, obj);
+ }
+
+ public void testKPOFInvalidateObjectUsages() throws Exception {
+ final FailingKeyedPoolableObjectFactory factory = new FailingKeyedPoolableObjectFactory();
+ final KeyedObjectPool pool = makeEmptyPool(factory);
+ final List expectedMethods = new ArrayList();
+ Object obj;
+
+ /// Test correct behavior code paths
+
+ obj = pool.borrowObject(KEY);
+ clear(factory, expectedMethods);
+
+ // invalidated object should be destroyed
+ pool.invalidateObject(KEY, obj);
+ expectedMethods.add(new MethodCall("destroyObject", KEY, obj));
+ assertEquals(expectedMethods, factory.getMethodCalls());
+
+ //// Test exception handling of invalidateObject
+ reset(pool, factory, expectedMethods);
+ obj = pool.borrowObject(KEY);
+ clear(factory, expectedMethods);
+ factory.setDestroyObjectFail(true);
+ pool.invalidateObject(KEY, obj);
+ Thread.sleep(250); // could be defered
+ TestObjectPool.removeDestroyObjectCall(factory.getMethodCalls());
+ assertEquals(expectedMethods, factory.getMethodCalls());
+ }
+
+ public void testKPOFClearUsages() throws Exception {
+ final FailingKeyedPoolableObjectFactory factory = new FailingKeyedPoolableObjectFactory();
+ final KeyedObjectPool pool = makeEmptyPool(factory);
+ final List expectedMethods = new ArrayList();
+
+ /// Test correct behavior code paths
+ PoolUtils.prefill(pool, KEY, 5);
+ pool.clear();
+
+ //// Test exception handling clear should swallow destory object failures
+ reset(pool, factory, expectedMethods);
+ factory.setDestroyObjectFail(true);
+ PoolUtils.prefill(pool, KEY, 5);
+ pool.clear();
+ }
+
+ public void testKPOFCloseUsages() throws Exception {
+ final FailingKeyedPoolableObjectFactory factory = new FailingKeyedPoolableObjectFactory();
+ KeyedObjectPool pool = makeEmptyPool(factory);
+ final List expectedMethods = new ArrayList();
+
+ /// Test correct behavior code paths
+ PoolUtils.prefill(pool, KEY, 5);
+ pool.close();
+
+
+ //// Test exception handling close should swallow failures
+ pool = makeEmptyPool(factory);
+ reset(pool, factory, expectedMethods);
+ factory.setDestroyObjectFail(true);
+ PoolUtils.prefill(pool, KEY, 5);
+ pool.close();
+ }
+
+ private void reset(final KeyedObjectPool pool, final FailingKeyedPoolableObjectFactory factory, final List expectedMethods) throws Exception {
+ pool.clear();
+ clear(factory, expectedMethods);
+ factory.reset();
+ }
+
+ private void clear(final FailingKeyedPoolableObjectFactory factory, final List expectedMethods) {
+ factory.getMethodCalls().clear();
+ expectedMethods.clear();
+ }
+
private KeyedObjectPool _pool = null;
+
+ private static class FailingKeyedPoolableObjectFactory implements KeyedPoolableObjectFactory {
+ private final List methodCalls = new ArrayList();
+ private int count = 0;
+ private boolean makeObjectFail;
+ private boolean activateObjectFail;
+ private boolean validateObjectFail;
+ private boolean passivateObjectFail;
+ private boolean destroyObjectFail;
+
+ public void reset() {
+ count = 0;
+ getMethodCalls().clear();
+ setMakeObjectFail(false);
+ setActivateObjectFail(false);
+ setValidateObjectFail(false);
+ setPassivateObjectFail(false);
+ setDestroyObjectFail(false);
+ }
+
+ public List getMethodCalls() {
+ return methodCalls;
+ }
+
+ public int getCurrentCount() {
+ return count;
+ }
+
+ public void setCurrentCount(final int count) {
+ this.count = count;
+ }
+
+ public boolean isMakeObjectFail() {
+ return makeObjectFail;
+ }
+
+ public void setMakeObjectFail(boolean makeObjectFail) {
+ this.makeObjectFail = makeObjectFail;
+ }
+
+ public boolean isDestroyObjectFail() {
+ return destroyObjectFail;
+ }
+
+ public void setDestroyObjectFail(boolean destroyObjectFail) {
+ this.destroyObjectFail = destroyObjectFail;
+ }
+
+ public boolean isValidateObjectFail() {
+ return validateObjectFail;
+ }
+
+ public void setValidateObjectFail(boolean validateObjectFail) {
+ this.validateObjectFail = validateObjectFail;
+ }
+
+ public boolean isActivateObjectFail() {
+ return activateObjectFail;
+ }
+
+ public void setActivateObjectFail(boolean activateObjectFail) {
+ this.activateObjectFail = activateObjectFail;
+ }
+
+ public boolean isPassivateObjectFail() {
+ return passivateObjectFail;
+ }
+
+ public void setPassivateObjectFail(boolean passivateObjectFail) {
+ this.passivateObjectFail = passivateObjectFail;
+ }
+
+ public Object makeObject(final Object key) throws Exception {
+ final MethodCall call = new MethodCall("makeObject", key);
+ methodCalls.add(call);
+ int count = this.count++;
+ if (makeObjectFail) {
+ throw new PrivateException("makeObject");
+ }
+ final Integer obj = new Integer(count);
+ call.setReturned(obj);
+ return obj;
+ }
+
+ public void activateObject(final Object key, final Object obj) throws Exception {
+ methodCalls.add(new MethodCall("activateObject", key, obj));
+ if (activateObjectFail) {
+ throw new PrivateException("activateObject");
+ }
+ }
+
+ public boolean validateObject(final Object key, final Object obj) {
+ final MethodCall call = new MethodCall("validateObject", key, obj);
+ methodCalls.add(call);
+ if (validateObjectFail) {
+ throw new PrivateException("validateObject");
+ }
+ final boolean r = true;
+ call.returned(Boolean.valueOf(r));
+ return r;
+ }
+
+ public void passivateObject(final Object key, final Object obj) throws Exception {
+ methodCalls.add(new MethodCall("passivateObject", key, obj));
+ if (passivateObjectFail) {
+ throw new PrivateException("passivateObject");
+ }
+ }
+
+ public void destroyObject(final Object key, final Object obj) throws Exception {
+ methodCalls.add(new MethodCall("destroyObject", key, obj));
+ if (destroyObjectFail) {
+ throw new PrivateException("destroyObject");
+ }
+ }
+ }
}
Modified: jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/TestObjectPool.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/TestObjectPool.java?rev=386186&r1=386185&r2=386186&view=diff
==============================================================================
--- jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/TestObjectPool.java (original)
+++ jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/TestObjectPool.java Wed Mar 15 14:28:20 2006
@@ -18,7 +18,6 @@
import junit.framework.TestCase;
import java.util.List;
-import java.util.Collections;
import java.util.ArrayList;
import java.util.Iterator;
@@ -467,7 +466,7 @@
pool.close();
}
- private void removeDestroyObjectCall(List calls) {
+ static void removeDestroyObjectCall(List calls) {
Iterator iter = calls.iterator();
while (iter.hasNext()) {
MethodCall call = (MethodCall)iter.next();
@@ -603,97 +602,6 @@
if (destroyObjectFail) {
throw new PrivateException("destroyObject");
}
- }
- }
-
- private static class MethodCall {
- private final String name;
- private final List params;
- private Object returned;
-
- MethodCall(final String name) {
- this(name, null);
- }
-
- MethodCall(final String name, final Object param) {
- this(name, Collections.singletonList(param));
- }
-
- MethodCall(final String name, final List params) {
- if (name == null) {
- throw new IllegalArgumentException("name must not be null.");
- }
- this.name = name;
- if (params != null) {
- this.params = params;
- } else {
- this.params = Collections.EMPTY_LIST;
- }
- }
-
- public String getName() {
- return name;
- }
-
- public List getParams() {
- return params;
- }
-
- public Object getReturned() {
- return returned;
- }
-
- public void setReturned(final Object returned) {
- this.returned = returned;
- }
-
- public MethodCall returned(Object obj) {
- setReturned(obj);
- return this;
- }
-
- public boolean equals(final Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- final MethodCall that = (MethodCall)o;
-
- if (name != null ? !name.equals(that.name) : that.name != null) return false;
- if (params != null ? !params.equals(that.params) : that.params != null) return false;
- if (returned != null ? !returned.equals(that.returned) : that.returned != null) return false;
-
- return true;
- }
-
- public int hashCode() {
- int result;
- result = (name != null ? name.hashCode() : 0);
- result = 29 * result + (params != null ? params.hashCode() : 0);
- result = 29 * result + (returned != null ? returned.hashCode() : 0);
- return result;
- }
-
- public String toString() {
- final StringBuffer sb = new StringBuffer();
- sb.append("MethodCall");
- sb.append("{name='").append(name).append('\'');
- if (!params.isEmpty()) {
- sb.append(", params=").append(params);
- }
- if (returned != null) {
- sb.append(", returned=").append(returned);
- }
- sb.append('}');
- return sb.toString();
- }
- }
-
- /**
- * An exception that only is thrown by this test.
- */
- private static class PrivateException extends RuntimeException {
- PrivateException(final String message) {
- super(message);
}
}
}
Modified: jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/impl/TestGenericKeyedObjectPool.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/impl/TestGenericKeyedObjectPool.java?rev=386186&r1=386185&r2=386186&view=diff
==============================================================================
--- jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/impl/TestGenericKeyedObjectPool.java (original)
+++ jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/impl/TestGenericKeyedObjectPool.java Wed Mar 15 14:28:20 2006
@@ -63,6 +63,10 @@
return pool;
}
+ protected KeyedObjectPool makeEmptyPool(KeyedPoolableObjectFactory factory) {
+ return new GenericKeyedObjectPool(factory);
+ }
+
protected Object getNthObject(Object key, int n) {
return String.valueOf(key) + String.valueOf(n);
}
@@ -82,17 +86,6 @@
super.tearDown();
pool.close();
pool = null;
- }
-
- public void testWithInitiallyInvalid() throws Exception {
- GenericKeyedObjectPool pool = new GenericKeyedObjectPool(new SimpleFactory(false));
- pool.setTestOnBorrow(true);
- try {
- pool.borrowObject("xyzzy");
- fail("Expected NoSuchElementException");
- } catch(NoSuchElementException e) {
- // expected
- }
}
public void testNegativeMaxActive() throws Exception {
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org