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