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/09 05:40:12 UTC
svn commit: r384427 - in /jakarta/commons/proper/pool/trunk/src:
java/org/apache/commons/pool/PoolUtils.java
test/org/apache/commons/pool/TestPoolUtils.java
Author: sandymac
Date: Wed Mar 8 20:40:10 2006
New Revision: 384427
URL: http://svn.apache.org/viewcvs?rev=384427&view=rev
Log:
Added type checking wrappers to PoolUtils.
Modified:
jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/PoolUtils.java
jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/TestPoolUtils.java
Modified: jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/PoolUtils.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/PoolUtils.java?rev=384427&r1=384426&r2=384427&view=diff
==============================================================================
--- jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/PoolUtils.java (original)
+++ jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/PoolUtils.java Wed Mar 8 20:40:10 2006
@@ -25,7 +25,7 @@
import java.util.TimerTask;
/**
- * This class consists exclusively of static methods that operate on or return pool related interfaces.
+ * This class consists exclusively of static methods that operate on or return keyedPool related interfaces.
*
* @author Sandy McArthur
* @version $Revision$ $Date$
@@ -118,29 +118,63 @@
* The key is ignored.
*
* @param pool the {@link ObjectPool} to delegate to.
- * @return a {@link KeyedObjectPool} that delegates to <code>pool</code> ignoring the key.
- * @throws IllegalArgumentException when <code>pool</code> is <code>null</code>.
+ * @return a {@link KeyedObjectPool} that delegates to <code>keyedPool</code> ignoring the key.
+ * @throws IllegalArgumentException when <code>keyedPool</code> is <code>null</code>.
*/
public static KeyedObjectPool adapt(final ObjectPool pool) throws IllegalArgumentException {
return new KeyedObjectPoolAdaptor(pool);
}
/**
- * Periodically check the idle object count for the pool. At most one idle object will be added per period.
+ * Wraps an <code>ObjectPool</code> and dynamically checks the type of objects borrowed and returned to the keyedPool.
+ * If an object is passed to the keyedPool that isn't of type <code>type</code> a {@link ClassCastException} will be thrown.
+ *
+ * @param pool the keyedPool to enforce type safety on
+ * @return an <code>ObjectPool</code> that will only allow objects of <code>type</code>
+ */
+ public static ObjectPool checkedPool(final ObjectPool pool, final Class type) {
+ if (pool == null) {
+ throw new IllegalArgumentException("pool must not be null.");
+ }
+ if (type == null) {
+ throw new IllegalArgumentException("type must not be null.");
+ }
+ return new CheckedObjectPool(pool, type);
+ }
+
+ /**
+ * Wraps an <code>KeyedObjectPool</code> and dynamically checks the type of objects borrowed and returned to the keyedPool.
+ * If an object is passed to the keyedPool that isn't of type <code>type</code> a {@link ClassCastException} will be thrown.
+ *
+ * @param keyedPool the keyedPool to enforce type safety on
+ * @return an <code>KeyedObjectPool</code> that will only allow objects of <code>type</code>
+ */
+ public static KeyedObjectPool checkedPool(final KeyedObjectPool keyedPool, final Class type) {
+ if (keyedPool == null) {
+ throw new IllegalArgumentException("keyedPool must not be null.");
+ }
+ if (type == null) {
+ throw new IllegalArgumentException("type must not be null.");
+ }
+ return new CheckedKeyedObjectPool(keyedPool, type);
+ }
+
+ /**
+ * Periodically check the idle object count for the keyedPool. At most one idle object will be added per period.
* If there is an exception when calling {@link ObjectPool#addObject()} then no more checks will be performed.
*
- * @param pool the pool to check periodically.
+ * @param pool the keyedPool to check periodically.
* @param minIdle if the {@link ObjectPool#getNumIdle()} is less than this then add an idle object.
- * @param period the frequency to check the number of idle objects in a pool, see
+ * @param period the frequency to check the number of idle objects in a keyedPool, see
* {@link Timer#schedule(TimerTask, long, long)}.
* @return the {@link TimerTask} that will periodically check the pools idle object count.
- * @throws IllegalArgumentException when <code>pool</code> is <code>null</code> or
+ * @throws IllegalArgumentException when <code>keyedPool</code> is <code>null</code> or
* when <code>minIdle</code> is negative or when <code>period</code> isn't
* valid for {@link Timer#schedule(TimerTask, long, long)}.
*/
public static TimerTask checkMinIdle(final ObjectPool pool, final int minIdle, final long period) throws IllegalArgumentException {
if (pool == null) {
- throw new IllegalArgumentException("pool must not be null.");
+ throw new IllegalArgumentException("keyedPool must not be null.");
}
if (minIdle < 0) {
throw new IllegalArgumentException("minIdle must be non-negative.");
@@ -151,14 +185,14 @@
}
/**
- * Periodically check the idle object count for the key in the pool. At most one idle object will be added per period.
+ * Periodically check the idle object count for the key in the keyedPool. At most one idle object will be added per period.
* If there is an exception when calling {@link KeyedObjectPool#addObject(Object)} then no more checks for that key
* will be performed.
*
- * @param keyedPool the pool to check periodically.
+ * @param keyedPool the keyedPool to check periodically.
* @param key the key to check the idle count of.
* @param minIdle if the {@link KeyedObjectPool#getNumIdle(Object)} is less than this then add an idle object.
- * @param period the frequency to check the number of idle objects in a pool, see
+ * @param period the frequency to check the number of idle objects in a keyedPool, see
* {@link Timer#schedule(TimerTask, long, long)}.
* @return the {@link TimerTask} that will periodically check the pools idle object count.
* @throws IllegalArgumentException when <code>keyedPool</code>, <code>key</code> is <code>null</code> or
@@ -181,13 +215,13 @@
}
/**
- * Periodically check the idle object count for each key in the <code>Collection</code> <code>keys</code> in the pool.
+ * Periodically check the idle object count for each key in the <code>Collection</code> <code>keys</code> in the keyedPool.
* At most one idle object will be added per period.
*
- * @param keyedPool the pool to check periodically.
+ * @param keyedPool the keyedPool to check periodically.
* @param keys a collection of keys to check the idle object count.
* @param minIdle if the {@link KeyedObjectPool#getNumIdle(Object)} is less than this then add an idle object.
- * @param period the frequency to check the number of idle objects in a pool, see
+ * @param period the frequency to check the number of idle objects in a keyedPool, see
* {@link Timer#schedule(TimerTask, long, long)}.
* @return a {@link Map} of key and {@link TimerTask} pairs that will periodically check the pools idle object count.
* @throws IllegalArgumentException when <code>keyedPool</code>, <code>keys</code>, or any of the values in the
@@ -210,16 +244,16 @@
}
/**
- * Call <code>addObject()</code> on <code>pool</code> <code>count</code> number of times.
+ * Call <code>addObject()</code> on <code>keyedPool</code> <code>count</code> number of times.
*
- * @param pool the pool to prefill.
+ * @param pool the keyedPool to prefill.
* @param count the number of idle objects to add.
* @throws Exception when {@link ObjectPool#addObject()} fails.
- * @throws IllegalArgumentException when <code>pool</code> is <code>null</code>.
+ * @throws IllegalArgumentException when <code>keyedPool</code> is <code>null</code>.
*/
public static void prefill(final ObjectPool pool, final int count) throws Exception, IllegalArgumentException {
if (pool == null) {
- throw new IllegalArgumentException("pool must not be null.");
+ throw new IllegalArgumentException("keyedPool must not be null.");
}
for (int i = 0; i < count; i++) {
pool.addObject();
@@ -230,7 +264,7 @@
* Call <code>addObject(Object)</code> on <code>keyedPool</code> with <code>key</code> <code>count</code>
* number of times.
*
- * @param keyedPool the pool to prefill.
+ * @param keyedPool the keyedPool to prefill.
* @param key the key to add objects for.
* @param count the number of idle objects to add for <code>key</code>.
* @throws Exception when {@link KeyedObjectPool#addObject(Object)} fails.
@@ -253,7 +287,7 @@
* <code>count</code> number of times. This has the same effect as calling
* {@link #prefill(KeyedObjectPool, Object, int)} for each key in the <code>keys</code> collection.
*
- * @param keyedPool the pool to prefill.
+ * @param keyedPool the keyedPool to prefill.
* @param keys {@link Collection} of keys to add objects for.
* @param count the number of idle objects to add for each <code>key</code>.
* @throws Exception when {@link KeyedObjectPool#addObject(Object)} fails.
@@ -308,8 +342,8 @@
}
/**
- * Get the <code>Timer</code> for checking pool's idle count. Lazily create the {@link Timer} as needed.
- * @return the {@link Timer} for checking pool's idle count.
+ * Get the <code>Timer</code> for checking keyedPool's idle count. Lazily create the {@link Timer} as needed.
+ * @return the {@link Timer} for checking keyedPool's idle count.
*/
private static synchronized Timer getMinIdleTimer() {
if (MIN_IDLE_TIMER == null) {
@@ -468,7 +502,7 @@
KeyedObjectPoolAdaptor(final ObjectPool pool) throws IllegalArgumentException {
if (pool == null) {
- throw new IllegalArgumentException("pool must not be null.");
+ throw new IllegalArgumentException("keyedPool must not be null.");
}
this.pool = pool;
}
@@ -524,7 +558,167 @@
public String toString() {
final StringBuffer sb = new StringBuffer();
sb.append("KeyedObjectPoolAdaptor");
- sb.append("{pool=").append(pool);
+ sb.append("{keyedPool=").append(pool);
+ sb.append('}');
+ return sb.toString();
+ }
+ }
+
+ private static class CheckedObjectPool implements ObjectPool {
+ private final Class type;
+ private final ObjectPool pool;
+
+ CheckedObjectPool(final ObjectPool pool, final Class type) {
+ if (pool == null) {
+ throw new IllegalArgumentException("pool must not be null.");
+ }
+ if (type == null) {
+ throw new IllegalArgumentException("type must not be null.");
+ }
+ this.pool = pool;
+ this.type = type;
+ }
+
+ public Object borrowObject() throws Exception, NoSuchElementException, IllegalStateException {
+ final Object obj = pool.borrowObject();
+ if (type.isInstance(obj)) {
+ return obj;
+ } else {
+ throw new ClassCastException("Borrowed object is not of type: " + type.getName() + " was: " + obj);
+ }
+ }
+
+ public void returnObject(final Object obj) throws Exception {
+ if (type.isInstance(obj)) {
+ pool.returnObject(obj);
+ } else {
+ throw new ClassCastException("Returned object is not of type: " + type.getName() + " was: " + obj);
+ }
+ }
+
+ public void invalidateObject(final Object obj) throws Exception {
+ if (type.isInstance(obj)) {
+ pool.invalidateObject(obj);
+ } else {
+ throw new ClassCastException("Invalidated object is not of type: " + type.getName() + " was: " + obj);
+ }
+ }
+
+ public void addObject() throws Exception, IllegalStateException, UnsupportedOperationException {
+ pool.addObject();
+ }
+
+ public int getNumIdle() throws UnsupportedOperationException {
+ return pool.getNumIdle();
+ }
+
+ public int getNumActive() throws UnsupportedOperationException {
+ return pool.getNumActive();
+ }
+
+ public void clear() throws Exception, UnsupportedOperationException {
+ pool.clear();
+ }
+
+ public void close() throws Exception {
+ pool.close();
+ }
+
+ public void setFactory(final PoolableObjectFactory factory) throws IllegalStateException, UnsupportedOperationException {
+ pool.setFactory(factory);
+ }
+
+ public String toString() {
+ final StringBuffer sb = new StringBuffer();
+ sb.append("CheckedObjectPool");
+ sb.append("{type=").append(type);
+ sb.append(", keyedPool=").append(pool);
+ sb.append('}');
+ return sb.toString();
+ }
+ }
+
+ private static class CheckedKeyedObjectPool implements KeyedObjectPool {
+ private final Class type;
+ private final KeyedObjectPool keyedPool;
+
+ CheckedKeyedObjectPool(final KeyedObjectPool keyedPool, final Class type) {
+ if (keyedPool == null) {
+ throw new IllegalArgumentException("keyedPool must not be null.");
+ }
+ if (type == null) {
+ throw new IllegalArgumentException("type must not be null.");
+ }
+ this.keyedPool = keyedPool;
+ this.type = type;
+ }
+
+ public Object borrowObject(final Object key) throws Exception, NoSuchElementException, IllegalStateException {
+ Object obj = keyedPool.borrowObject(key);
+ if (type.isInstance(obj)) {
+ return obj;
+ } else {
+ throw new ClassCastException("Borrowed object for key: " + key + " is not of type: " + type.getName() + " was: " + obj);
+ }
+ }
+
+ public void returnObject(final Object key, final Object obj) throws Exception {
+ if (type.isInstance(obj)) {
+ keyedPool.returnObject(key, obj);
+ } else {
+ throw new ClassCastException("Returned object for key: " + key + " is not of type: " + type.getName() + " was: " + obj);
+ }
+ }
+
+ public void invalidateObject(final Object key, final Object obj) throws Exception {
+ if (type.isInstance(obj)) {
+ keyedPool.invalidateObject(key, obj);
+ } else {
+ throw new ClassCastException("Invalidated object for key: " + key + " is not of type: " + type.getName() + " was: " + obj);
+ }
+ }
+
+ public void addObject(final Object key) throws Exception, IllegalStateException, UnsupportedOperationException {
+ keyedPool.addObject(key);
+ }
+
+ public int getNumIdle(final Object key) throws UnsupportedOperationException {
+ return keyedPool.getNumIdle(key);
+ }
+
+ public int getNumActive(final Object key) throws UnsupportedOperationException {
+ return keyedPool.getNumActive(key);
+ }
+
+ public int getNumIdle() throws UnsupportedOperationException {
+ return keyedPool.getNumIdle();
+ }
+
+ public int getNumActive() throws UnsupportedOperationException {
+ return keyedPool.getNumActive();
+ }
+
+ public void clear() throws Exception, UnsupportedOperationException {
+ keyedPool.clear();
+ }
+
+ public void clear(final Object key) throws Exception, UnsupportedOperationException {
+ keyedPool.clear(key);
+ }
+
+ public void close() throws Exception {
+ keyedPool.close();
+ }
+
+ public void setFactory(final KeyedPoolableObjectFactory factory) throws IllegalStateException, UnsupportedOperationException {
+ keyedPool.setFactory(factory);
+ }
+
+ public String toString() {
+ final StringBuffer sb = new StringBuffer();
+ sb.append("CheckedKeyedObjectPool");
+ sb.append("{type=").append(type);
+ sb.append(", keyedPool=").append(keyedPool);
sb.append('}');
return sb.toString();
}
@@ -565,7 +759,7 @@
final StringBuffer sb = new StringBuffer();
sb.append("ObjectPoolMinIdleTimerTask");
sb.append("{minIdle=").append(minIdle);
- sb.append(", pool=").append(pool);
+ sb.append(", keyedPool=").append(pool);
sb.append('}');
return sb.toString();
}
@@ -578,7 +772,7 @@
KeyedObjectPoolMinIdleTimerTask(final KeyedObjectPool pool, final Object key, final int minIdle) throws IllegalArgumentException {
if (pool == null) {
- throw new IllegalArgumentException("pool must not be null.");
+ throw new IllegalArgumentException("keyedPool must not be null.");
}
this.pool = pool;
this.key = key;
@@ -609,7 +803,7 @@
sb.append("KeyedObjectPoolMinIdleTimerTask");
sb.append("{minIdle=").append(minIdle);
sb.append(", key=").append(key);
- sb.append(", pool=").append(pool);
+ sb.append(", keyedPool=").append(pool);
sb.append('}');
return sb.toString();
}
@@ -621,7 +815,7 @@
SynchronizedObjectPool(final ObjectPool pool) throws IllegalArgumentException {
if (pool == null) {
- throw new IllegalArgumentException("pool must not be null.");
+ throw new IllegalArgumentException("keyedPool must not be null.");
}
this.pool = pool;
lock = new Object();
@@ -684,7 +878,7 @@
public String toString() {
final StringBuffer sb = new StringBuffer();
sb.append("SynchronizedObjectPool");
- sb.append("{pool=").append(pool);
+ sb.append("{keyedPool=").append(pool);
sb.append('}');
return sb.toString();
}
Modified: jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/TestPoolUtils.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/TestPoolUtils.java?rev=384427&r1=384426&r2=384427&view=diff
==============================================================================
--- jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/TestPoolUtils.java (original)
+++ jakarta/commons/proper/pool/trunk/src/test/org/apache/commons/pool/TestPoolUtils.java Wed Mar 8 20:40:10 2006
@@ -155,6 +155,109 @@
assertEquals(expectedMethods, calledMethods);
}
+ public void testCheckedPoolObjectPool() throws Exception {
+ try {
+ PoolUtils.checkedPool((ObjectPool)null, Object.class);
+ fail("PoolUtils.checkedPool(ObjectPool, Class) must not allow a null pool.");
+ } catch(IllegalArgumentException iae) {
+ // expected
+ }
+ try {
+ PoolUtils.checkedPool((ObjectPool)createProxy(ObjectPool.class, null), null);
+ fail("PoolUtils.checkedPool(ObjectPool, Class) must not allow a null type.");
+ } catch(IllegalArgumentException iae) {
+ // expected
+ }
+
+ final List calledMethods = new ArrayList();
+ ObjectPool op = (ObjectPool)createProxy(ObjectPool.class, calledMethods);
+
+ ObjectPool cop = PoolUtils.checkedPool(op, Object.class);
+ final List expectedMethods = invokeEveryMethod(cop);
+ assertEquals(expectedMethods, calledMethods);
+
+ op = new BaseObjectPool() {
+ public Object borrowObject() throws Exception {
+ return new Integer(0);
+ }
+ public void returnObject(Object obj) {}
+ public void invalidateObject(Object obj) {}
+ };
+ cop = PoolUtils.checkedPool(op, String.class);
+
+ try {
+ cop.borrowObject();
+ fail("borrowObject should have failed as Integer !instanceof String.");
+ } catch (ClassCastException cce) {
+ // expected
+ }
+ try {
+ cop.returnObject(new Integer(1));
+ fail("returnObject should have failed as Integer !instanceof String.");
+ } catch (ClassCastException cce) {
+ // expected
+ }
+ try {
+ cop.invalidateObject(new Integer(2));
+ fail("invalidateObject should have failed as Integer !instanceof String.");
+ } catch (ClassCastException cce) {
+ // expected
+ }
+ }
+
+ public void testCheckedPoolKeyedObjectPool() throws Exception {
+ try {
+ PoolUtils.checkedPool((KeyedObjectPool)null, Object.class);
+ fail("PoolUtils.checkedPool(KeyedObjectPool, Class) must not allow a null pool.");
+ } catch(IllegalArgumentException iae) {
+ // expected
+ }
+ try {
+ PoolUtils.checkedPool((KeyedObjectPool)createProxy(KeyedObjectPool.class, null), null);
+ fail("PoolUtils.checkedPool(KeyedObjectPool, Class) must not allow a null type.");
+ } catch(IllegalArgumentException iae) {
+ // expected
+ }
+
+ final List calledMethods = new ArrayList();
+ KeyedObjectPool op = (KeyedObjectPool)createProxy(KeyedObjectPool.class, calledMethods);
+
+ KeyedObjectPool cop = PoolUtils.checkedPool(op, Object.class);
+ final List expectedMethods = invokeEveryMethod(cop);
+ assertEquals(expectedMethods, calledMethods);
+
+
+ op = new BaseKeyedObjectPool() {
+ public Object borrowObject(Object key) {
+ return new Integer(0);
+ }
+
+ public void returnObject(Object key, Object obj) {}
+
+ public void invalidateObject(Object key, Object obj) {}
+ };
+ cop = PoolUtils.checkedPool(op, String.class);
+
+ try {
+ cop.borrowObject(null);
+ fail("borrowObject should have failed as Integer !instanceof String.");
+ } catch (ClassCastException cce) {
+ // expected
+ }
+ try {
+ cop.returnObject(null, new Integer(1));
+ fail("returnObject should have failed as Integer !instanceof String.");
+ } catch (ClassCastException cce) {
+ // expected
+ }
+ try {
+ cop.invalidateObject(null, new Integer(2));
+ fail("invalidateObject should have failed as Integer !instanceof String.");
+ } catch (ClassCastException cce) {
+ // expected
+ }
+ }
+
public void testCheckMinIdleObjectPool() throws Exception {
try {
PoolUtils.checkMinIdle(null, 1, 1);
@@ -459,8 +562,8 @@
op.close();
op.getNumActive();
op.getNumIdle();
- op.invalidateObject(null);
- op.returnObject(null);
+ op.invalidateObject(new Object());
+ op.returnObject(new Object());
op.setFactory((PoolableObjectFactory)createProxy(PoolableObjectFactory.class, null));
op.toString();
@@ -482,8 +585,8 @@
kop.getNumActive(null);
kop.getNumIdle();
kop.getNumIdle(null);
- kop.invalidateObject(null, null);
- kop.returnObject(null, null);
+ kop.invalidateObject(null, new Object());
+ kop.returnObject(null, new Object());
kop.setFactory((KeyedPoolableObjectFactory)createProxy(KeyedPoolableObjectFactory.class, null));
kop.toString();
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org