001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.pool2.proxy;
018
019import java.util.List;
020
021import org.apache.commons.pool2.KeyedObjectPool;
022import org.apache.commons.pool2.UsageTracking;
023
024/**
025 * Create a new keyed object pool where the pooled objects are wrapped in
026 * proxies allowing better control of pooled objects and in particular the
027 * prevention of the continued use of an object by a client after that client
028 * returns the object to the pool.
029 *
030 * @param <K> type of the key
031 * @param <V> type of the pooled object
032 * @since 2.0
033 */
034public class ProxiedKeyedObjectPool<K, V> implements KeyedObjectPool<K, V> {
035
036    private final KeyedObjectPool<K, V> pool;
037    private final ProxySource<V> proxySource;
038
039    /**
040     * Constructs a new proxied object pool.
041     *
042     * @param pool  The object pool to wrap
043     * @param proxySource The source of the proxy objects
044     */
045    public ProxiedKeyedObjectPool(final KeyedObjectPool<K, V> pool,
046            final ProxySource<V> proxySource) {
047        this.pool = pool;
048        this.proxySource = proxySource;
049    }
050
051    @Override
052    public void addObject(final K key) throws Exception {
053        pool.addObject(key);
054    }
055
056    @SuppressWarnings("unchecked")
057    @Override
058    public V borrowObject(final K key) throws Exception {
059        UsageTracking<V> usageTracking = null;
060        if (pool instanceof UsageTracking) {
061            usageTracking = (UsageTracking<V>) pool;
062        }
063        return proxySource.createProxy(pool.borrowObject(key), usageTracking);
064    }
065
066    @Override
067    public void clear() throws Exception {
068        pool.clear();
069    }
070
071    @Override
072    public void clear(final K key) throws Exception {
073        pool.clear(key);
074    }
075
076    @Override
077    public void close() {
078        pool.close();
079    }
080
081    /**
082     * Gets a copy of the pool key list.
083     *
084     * @return a copy of the pool key list.
085     * @since 2.12.0
086     */
087    @Override
088    public List<K> getKeys() {
089        return pool.getKeys();
090    }
091
092    @Override
093    public int getNumActive() {
094        return pool.getNumActive();
095    }
096
097    @Override
098    public int getNumActive(final K key) {
099        return pool.getNumActive(key);
100    }
101
102    @Override
103    public int getNumIdle() {
104        return pool.getNumIdle();
105    }
106
107    @Override
108    public int getNumIdle(final K key) {
109        return pool.getNumIdle(key);
110    }
111
112    @Override
113    public void invalidateObject(final K key, final V proxy) throws Exception {
114        pool.invalidateObject(key, proxySource.resolveProxy(proxy));
115    }
116
117    @Override
118    public void returnObject(final K key, final V proxy) throws Exception {
119        pool.returnObject(key, proxySource.resolveProxy(proxy));
120    }
121
122    /**
123     * @since 2.4.3
124     */
125    @Override
126    public String toString() {
127        final StringBuilder builder = new StringBuilder();
128        builder.append("ProxiedKeyedObjectPool [pool=");
129        builder.append(pool);
130        builder.append(", proxySource=");
131        builder.append(proxySource);
132        builder.append("]");
133        return builder.toString();
134    }
135}