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: 1531140 $
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 Exception
112     */
113    void returnObject(K key, V obj) throws Exception;
114
115    /**
116     * Invalidates an object from the pool.
117     * <p>
118     * By contract, <code>obj</code> <strong>must</strong> have been obtained
119     * using {@link #borrowObject borrowObject} or a related method as defined
120     * in an implementation or sub-interface using a <code>key</code> that is
121     * equivalent to the one used to borrow the <code>Object</code> in the first
122     * place.
123     * <p>
124     * This method should be used when an object that has been borrowed is
125     * determined (due to an exception or other problem) to be invalid.
126     *
127     * @param key the key used to obtain the object
128     * @param obj a {@link #borrowObject borrowed} instance to be returned.
129     *
130     * @throws Exception
131     */
132    void invalidateObject(K key, V obj) throws Exception;
133
134    /**
135     * Create an object using the {@link KeyedPooledObjectFactory factory} or
136     * other implementation dependent mechanism, passivate it, and then place it
137     * in the idle object pool. <code>addObject</code> is useful for
138     * "pre-loading" a pool with idle objects (Optional operation).
139     *
140     * @param key the key a new instance should be added to
141     *
142     * @throws Exception
143     *              when {@link KeyedPooledObjectFactory#makeObject} fails.
144     * @throws IllegalStateException
145     *              after {@link #close} has been called on this pool.
146     * @throws UnsupportedOperationException
147     *              when this pool cannot add new idle objects.
148     */
149    void addObject(K key) throws Exception, IllegalStateException,
150            UnsupportedOperationException;
151
152    /**
153     * Returns the number of instances corresponding to the given
154     * <code>key</code> currently idle in this pool. Returns a negative value if
155     * this information is not available.
156     *
157     * @param key the key to query
158     * @return the number of instances corresponding to the given
159     * <code>key</code> currently idle in this pool.
160     */
161    int getNumIdle(K key);
162
163    /**
164     * Returns the number of instances currently borrowed from but not yet
165     * returned to the pool corresponding to the given <code>key</code>.
166     * Returns a negative value if this information is not available.
167     *
168     * @param key the key to query
169     * @return the number of instances currently borrowed from but not yet
170     * returned to the pool corresponding to the given <code>key</code>.
171=     */
172    int getNumActive(K key);
173
174    /**
175     * Returns the total number of instances currently idle in this pool.
176     * Returns a negative value if this information is not available.
177     * @return the total number of instances currently idle in this pool.
178 =    */
179    int getNumIdle();
180
181    /**
182     * Returns the total number of instances current borrowed from this pool but
183     * not yet returned. Returns a negative value if this information is not
184     * available.
185     * @return the total number of instances current borrowed from this pool but
186     * not yet returned.
187     */
188    int getNumActive();
189
190    /**
191     * Clears the pool, removing all pooled instances (optional operation).
192     *
193     * @throws UnsupportedOperationException when this implementation doesn't
194     *                                       support the operation
195     */
196    void clear() throws Exception, UnsupportedOperationException;
197
198    /**
199     * Clears the specified pool, removing all pooled instances corresponding to
200     * the given <code>key</code> (optional operation).
201     *
202     * @param key the key to clear
203     *
204     * @throws UnsupportedOperationException when this implementation doesn't
205     *                                       support the operation
206     */
207    void clear(K key) throws Exception, UnsupportedOperationException;
208
209    /**
210     * Close this pool, and free any resources associated with it.
211     * <p>
212     * Calling {@link #addObject addObject} or
213     * {@link #borrowObject borrowObject} after invoking this method on a pool
214     * will cause them to throw an {@link IllegalStateException}.
215     * <p>
216     * Implementations should silently fail if not all resources can be freed.
217     */
218    void close();
219}