0001: /*
0002: * Copyright 2006 The Apache Software Foundation.
0003: *
0004: * Licensed under the Apache License, Version 2.0 (the "License");
0005: * you may not use this file except in compliance with the License.
0006: * You may obtain a copy of the License at
0007: *
0008: * http://www.apache.org/licenses/LICENSE-2.0
0009: *
0010: * Unless required by applicable law or agreed to in writing, software
0011: * distributed under the License is distributed on an "AS IS" BASIS,
0012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013: * See the License for the specific language governing permissions and
0014: * limitations under the License.
0015: */
0016:
0017: package org.apache.commons.pool;
0018:
0019: import java.util.Collection;
0020: import java.util.HashMap;
0021: import java.util.Iterator;
0022: import java.util.Map;
0023: import java.util.NoSuchElementException;
0024: import java.util.Timer;
0025: import java.util.TimerTask;
0026:
0027: /**
0028: * This class consists exclusively of static methods that operate on or return keyedPool related interfaces.
0029: *
0030: * @author Sandy McArthur
0031: * @version $Revision: 385296 $ $Date: 2006-03-12 10:28:08 -0500 (Sun, 12 Mar 2006) $
0032: * @since Pool 1.3
0033: */
0034: public final class PoolUtils {
0035:
0036: /**
0037: * Timer used to periodically check pools idle object count.
0038: * Because a {@link Timer} creates a {@link Thread} this is lazily instantiated.
0039: */
0040: private static Timer MIN_IDLE_TIMER;
0041:
0042: /**
0043: * PoolUtils instances should NOT be constructed in standard programming.
0044: * Instead, the class should be used procedurally: PoolUtils.adapt(aPool);.
0045: * This constructor is public to permit tools that require a JavaBean instance to operate.
0046: */
0047: public PoolUtils() {
0048: }
0049:
0050: /**
0051: * Adapt a <code>KeyedPoolableObjectFactory</code> instance to work where a <code>PoolableObjectFactory</code> is
0052: * needed. This method is the equivalent of calling
0053: * {@link #adapt(KeyedPoolableObjectFactory, Object) PoolUtils.adapt(aKeyedPoolableObjectFactory, new Object())}.
0054: *
0055: * @param keyedFactory the {@link KeyedPoolableObjectFactory} to delegate to.
0056: * @return a {@link PoolableObjectFactory} that delegates to <code>keyedFactory</code> with an internal key.
0057: * @throws IllegalArgumentException when <code>keyedFactory</code> is <code>null</code>.
0058: * @see #adapt(KeyedPoolableObjectFactory, Object)
0059: * @since Pool 1.3
0060: */
0061: public static PoolableObjectFactory adapt(
0062: final KeyedPoolableObjectFactory keyedFactory)
0063: throws IllegalArgumentException {
0064: return adapt(keyedFactory, new Object());
0065: }
0066:
0067: /**
0068: * Adapt a <code>KeyedPoolableObjectFactory</code> instance to work where a <code>PoolableObjectFactory</code> is
0069: * needed using the specified <code>key</code> when delegating.
0070: *
0071: * @param keyedFactory the {@link KeyedPoolableObjectFactory} to delegate to.
0072: * @param key the key to use when delegating.
0073: * @return a {@link PoolableObjectFactory} that delegates to <code>keyedFactory</code> with the specified key.
0074: * @throws IllegalArgumentException when <code>keyedFactory</code> or <code>key</code> is <code>null</code>.
0075: * @see #adapt(KeyedPoolableObjectFactory)
0076: * @since Pool 1.3
0077: */
0078: public static PoolableObjectFactory adapt(
0079: final KeyedPoolableObjectFactory keyedFactory,
0080: final Object key) throws IllegalArgumentException {
0081: return new PoolableObjectFactoryAdaptor(keyedFactory, key);
0082: }
0083:
0084: /**
0085: * Adapt a <code>PoolableObjectFactory</code> instance to work where a <code>KeyedPoolableObjectFactory</code> is
0086: * needed. The key is ignored.
0087: *
0088: * @param factory the {@link PoolableObjectFactory} to delegate to.
0089: * @return a {@link KeyedPoolableObjectFactory} that delegates to <code>factory</code> ignoring the key.
0090: * @throws IllegalArgumentException when <code>factory</code> is <code>null</code>.
0091: * @since Pool 1.3
0092: */
0093: public static KeyedPoolableObjectFactory adapt(
0094: final PoolableObjectFactory factory)
0095: throws IllegalArgumentException {
0096: return new KeyedPoolableObjectFactoryAdaptor(factory);
0097: }
0098:
0099: /**
0100: * Adapt a <code>KeyedObjectPool</code> instance to work where an <code>ObjectPool</code> is needed. This is the
0101: * equivalent of calling {@link #adapt(KeyedObjectPool, Object) PoolUtils.adapt(aKeyedObjectPool, new Object())}.
0102: *
0103: * @param keyedPool the {@link KeyedObjectPool} to delegate to.
0104: * @return an {@link ObjectPool} that delegates to <code>keyedPool</code> with an internal key.
0105: * @throws IllegalArgumentException when <code>keyedPool</code> is <code>null</code>.
0106: * @see #adapt(KeyedObjectPool, Object)
0107: * @since Pool 1.3
0108: */
0109: public static ObjectPool adapt(final KeyedObjectPool keyedPool)
0110: throws IllegalArgumentException {
0111: return adapt(keyedPool, new Object());
0112: }
0113:
0114: /**
0115: * Adapt a <code>KeyedObjectPool</code> instance to work where an <code>ObjectPool</code> is needed using the
0116: * specified <code>key</code> when delegating.
0117: *
0118: * @param keyedPool the {@link KeyedObjectPool} to delegate to.
0119: * @param key the key to use when delegating.
0120: * @return an {@link ObjectPool} that delegates to <code>keyedPool</code> with the specified key.
0121: * @throws IllegalArgumentException when <code>keyedPool</code> or <code>key</code> is <code>null</code>.
0122: * @see #adapt(KeyedObjectPool)
0123: * @since Pool 1.3
0124: */
0125: public static ObjectPool adapt(final KeyedObjectPool keyedPool,
0126: final Object key) throws IllegalArgumentException {
0127: return new ObjectPoolAdaptor(keyedPool, key);
0128: }
0129:
0130: /**
0131: * Adapt an <code>ObjectPool</code> to work where an <code>KeyedObjectPool</code> is needed.
0132: * The key is ignored.
0133: *
0134: * @param pool the {@link ObjectPool} to delegate to.
0135: * @return a {@link KeyedObjectPool} that delegates to <code>keyedPool</code> ignoring the key.
0136: * @throws IllegalArgumentException when <code>keyedPool</code> is <code>null</code>.
0137: * @since Pool 1.3
0138: */
0139: public static KeyedObjectPool adapt(final ObjectPool pool)
0140: throws IllegalArgumentException {
0141: return new KeyedObjectPoolAdaptor(pool);
0142: }
0143:
0144: /**
0145: * Wraps an <code>ObjectPool</code> and dynamically checks the type of objects borrowed and returned to the keyedPool.
0146: * If an object is passed to the keyedPool that isn't of type <code>type</code> a {@link ClassCastException} will be thrown.
0147: *
0148: * @param pool the keyedPool to enforce type safety on
0149: * @return an <code>ObjectPool</code> that will only allow objects of <code>type</code>
0150: * @since Pool 1.3
0151: */
0152: public static ObjectPool checkedPool(final ObjectPool pool,
0153: final Class type) {
0154: if (pool == null) {
0155: throw new IllegalArgumentException("pool must not be null.");
0156: }
0157: if (type == null) {
0158: throw new IllegalArgumentException("type must not be null.");
0159: }
0160: return new CheckedObjectPool(pool, type);
0161: }
0162:
0163: /**
0164: * Wraps an <code>KeyedObjectPool</code> and dynamically checks the type of objects borrowed and returned to the keyedPool.
0165: * If an object is passed to the keyedPool that isn't of type <code>type</code> a {@link ClassCastException} will be thrown.
0166: *
0167: * @param keyedPool the keyedPool to enforce type safety on
0168: * @return an <code>KeyedObjectPool</code> that will only allow objects of <code>type</code>
0169: * @since Pool 1.3
0170: */
0171: public static KeyedObjectPool checkedPool(
0172: final KeyedObjectPool keyedPool, final Class type) {
0173: if (keyedPool == null) {
0174: throw new IllegalArgumentException(
0175: "keyedPool must not be null.");
0176: }
0177: if (type == null) {
0178: throw new IllegalArgumentException("type must not be null.");
0179: }
0180: return new CheckedKeyedObjectPool(keyedPool, type);
0181: }
0182:
0183: /**
0184: * Periodically check the idle object count for the keyedPool. At most one idle object will be added per period.
0185: * If there is an exception when calling {@link ObjectPool#addObject()} then no more checks will be performed.
0186: *
0187: * @param pool the keyedPool to check periodically.
0188: * @param minIdle if the {@link ObjectPool#getNumIdle()} is less than this then add an idle object.
0189: * @param period the frequency to check the number of idle objects in a keyedPool, see
0190: * {@link Timer#schedule(TimerTask, long, long)}.
0191: * @return the {@link TimerTask} that will periodically check the pools idle object count.
0192: * @throws IllegalArgumentException when <code>keyedPool</code> is <code>null</code> or
0193: * when <code>minIdle</code> is negative or when <code>period</code> isn't
0194: * valid for {@link Timer#schedule(TimerTask, long, long)}.
0195: * @since Pool 1.3
0196: */
0197: public static TimerTask checkMinIdle(final ObjectPool pool,
0198: final int minIdle, final long period)
0199: throws IllegalArgumentException {
0200: if (pool == null) {
0201: throw new IllegalArgumentException(
0202: "keyedPool must not be null.");
0203: }
0204: if (minIdle < 0) {
0205: throw new IllegalArgumentException(
0206: "minIdle must be non-negative.");
0207: }
0208: final TimerTask task = new ObjectPoolMinIdleTimerTask(pool,
0209: minIdle);
0210: getMinIdleTimer().schedule(task, 0L, period);
0211: return task;
0212: }
0213:
0214: /**
0215: * Periodically check the idle object count for the key in the keyedPool. At most one idle object will be added per period.
0216: * If there is an exception when calling {@link KeyedObjectPool#addObject(Object)} then no more checks for that key
0217: * will be performed.
0218: *
0219: * @param keyedPool the keyedPool to check periodically.
0220: * @param key the key to check the idle count of.
0221: * @param minIdle if the {@link KeyedObjectPool#getNumIdle(Object)} is less than this then add an idle object.
0222: * @param period the frequency to check the number of idle objects in a keyedPool, see
0223: * {@link Timer#schedule(TimerTask, long, long)}.
0224: * @return the {@link TimerTask} that will periodically check the pools idle object count.
0225: * @throws IllegalArgumentException when <code>keyedPool</code>, <code>key</code> is <code>null</code> or
0226: * when <code>minIdle</code> is negative or when <code>period</code> isn't
0227: * valid for {@link Timer#schedule(TimerTask, long, long)}.
0228: * @since Pool 1.3
0229: */
0230: public static TimerTask checkMinIdle(
0231: final KeyedObjectPool keyedPool, final Object key,
0232: final int minIdle, final long period)
0233: throws IllegalArgumentException {
0234: if (keyedPool == null) {
0235: throw new IllegalArgumentException(
0236: "keyedPool must not be null.");
0237: }
0238: if (key == null) {
0239: throw new IllegalArgumentException("key must not be null.");
0240: }
0241: if (minIdle < 0) {
0242: throw new IllegalArgumentException(
0243: "minIdle must be non-negative.");
0244: }
0245: final TimerTask task = new KeyedObjectPoolMinIdleTimerTask(
0246: keyedPool, key, minIdle);
0247: getMinIdleTimer().schedule(task, 0L, period);
0248: return task;
0249: }
0250:
0251: /**
0252: * Periodically check the idle object count for each key in the <code>Collection</code> <code>keys</code> in the keyedPool.
0253: * At most one idle object will be added per period.
0254: *
0255: * @param keyedPool the keyedPool to check periodically.
0256: * @param keys a collection of keys to check the idle object count.
0257: * @param minIdle if the {@link KeyedObjectPool#getNumIdle(Object)} is less than this then add an idle object.
0258: * @param period the frequency to check the number of idle objects in a keyedPool, see
0259: * {@link Timer#schedule(TimerTask, long, long)}.
0260: * @return a {@link Map} of key and {@link TimerTask} pairs that will periodically check the pools idle object count.
0261: * @throws IllegalArgumentException when <code>keyedPool</code>, <code>keys</code>, or any of the values in the
0262: * collection is <code>null</code> or when <code>minIdle</code> is negative or when <code>period</code> isn't
0263: * valid for {@link Timer#schedule(TimerTask, long, long)}.
0264: * @see #checkMinIdle(KeyedObjectPool, Object, int, long)
0265: * @since Pool 1.3
0266: */
0267: public static Map checkMinIdle(final KeyedObjectPool keyedPool,
0268: final Collection keys, final int minIdle, final long period)
0269: throws IllegalArgumentException {
0270: if (keys == null) {
0271: throw new IllegalArgumentException("keys must not be null.");
0272: }
0273: final Map tasks = new HashMap(keys.size());
0274: final Iterator iter = keys.iterator();
0275: while (iter.hasNext()) {
0276: final Object key = iter.next();
0277: final TimerTask task = checkMinIdle(keyedPool, key,
0278: minIdle, period);
0279: tasks.put(key, task);
0280: }
0281: return tasks;
0282: }
0283:
0284: /**
0285: * Call <code>addObject()</code> on <code>keyedPool</code> <code>count</code> number of times.
0286: *
0287: * @param pool the keyedPool to prefill.
0288: * @param count the number of idle objects to add.
0289: * @throws Exception when {@link ObjectPool#addObject()} fails.
0290: * @throws IllegalArgumentException when <code>keyedPool</code> is <code>null</code>.
0291: * @since Pool 1.3
0292: */
0293: public static void prefill(final ObjectPool pool, final int count)
0294: throws Exception, IllegalArgumentException {
0295: if (pool == null) {
0296: throw new IllegalArgumentException(
0297: "keyedPool must not be null.");
0298: }
0299: for (int i = 0; i < count; i++) {
0300: pool.addObject();
0301: }
0302: }
0303:
0304: /**
0305: * Call <code>addObject(Object)</code> on <code>keyedPool</code> with <code>key</code> <code>count</code>
0306: * number of times.
0307: *
0308: * @param keyedPool the keyedPool to prefill.
0309: * @param key the key to add objects for.
0310: * @param count the number of idle objects to add for <code>key</code>.
0311: * @throws Exception when {@link KeyedObjectPool#addObject(Object)} fails.
0312: * @throws IllegalArgumentException when <code>keyedPool</code> or <code>key</code> is <code>null</code>.
0313: * @since Pool 1.3
0314: */
0315: public static void prefill(final KeyedObjectPool keyedPool,
0316: final Object key, final int count) throws Exception,
0317: IllegalArgumentException {
0318: if (keyedPool == null) {
0319: throw new IllegalArgumentException(
0320: "keyedPool must not be null.");
0321: }
0322: if (key == null) {
0323: throw new IllegalArgumentException("key must not be null.");
0324: }
0325: for (int i = 0; i < count; i++) {
0326: keyedPool.addObject(key);
0327: }
0328: }
0329:
0330: /**
0331: * Call <code>addObject(Object)</code> on <code>keyedPool</code> with each key in <code>keys</code> for
0332: * <code>count</code> number of times. This has the same effect as calling
0333: * {@link #prefill(KeyedObjectPool, Object, int)} for each key in the <code>keys</code> collection.
0334: *
0335: * @param keyedPool the keyedPool to prefill.
0336: * @param keys {@link Collection} of keys to add objects for.
0337: * @param count the number of idle objects to add for each <code>key</code>.
0338: * @throws Exception when {@link KeyedObjectPool#addObject(Object)} fails.
0339: * @throws IllegalArgumentException when <code>keyedPool</code>, <code>keys</code>, or
0340: * any value in <code>keys</code> is <code>null</code>.
0341: * @see #prefill(KeyedObjectPool, Object, int)
0342: * @since Pool 1.3
0343: */
0344: public static void prefill(final KeyedObjectPool keyedPool,
0345: final Collection keys, final int count) throws Exception,
0346: IllegalArgumentException {
0347: if (keys == null) {
0348: throw new IllegalArgumentException("keys must not be null.");
0349: }
0350: final Iterator iter = keys.iterator();
0351: while (iter.hasNext()) {
0352: prefill(keyedPool, iter.next(), count);
0353: }
0354: }
0355:
0356: /**
0357: * Returns a synchronized (thread-safe) ObjectPool backed by the specified ObjectPool.
0358: *
0359: * @param pool the ObjectPool to be "wrapped" in a synchronized ObjectPool.
0360: * @return a synchronized view of the specified ObjectPool.
0361: * @since Pool 1.3
0362: */
0363: public static ObjectPool synchronizedPool(final ObjectPool pool) {
0364: return new SynchronizedObjectPool(pool);
0365: }
0366:
0367: /**
0368: * Returns a synchronized (thread-safe) KeyedObjectPool backed by the specified KeyedObjectPool.
0369: *
0370: * @param keyedPool the KeyedObjectPool to be "wrapped" in a synchronized KeyedObjectPool.
0371: * @return a synchronized view of the specified KeyedObjectPool.
0372: * @since Pool 1.3
0373: */
0374: public static KeyedObjectPool synchronizedPool(
0375: final KeyedObjectPool keyedPool) {
0376: return new SynchronizedKeyedObjectPool(keyedPool);
0377: }
0378:
0379: /**
0380: * Returns a synchronized (thread-safe) PoolableObjectFactory backed by the specified PoolableObjectFactory.
0381: *
0382: * @param factory the PoolableObjectFactory to be "wrapped" in a synchronized PoolableObjectFactory.
0383: * @return a synchronized view of the specified PoolableObjectFactory.
0384: * @since Pool 1.3
0385: */
0386: public static PoolableObjectFactory synchronizedPoolableFactory(
0387: final PoolableObjectFactory factory) {
0388: return new SynchronizedPoolableObjectFactory(factory);
0389: }
0390:
0391: /**
0392: * Returns a synchronized (thread-safe) KeyedPoolableObjectFactory backed by the specified KeyedPoolableObjectFactory.
0393: *
0394: * @param keyedFactory the KeyedPoolableObjectFactory to be "wrapped" in a synchronized KeyedPoolableObjectFactory.
0395: * @return a synchronized view of the specified KeyedPoolableObjectFactory.
0396: * @since Pool 1.3
0397: */
0398: public static KeyedPoolableObjectFactory synchronizedPoolableFactory(
0399: final KeyedPoolableObjectFactory keyedFactory) {
0400: return new SynchronizedKeyedPoolableObjectFactory(keyedFactory);
0401: }
0402:
0403: /**
0404: * Get the <code>Timer</code> for checking keyedPool's idle count. Lazily create the {@link Timer} as needed.
0405: *
0406: * @return the {@link Timer} for checking keyedPool's idle count.
0407: * @since Pool 1.3
0408: */
0409: private static synchronized Timer getMinIdleTimer() {
0410: if (MIN_IDLE_TIMER == null) {
0411: MIN_IDLE_TIMER = new Timer(true);
0412: }
0413: return MIN_IDLE_TIMER;
0414: }
0415:
0416: private static class PoolableObjectFactoryAdaptor implements
0417: PoolableObjectFactory {
0418: private final Object key;
0419: private final KeyedPoolableObjectFactory keyedFactory;
0420:
0421: PoolableObjectFactoryAdaptor(
0422: final KeyedPoolableObjectFactory keyedFactory,
0423: final Object key) throws IllegalArgumentException {
0424: if (keyedFactory == null) {
0425: throw new IllegalArgumentException(
0426: "keyedFactory must not be null.");
0427: }
0428: if (key == null) {
0429: throw new IllegalArgumentException(
0430: "key must not be null.");
0431: }
0432: this .keyedFactory = keyedFactory;
0433: this .key = key;
0434: }
0435:
0436: public Object makeObject() throws Exception {
0437: return keyedFactory.makeObject(key);
0438: }
0439:
0440: public void destroyObject(final Object obj) throws Exception {
0441: keyedFactory.destroyObject(key, obj);
0442: }
0443:
0444: public boolean validateObject(final Object obj) {
0445: return keyedFactory.validateObject(key, obj);
0446: }
0447:
0448: public void activateObject(final Object obj) throws Exception {
0449: keyedFactory.activateObject(key, obj);
0450: }
0451:
0452: public void passivateObject(final Object obj) throws Exception {
0453: keyedFactory.passivateObject(key, obj);
0454: }
0455:
0456: public String toString() {
0457: final StringBuffer sb = new StringBuffer();
0458: sb.append("PoolableObjectFactoryAdaptor");
0459: sb.append("{key=").append(key);
0460: sb.append(", keyedFactory=").append(keyedFactory);
0461: sb.append('}');
0462: return sb.toString();
0463: }
0464: }
0465:
0466: private static class KeyedPoolableObjectFactoryAdaptor implements
0467: KeyedPoolableObjectFactory {
0468: private final PoolableObjectFactory factory;
0469:
0470: KeyedPoolableObjectFactoryAdaptor(
0471: final PoolableObjectFactory factory)
0472: throws IllegalArgumentException {
0473: if (factory == null) {
0474: throw new IllegalArgumentException(
0475: "factory must not be null.");
0476: }
0477: this .factory = factory;
0478: }
0479:
0480: public Object makeObject(final Object key) throws Exception {
0481: return factory.makeObject();
0482: }
0483:
0484: public void destroyObject(final Object key, final Object obj)
0485: throws Exception {
0486: factory.destroyObject(obj);
0487: }
0488:
0489: public boolean validateObject(final Object key, final Object obj) {
0490: return factory.validateObject(obj);
0491: }
0492:
0493: public void activateObject(final Object key, final Object obj)
0494: throws Exception {
0495: factory.activateObject(obj);
0496: }
0497:
0498: public void passivateObject(final Object key, final Object obj)
0499: throws Exception {
0500: factory.passivateObject(obj);
0501: }
0502:
0503: public String toString() {
0504: final StringBuffer sb = new StringBuffer();
0505: sb.append("KeyedPoolableObjectFactoryAdaptor");
0506: sb.append("{factory=").append(factory);
0507: sb.append('}');
0508: return sb.toString();
0509: }
0510: }
0511:
0512: private static class ObjectPoolAdaptor implements ObjectPool {
0513: private final Object key;
0514: private final KeyedObjectPool keyedPool;
0515:
0516: ObjectPoolAdaptor(final KeyedObjectPool keyedPool,
0517: final Object key) throws IllegalArgumentException {
0518: if (keyedPool == null) {
0519: throw new IllegalArgumentException(
0520: "keyedPool must not be null.");
0521: }
0522: if (key == null) {
0523: throw new IllegalArgumentException(
0524: "key must not be null.");
0525: }
0526: this .keyedPool = keyedPool;
0527: this .key = key;
0528: }
0529:
0530: public Object borrowObject() throws Exception,
0531: NoSuchElementException, IllegalStateException {
0532: return keyedPool.borrowObject(key);
0533: }
0534:
0535: public void returnObject(final Object obj) throws Exception {
0536: keyedPool.returnObject(key, obj);
0537: }
0538:
0539: public void invalidateObject(final Object obj) throws Exception {
0540: keyedPool.invalidateObject(key, obj);
0541: }
0542:
0543: public void addObject() throws Exception, IllegalStateException {
0544: keyedPool.addObject(key);
0545: }
0546:
0547: public int getNumIdle() throws UnsupportedOperationException {
0548: return keyedPool.getNumIdle(key);
0549: }
0550:
0551: public int getNumActive() throws UnsupportedOperationException {
0552: return keyedPool.getNumActive(key);
0553: }
0554:
0555: public void clear() throws Exception,
0556: UnsupportedOperationException {
0557: keyedPool.clear();
0558: }
0559:
0560: public void close() throws Exception {
0561: keyedPool.close();
0562: }
0563:
0564: public void setFactory(final PoolableObjectFactory factory)
0565: throws IllegalStateException,
0566: UnsupportedOperationException {
0567: keyedPool.setFactory(adapt(factory));
0568: }
0569:
0570: public String toString() {
0571: final StringBuffer sb = new StringBuffer();
0572: sb.append("ObjectPoolAdaptor");
0573: sb.append("{key=").append(key);
0574: sb.append(", keyedPool=").append(keyedPool);
0575: sb.append('}');
0576: return sb.toString();
0577: }
0578: }
0579:
0580: private static class KeyedObjectPoolAdaptor implements
0581: KeyedObjectPool {
0582: private final ObjectPool pool;
0583:
0584: KeyedObjectPoolAdaptor(final ObjectPool pool)
0585: throws IllegalArgumentException {
0586: if (pool == null) {
0587: throw new IllegalArgumentException(
0588: "keyedPool must not be null.");
0589: }
0590: this .pool = pool;
0591: }
0592:
0593: public Object borrowObject(final Object key) throws Exception,
0594: NoSuchElementException, IllegalStateException {
0595: return pool.borrowObject();
0596: }
0597:
0598: public void returnObject(final Object key, final Object obj)
0599: throws Exception {
0600: pool.returnObject(obj);
0601: }
0602:
0603: public void invalidateObject(final Object key, final Object obj)
0604: throws Exception {
0605: pool.invalidateObject(obj);
0606: }
0607:
0608: public void addObject(final Object key) throws Exception,
0609: IllegalStateException {
0610: pool.addObject();
0611: }
0612:
0613: public int getNumIdle(final Object key)
0614: throws UnsupportedOperationException {
0615: return pool.getNumIdle();
0616: }
0617:
0618: public int getNumActive(final Object key)
0619: throws UnsupportedOperationException {
0620: return pool.getNumActive();
0621: }
0622:
0623: public int getNumIdle() throws UnsupportedOperationException {
0624: return pool.getNumIdle();
0625: }
0626:
0627: public int getNumActive() throws UnsupportedOperationException {
0628: return pool.getNumActive();
0629: }
0630:
0631: public void clear() throws Exception,
0632: UnsupportedOperationException {
0633: pool.clear();
0634: }
0635:
0636: public void clear(final Object key) throws Exception,
0637: UnsupportedOperationException {
0638: pool.clear();
0639: }
0640:
0641: public void close() throws Exception {
0642: pool.close();
0643: }
0644:
0645: public void setFactory(final KeyedPoolableObjectFactory factory)
0646: throws IllegalStateException,
0647: UnsupportedOperationException {
0648: pool.setFactory(adapt(factory));
0649: }
0650:
0651: public String toString() {
0652: final StringBuffer sb = new StringBuffer();
0653: sb.append("KeyedObjectPoolAdaptor");
0654: sb.append("{keyedPool=").append(pool);
0655: sb.append('}');
0656: return sb.toString();
0657: }
0658: }
0659:
0660: private static class CheckedObjectPool implements ObjectPool {
0661: private final Class type;
0662: private final ObjectPool pool;
0663:
0664: CheckedObjectPool(final ObjectPool pool, final Class type) {
0665: if (pool == null) {
0666: throw new IllegalArgumentException(
0667: "pool must not be null.");
0668: }
0669: if (type == null) {
0670: throw new IllegalArgumentException(
0671: "type must not be null.");
0672: }
0673: this .pool = pool;
0674: this .type = type;
0675: }
0676:
0677: public Object borrowObject() throws Exception,
0678: NoSuchElementException, IllegalStateException {
0679: final Object obj = pool.borrowObject();
0680: if (type.isInstance(obj)) {
0681: return obj;
0682: } else {
0683: throw new ClassCastException(
0684: "Borrowed object is not of type: "
0685: + type.getName() + " was: " + obj);
0686: }
0687: }
0688:
0689: public void returnObject(final Object obj) throws Exception {
0690: if (type.isInstance(obj)) {
0691: pool.returnObject(obj);
0692: } else {
0693: throw new ClassCastException(
0694: "Returned object is not of type: "
0695: + type.getName() + " was: " + obj);
0696: }
0697: }
0698:
0699: public void invalidateObject(final Object obj) throws Exception {
0700: if (type.isInstance(obj)) {
0701: pool.invalidateObject(obj);
0702: } else {
0703: throw new ClassCastException(
0704: "Invalidated object is not of type: "
0705: + type.getName() + " was: " + obj);
0706: }
0707: }
0708:
0709: public void addObject() throws Exception,
0710: IllegalStateException, UnsupportedOperationException {
0711: pool.addObject();
0712: }
0713:
0714: public int getNumIdle() throws UnsupportedOperationException {
0715: return pool.getNumIdle();
0716: }
0717:
0718: public int getNumActive() throws UnsupportedOperationException {
0719: return pool.getNumActive();
0720: }
0721:
0722: public void clear() throws Exception,
0723: UnsupportedOperationException {
0724: pool.clear();
0725: }
0726:
0727: public void close() throws Exception {
0728: pool.close();
0729: }
0730:
0731: public void setFactory(final PoolableObjectFactory factory)
0732: throws IllegalStateException,
0733: UnsupportedOperationException {
0734: pool.setFactory(factory);
0735: }
0736:
0737: public String toString() {
0738: final StringBuffer sb = new StringBuffer();
0739: sb.append("CheckedObjectPool");
0740: sb.append("{type=").append(type);
0741: sb.append(", keyedPool=").append(pool);
0742: sb.append('}');
0743: return sb.toString();
0744: }
0745: }
0746:
0747: private static class CheckedKeyedObjectPool implements
0748: KeyedObjectPool {
0749: private final Class type;
0750: private final KeyedObjectPool keyedPool;
0751:
0752: CheckedKeyedObjectPool(final KeyedObjectPool keyedPool,
0753: final Class type) {
0754: if (keyedPool == null) {
0755: throw new IllegalArgumentException(
0756: "keyedPool must not be null.");
0757: }
0758: if (type == null) {
0759: throw new IllegalArgumentException(
0760: "type must not be null.");
0761: }
0762: this .keyedPool = keyedPool;
0763: this .type = type;
0764: }
0765:
0766: public Object borrowObject(final Object key) throws Exception,
0767: NoSuchElementException, IllegalStateException {
0768: Object obj = keyedPool.borrowObject(key);
0769: if (type.isInstance(obj)) {
0770: return obj;
0771: } else {
0772: throw new ClassCastException(
0773: "Borrowed object for key: " + key
0774: + " is not of type: " + type.getName()
0775: + " was: " + obj);
0776: }
0777: }
0778:
0779: public void returnObject(final Object key, final Object obj)
0780: throws Exception {
0781: if (type.isInstance(obj)) {
0782: keyedPool.returnObject(key, obj);
0783: } else {
0784: throw new ClassCastException(
0785: "Returned object for key: " + key
0786: + " is not of type: " + type.getName()
0787: + " was: " + obj);
0788: }
0789: }
0790:
0791: public void invalidateObject(final Object key, final Object obj)
0792: throws Exception {
0793: if (type.isInstance(obj)) {
0794: keyedPool.invalidateObject(key, obj);
0795: } else {
0796: throw new ClassCastException(
0797: "Invalidated object for key: " + key
0798: + " is not of type: " + type.getName()
0799: + " was: " + obj);
0800: }
0801: }
0802:
0803: public void addObject(final Object key) throws Exception,
0804: IllegalStateException, UnsupportedOperationException {
0805: keyedPool.addObject(key);
0806: }
0807:
0808: public int getNumIdle(final Object key)
0809: throws UnsupportedOperationException {
0810: return keyedPool.getNumIdle(key);
0811: }
0812:
0813: public int getNumActive(final Object key)
0814: throws UnsupportedOperationException {
0815: return keyedPool.getNumActive(key);
0816: }
0817:
0818: public int getNumIdle() throws UnsupportedOperationException {
0819: return keyedPool.getNumIdle();
0820: }
0821:
0822: public int getNumActive() throws UnsupportedOperationException {
0823: return keyedPool.getNumActive();
0824: }
0825:
0826: public void clear() throws Exception,
0827: UnsupportedOperationException {
0828: keyedPool.clear();
0829: }
0830:
0831: public void clear(final Object key) throws Exception,
0832: UnsupportedOperationException {
0833: keyedPool.clear(key);
0834: }
0835:
0836: public void close() throws Exception {
0837: keyedPool.close();
0838: }
0839:
0840: public void setFactory(final KeyedPoolableObjectFactory factory)
0841: throws IllegalStateException,
0842: UnsupportedOperationException {
0843: keyedPool.setFactory(factory);
0844: }
0845:
0846: public String toString() {
0847: final StringBuffer sb = new StringBuffer();
0848: sb.append("CheckedKeyedObjectPool");
0849: sb.append("{type=").append(type);
0850: sb.append(", keyedPool=").append(keyedPool);
0851: sb.append('}');
0852: return sb.toString();
0853: }
0854: }
0855:
0856: private static class ObjectPoolMinIdleTimerTask extends TimerTask {
0857: private final int minIdle;
0858: private final ObjectPool pool;
0859:
0860: ObjectPoolMinIdleTimerTask(final ObjectPool pool,
0861: final int minIdle) throws IllegalArgumentException {
0862: if (pool == null) {
0863: throw new IllegalArgumentException(
0864: "poll must not be null.");
0865: }
0866: this .pool = pool;
0867: this .minIdle = minIdle;
0868: }
0869:
0870: public void run() {
0871: boolean success = false;
0872: try {
0873: if (pool.getNumIdle() < minIdle) {
0874: pool.addObject();
0875: }
0876: success = true;
0877:
0878: } catch (Exception e) {
0879: cancel();
0880:
0881: } finally {
0882: // detect other types of Throwable and cancel this Timer
0883: if (!success) {
0884: cancel();
0885: }
0886: }
0887: }
0888:
0889: public String toString() {
0890: final StringBuffer sb = new StringBuffer();
0891: sb.append("ObjectPoolMinIdleTimerTask");
0892: sb.append("{minIdle=").append(minIdle);
0893: sb.append(", keyedPool=").append(pool);
0894: sb.append('}');
0895: return sb.toString();
0896: }
0897: }
0898:
0899: private static class KeyedObjectPoolMinIdleTimerTask extends
0900: TimerTask {
0901: private final int minIdle;
0902: private final Object key;
0903: private final KeyedObjectPool pool;
0904:
0905: KeyedObjectPoolMinIdleTimerTask(final KeyedObjectPool pool,
0906: final Object key, final int minIdle)
0907: throws IllegalArgumentException {
0908: if (pool == null) {
0909: throw new IllegalArgumentException(
0910: "keyedPool must not be null.");
0911: }
0912: this .pool = pool;
0913: this .key = key;
0914: this .minIdle = minIdle;
0915: }
0916:
0917: public void run() {
0918: boolean success = false;
0919: try {
0920: if (pool.getNumIdle(key) < minIdle) {
0921: pool.addObject(key);
0922: }
0923: success = true;
0924:
0925: } catch (Exception e) {
0926: cancel();
0927:
0928: } finally {
0929: // detect other types of Throwable and cancel this Timer
0930: if (!success) {
0931: cancel();
0932: }
0933: }
0934: }
0935:
0936: public String toString() {
0937: final StringBuffer sb = new StringBuffer();
0938: sb.append("KeyedObjectPoolMinIdleTimerTask");
0939: sb.append("{minIdle=").append(minIdle);
0940: sb.append(", key=").append(key);
0941: sb.append(", keyedPool=").append(pool);
0942: sb.append('}');
0943: return sb.toString();
0944: }
0945: }
0946:
0947: private static class SynchronizedObjectPool implements ObjectPool {
0948: private final Object lock;
0949: private final ObjectPool pool;
0950:
0951: SynchronizedObjectPool(final ObjectPool pool)
0952: throws IllegalArgumentException {
0953: if (pool == null) {
0954: throw new IllegalArgumentException(
0955: "keyedPool must not be null.");
0956: }
0957: this .pool = pool;
0958: lock = new Object();
0959: }
0960:
0961: public Object borrowObject() throws Exception,
0962: NoSuchElementException, IllegalStateException {
0963: synchronized (lock) {
0964: return pool.borrowObject();
0965: }
0966: }
0967:
0968: public void returnObject(final Object obj) throws Exception {
0969: synchronized (lock) {
0970: pool.returnObject(obj);
0971: }
0972: }
0973:
0974: public void invalidateObject(final Object obj) throws Exception {
0975: synchronized (lock) {
0976: pool.invalidateObject(obj);
0977: }
0978: }
0979:
0980: public void addObject() throws Exception,
0981: IllegalStateException, UnsupportedOperationException {
0982: synchronized (lock) {
0983: pool.addObject();
0984: }
0985: }
0986:
0987: public int getNumIdle() throws UnsupportedOperationException {
0988: synchronized (lock) {
0989: return pool.getNumIdle();
0990: }
0991: }
0992:
0993: public int getNumActive() throws UnsupportedOperationException {
0994: synchronized (lock) {
0995: return pool.getNumActive();
0996: }
0997: }
0998:
0999: public void clear() throws Exception,
1000: UnsupportedOperationException {
1001: synchronized (lock) {
1002: pool.clear();
1003: }
1004: }
1005:
1006: public void close() throws Exception {
1007: synchronized (lock) {
1008: pool.close();
1009: }
1010: }
1011:
1012: public void setFactory(final PoolableObjectFactory factory)
1013: throws IllegalStateException,
1014: UnsupportedOperationException {
1015: synchronized (lock) {
1016: pool.setFactory(factory);
1017: }
1018: }
1019:
1020: public String toString() {
1021: final StringBuffer sb = new StringBuffer();
1022: sb.append("SynchronizedObjectPool");
1023: sb.append("{keyedPool=").append(pool);
1024: sb.append('}');
1025: return sb.toString();
1026: }
1027: }
1028:
1029: private static class SynchronizedKeyedObjectPool implements
1030: KeyedObjectPool {
1031: private final Object lock;
1032: private final KeyedObjectPool keyedPool;
1033:
1034: SynchronizedKeyedObjectPool(final KeyedObjectPool keyedPool)
1035: throws IllegalArgumentException {
1036: if (keyedPool == null) {
1037: throw new IllegalArgumentException(
1038: "keyedPool must not be null.");
1039: }
1040: this .keyedPool = keyedPool;
1041: lock = new Object();
1042: }
1043:
1044: public Object borrowObject(final Object key) throws Exception,
1045: NoSuchElementException, IllegalStateException {
1046: synchronized (lock) {
1047: return keyedPool.borrowObject(key);
1048: }
1049: }
1050:
1051: public void returnObject(final Object key, final Object obj)
1052: throws Exception {
1053: synchronized (lock) {
1054: keyedPool.returnObject(key, obj);
1055: }
1056: }
1057:
1058: public void invalidateObject(final Object key, final Object obj)
1059: throws Exception {
1060: synchronized (lock) {
1061: keyedPool.invalidateObject(key, obj);
1062: }
1063: }
1064:
1065: public void addObject(final Object key) throws Exception,
1066: IllegalStateException, UnsupportedOperationException {
1067: synchronized (lock) {
1068: keyedPool.addObject(key);
1069: }
1070: }
1071:
1072: public int getNumIdle(final Object key)
1073: throws UnsupportedOperationException {
1074: synchronized (lock) {
1075: return keyedPool.getNumIdle(key);
1076: }
1077: }
1078:
1079: public int getNumActive(final Object key)
1080: throws UnsupportedOperationException {
1081: synchronized (lock) {
1082: return keyedPool.getNumActive(key);
1083: }
1084: }
1085:
1086: public int getNumIdle() throws UnsupportedOperationException {
1087: synchronized (lock) {
1088: return keyedPool.getNumIdle();
1089: }
1090: }
1091:
1092: public int getNumActive() throws UnsupportedOperationException {
1093: synchronized (lock) {
1094: return keyedPool.getNumActive();
1095: }
1096: }
1097:
1098: public void clear() throws Exception,
1099: UnsupportedOperationException {
1100: synchronized (lock) {
1101: keyedPool.clear();
1102: }
1103: }
1104:
1105: public void clear(final Object key) throws Exception,
1106: UnsupportedOperationException {
1107: synchronized (lock) {
1108: keyedPool.clear(key);
1109: }
1110: }
1111:
1112: public void close() throws Exception {
1113: synchronized (lock) {
1114: keyedPool.close();
1115: }
1116: }
1117:
1118: public void setFactory(final KeyedPoolableObjectFactory factory)
1119: throws IllegalStateException,
1120: UnsupportedOperationException {
1121: synchronized (lock) {
1122: keyedPool.setFactory(factory);
1123: }
1124: }
1125:
1126: public String toString() {
1127: final StringBuffer sb = new StringBuffer();
1128: sb.append("SynchronizedKeyedObjectPool");
1129: sb.append("{keyedPool=").append(keyedPool);
1130: sb.append('}');
1131: return sb.toString();
1132: }
1133: }
1134:
1135: private static class SynchronizedPoolableObjectFactory implements
1136: PoolableObjectFactory {
1137: private final Object lock;
1138: private final PoolableObjectFactory factory;
1139:
1140: SynchronizedPoolableObjectFactory(
1141: final PoolableObjectFactory factory)
1142: throws IllegalArgumentException {
1143: if (factory == null) {
1144: throw new IllegalArgumentException(
1145: "factory must not be null.");
1146: }
1147: this .factory = factory;
1148: lock = new Object();
1149: }
1150:
1151: public Object makeObject() throws Exception {
1152: synchronized (lock) {
1153: return factory.makeObject();
1154: }
1155: }
1156:
1157: public void destroyObject(final Object obj) throws Exception {
1158: synchronized (lock) {
1159: factory.destroyObject(obj);
1160: }
1161: }
1162:
1163: public boolean validateObject(final Object obj) {
1164: synchronized (lock) {
1165: return factory.validateObject(obj);
1166: }
1167: }
1168:
1169: public void activateObject(final Object obj) throws Exception {
1170: synchronized (lock) {
1171: factory.activateObject(obj);
1172: }
1173: }
1174:
1175: public void passivateObject(final Object obj) throws Exception {
1176: synchronized (lock) {
1177: factory.passivateObject(obj);
1178: }
1179: }
1180:
1181: public String toString() {
1182: final StringBuffer sb = new StringBuffer();
1183: sb.append("SynchronizedPoolableObjectFactory");
1184: sb.append("{factory=").append(factory);
1185: sb.append('}');
1186: return sb.toString();
1187: }
1188: }
1189:
1190: private static class SynchronizedKeyedPoolableObjectFactory
1191: implements KeyedPoolableObjectFactory {
1192: private final Object lock;
1193: private final KeyedPoolableObjectFactory keyedFactory;
1194:
1195: SynchronizedKeyedPoolableObjectFactory(
1196: final KeyedPoolableObjectFactory keyedFactory)
1197: throws IllegalArgumentException {
1198: if (keyedFactory == null) {
1199: throw new IllegalArgumentException(
1200: "keyedFactory must not be null.");
1201: }
1202: this .keyedFactory = keyedFactory;
1203: lock = new Object();
1204: }
1205:
1206: public Object makeObject(final Object key) throws Exception {
1207: synchronized (lock) {
1208: return keyedFactory.makeObject(key);
1209: }
1210: }
1211:
1212: public void destroyObject(final Object key, final Object obj)
1213: throws Exception {
1214: synchronized (lock) {
1215: keyedFactory.destroyObject(key, obj);
1216: }
1217: }
1218:
1219: public boolean validateObject(final Object key, final Object obj) {
1220: synchronized (lock) {
1221: return keyedFactory.validateObject(key, obj);
1222: }
1223: }
1224:
1225: public void activateObject(final Object key, final Object obj)
1226: throws Exception {
1227: synchronized (lock) {
1228: keyedFactory.activateObject(key, obj);
1229: }
1230: }
1231:
1232: public void passivateObject(final Object key, final Object obj)
1233: throws Exception {
1234: synchronized (lock) {
1235: keyedFactory.passivateObject(key, obj);
1236: }
1237: }
1238:
1239: public String toString() {
1240: final StringBuffer sb = new StringBuffer();
1241: sb.append("SynchronizedKeyedPoolableObjectFactory");
1242: sb.append("{keyedFactory=").append(keyedFactory);
1243: sb.append('}');
1244: return sb.toString();
1245: }
1246: }
1247: }
|