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;
018
019import java.util.NoSuchElementException;
020
021/**
022 * A "keyed" pooling interface.
023 * <p>
024 * A keyed pool maintains a pool of instances for each key value.
025 * <p>
026 * Example of use:
027 * <pre style="border:solid thin; padding: 1ex;"
028 * > Object obj = <code style="color:#00C">null</code>;
029 * Object key = <code style="color:#C00">"Key"</code>;
030 *
031 * <code style="color:#00C">try</code> {
032 *     obj = pool.borrowObject(key);
033 *     <code style="color:#0C0">//...use the object...</code>
034 * } <code style="color:#00C">catch</code>(Exception e) {
035 *     <code style="color:#0C0">// invalidate the object</code>
036 *     pool.invalidateObject(key, obj);
037 *     <code style="color:#0C0">// do not return the object to the pool twice</code>
038 *     obj = <code style="color:#00C">null</code>;
039 * } <code style="color:#00C">finally</code> {
040 *     <code style="color:#0C0">// make sure the object is returned to the pool</code>
041 *     <code style="color:#00C">if</code>(<code style="color:#00C">null</code> != obj) {
042 *         pool.returnObject(key, obj);
043 *     }
044 * }</pre>
045 * <p>
046 * {@link KeyedObjectPool} implementations <i>may</i> choose to store at most
047 * one instance per key value, or may choose to maintain a pool of instances
048 * for each key (essentially creating a {@link java.util.Map Map} of
049 * {@link ObjectPool pools}).
050 * <p>
051 * See {@link org.apache.commons.pool2.impl.GenericKeyedObjectPool
052 * GenericKeyedObjectPool} for an implementation.
053 *
054 * @param <K> The type of keys maintained by this pool.
055 * @param <V> Type of element pooled in this pool.
056 *
057 * @see KeyedPooledObjectFactory
058 * @see ObjectPool
059 * @see org.apache.commons.pool2.impl.GenericKeyedObjectPool GenericKeyedObjectPool
060 *
061 * @version $Revision: 1566605 $
062 *
063 * @since 2.0
064 */
065public interface KeyedObjectPool<K,V> {
066    /**
067     * Obtains an instance from this pool for the specified <code>key</code>.
068     * <p>
069     * Instances returned from this method will have been either newly created
070     * with {@link KeyedPooledObjectFactory#makeObject makeObject} or will be
071     * a previously idle object and have been activated with
072     * {@link KeyedPooledObjectFactory#activateObject activateObject} and then
073     * (optionally) validated with
074     * {@link KeyedPooledObjectFactory#validateObject validateObject}.
075     * <p>
076     * By contract, clients <strong>must</strong> return the borrowed object
077     * using {@link #returnObject returnObject},
078     * {@link #invalidateObject invalidateObject}, or a related method as
079     * defined in an implementation or sub-interface, using a <code>key</code>
080     * that is {@link Object#equals equivalent} to the one used to borrow the
081     * instance in the first place.
082     * <p>
083     * The behaviour of this method when the pool has been exhausted is not
084     * strictly specified (although it may be specified by implementations).
085     *
086     * @param key the key used to obtain the object
087     *
088     * @return an instance from this pool.
089     *
090     * @throws IllegalStateException
091     *              after {@link #close close} has been called on this pool
092     * @throws Exception
093     *              when {@link KeyedPooledObjectFactory#makeObject
094     *              makeObject} throws an exception
095     * @throws NoSuchElementException
096     *              when the pool is exhausted and cannot or will not return
097     *              another instance
098     */
099    V borrowObject(K key) throws Exception, NoSuchElementException, IllegalStateException;
100
101    /**
102     * Return an instance to the pool. By contract, <code>obj</code>
103     * <strong>must</strong> have been obtained using
104     * {@link #borrowObject borrowObject} or a related method as defined in an
105     * implementation or sub-interface using a <code>key</code> that is
106     * equivalent to the one used to borrow the instance in the first place.
107     *
108     * @param key the key used to obtain the object
109     * @param obj a {@link #borrowObject borrowed} instance to be returned.
110     *
111     * @throws IllegalStateException
112     *              if an attempt is made to return an object to the pool that
113     *              is in any state other than allocated (i.e. borrowed).
114     *              Attempting to return an object more than once or attempting
115     *              to return an object that was never borrowed from the pool
116     *              will trigger this exception.
117     *
118     * @throws Exception if an instance cannot be returned to the pool
119     */
120    void returnObject(K key, V obj) throws Exception;
121
122    /**
123     * Invalidates an object from the pool.
124     * <p>
125     * By contract, <code>obj</code> <strong>must</strong> have been obtained
126     * using {@link #borrowObject borrowObject} or a related method as defined
127     * in an implementation or sub-interface using a <code>key</code> that is
128     * equivalent to the one used to borrow the <code>Object</code> in the first
129     * place.
130     * <p>
131     * This method should be used when an object that has been borrowed is
132     * determined (due to an exception or other problem) to be invalid.
133     *
134     * @param key the key used to obtain the object
135     * @param obj a {@link #borrowObject borrowed} instance to be returned.
136     *
137     * @throws Exception if the instance cannot be invalidated
138     */
139    void invalidateObject(K key, V obj) throws Exception;
140
141    /**
142     * Create an object using the {@link KeyedPooledObjectFactory factory} or
143     * other implementation dependent mechanism, passivate it, and then place it
144     * in the idle object pool. <code>addObject</code> is useful for
145     * "pre-loading" a pool with idle objects (Optional operation).
146     *
147     * @param key the key a new instance should be added to
148     *
149     * @throws Exception
150     *              when {@link KeyedPooledObjectFactory#makeObject} fails.
151     * @throws IllegalStateException
152     *              after {@link #close} has been called on this pool.
153     * @throws UnsupportedOperationException
154     *              when this pool cannot add new idle objects.
155     */
156    void addObject(K key) throws Exception, IllegalStateException,
157            UnsupportedOperationException;
158
159    /**
160     * Returns the number of instances corresponding to the given
161     * <code>key</code> currently idle in this pool. Returns a negative value if
162     * this information is not available.
163     *
164     * @param key the key to query
165     * @return the number of instances corresponding to the given
166     * <code>key</code> currently idle in this pool.
167     */
168    int getNumIdle(K key);
169
170    /**
171     * Returns the number of instances currently borrowed from but not yet
172     * returned to the pool corresponding to the given <code>key</code>.
173     * Returns a negative value if this information is not available.
174     *
175     * @param key the key to query
176     * @return the number of instances currently borrowed from but not yet
177     * returned to the pool corresponding to the given <code>key</code>.
178=     */
179    int getNumActive(K key);
180
181    /**
182     * Returns the total number of instances currently idle in this pool.
183     * Returns a negative value if this information is not available.
184     * @return the total number of instances currently idle in this pool.
185 =    */
186    int getNumIdle();
187
188    /**
189     * Returns the total number of instances current borrowed from this pool but
190     * not yet returned. Returns a negative value if this information is not
191     * available.
192     * @return the total number of instances current borrowed from this pool but
193     * not yet returned.
194     */
195    int getNumActive();
196
197    /**
198     * Clears the pool, removing all pooled instances (optional operation).
199     *
200     * @throws UnsupportedOperationException when this implementation doesn't
201     *                                       support the operation
202     *
203     * @throws Exception if the pool cannot be cleared
204     */
205    void clear() throws Exception, UnsupportedOperationException;
206
207    /**
208     * Clears the specified pool, removing all pooled instances corresponding to
209     * the given <code>key</code> (optional operation).
210     *
211     * @param key the key to clear
212     *
213     * @throws UnsupportedOperationException when this implementation doesn't
214     *                                       support the operation
215     *
216     * @throws Exception if the key cannot be cleared
217     */
218    void clear(K key) throws Exception, UnsupportedOperationException;
219
220    /**
221     * Close this pool, and free any resources associated with it.
222     * <p>
223     * Calling {@link #addObject addObject} or
224     * {@link #borrowObject borrowObject} after invoking this method on a pool
225     * will cause them to throw an {@link IllegalStateException}.
226     * <p>
227     * Implementations should silently fail if not all resources can be freed.
228     */
229    void close();
230}