View Javadoc

1   /*
2    * $Id: CommonsPoolObjectPool.java 12269 2008-07-10 04:19:03Z dfeist $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.util.pool;
12  
13  import org.mule.api.lifecycle.Disposable;
14  import org.mule.api.lifecycle.InitialisationException;
15  import org.mule.api.object.ObjectFactory;
16  import org.mule.config.PoolingProfile;
17  import org.mule.config.i18n.MessageFactory;
18  
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import org.apache.commons.logging.Log;
23  import org.apache.commons.logging.LogFactory;
24  import org.apache.commons.pool.PoolableObjectFactory;
25  import org.apache.commons.pool.impl.GenericObjectPool;
26  
27  /**
28   * <code>CommonsPoolProxyPool</code> is an implementation of {@link ObjectPool}
29   * that internally uses the commons-pool {@link GenericObjectPool} and uses a
30   * {@link ObjectFactory} for creating new pooled instances.
31   */
32  public class CommonsPoolObjectPool implements ObjectPool
33  {
34      /**
35       * logger used by this class
36       */
37      protected static final Log logger = LogFactory.getLog(CommonsPoolObjectPool.class);
38  
39      /**
40       * The pool
41       */
42      protected GenericObjectPool pool;
43  
44      /**
45       * The ObjectFactory used to create new pool instances
46       */
47      protected ObjectFactory objectFactory;
48  
49      /**
50       * The pooling profile used to configure and initialise pool
51       */
52      protected PoolingProfile poolingProfile;
53  
54      /**
55       * Creates a new pool and an Object factory with the UMODescriptor
56       * 
57       * @param descriptor the descriptor to use when constructing MuleProxy objects in
58       *            the pool
59       */
60      public CommonsPoolObjectPool(ObjectFactory objectFactory, PoolingProfile poolingProfile)
61      {
62          this.objectFactory = objectFactory;
63          this.poolingProfile = poolingProfile;
64      }
65  
66      public void initialise() throws InitialisationException
67      {
68          GenericObjectPool.Config config = new GenericObjectPool.Config();
69  
70          if (poolingProfile != null)
71          {
72              config.maxIdle = poolingProfile.getMaxIdle();
73              config.maxActive = poolingProfile.getMaxActive();
74              config.maxWait = poolingProfile.getMaxWait();
75              config.whenExhaustedAction = (byte) poolingProfile.getExhaustedAction();
76          }
77  
78          pool = new GenericObjectPool(getPooledObjectFactory(), config);
79  
80          try
81          {
82              applyInitialisationPolicy();
83          }
84          catch (Exception e)
85          {
86              throw new InitialisationException(e, this);
87          }
88      }
89  
90      /**
91       * Template method to be overridden by implementations that do more than just
92       * invoke objectFactory
93       * 
94       * @return
95       */
96      protected PoolableObjectFactory getPooledObjectFactory()
97      {
98          return new PoolabeObjectFactoryAdaptor();
99      }
100 
101     protected void applyInitialisationPolicy() throws Exception
102     {
103         if (poolingProfile != null)
104         {
105             int numToBorrow = 0;
106             int initPolicy = poolingProfile.getInitialisationPolicy();
107 
108             if (initPolicy == PoolingProfile.INITIALISE_ALL)
109             {
110                 numToBorrow = poolingProfile.getMaxActive();
111             }
112             else if (initPolicy == PoolingProfile.INITIALISE_ONE)
113             {
114                 numToBorrow = 1;
115             }
116 
117             List holderList = new ArrayList(numToBorrow);
118             try
119             {
120                 for (int t = 0; t < numToBorrow; t++)
121                 {
122                     holderList.add(objectFactory.getInstance());
123                 }
124             }
125             finally
126             {
127                 for (int t = 0; t < holderList.size(); t++)
128                 {
129                     Object obj = holderList.get(t);
130                     if (obj != null)
131                     {
132                         this.returnObject(obj);
133                     }
134                 }
135             }
136         }
137     }
138 
139     public Object borrowObject() throws Exception
140     {
141         if (pool != null)
142         {
143             return pool.borrowObject();
144         }
145         else
146         {
147             throw new InitialisationException(
148                 MessageFactory.createStaticMessage("Object pool has not been initialized."), this);
149         }
150     }
151 
152     public void returnObject(Object object)
153     {
154         if (pool != null)
155         {
156             try
157             {
158                 pool.returnObject(object);
159             }
160             catch (Exception ex)
161             {
162                 // declared Exception is never thrown from pool; this is a known bug
163                 // in
164                 // the pool API
165             }
166         }
167     }
168 
169     public int getNumActive()
170     {
171         return pool.getNumActive();
172     }
173 
174     public int getMaxActive()
175     {
176         return pool.getMaxActive();
177     }
178 
179     public void dispose()
180     {
181         if (pool != null)
182         {
183             try
184             {
185                 pool.close();
186             }
187             catch (Exception e)
188             {
189                 // close() never throws - wrong method signature
190             }
191             finally
192             {
193                 pool = null;
194             }
195         }
196     }
197 
198     public void clear()
199     {
200         if (pool != null)
201         {
202             pool.clear();
203         }
204 
205     }
206 
207     public void close()
208     {
209         if (pool != null)
210         {
211             try
212             {
213                 pool.close();
214             }
215             catch (Exception e)
216             {
217                 // close() never throws - wrong method signature
218             }
219             finally
220             {
221                 pool = null;
222             }
223         }
224 
225     }
226 
227     public void setObjectFactory(ObjectFactory objectFactory)
228     {
229         this.objectFactory = objectFactory;
230     }
231 
232     public ObjectFactory getObjectFactory()
233     {
234         return objectFactory;
235     }
236 
237     /**
238      * Wraps org.mule.object.ObjectFactory with commons-pool PoolableObjectFactory
239      */
240     class PoolabeObjectFactoryAdaptor implements PoolableObjectFactory
241     {
242 
243         public void activateObject(Object obj) throws Exception
244         {
245             // nothing to do
246         }
247 
248         public void destroyObject(Object obj) throws Exception
249         {
250             if (obj instanceof Disposable)
251             {
252                 ((Disposable) obj).dispose();
253             }
254         }
255 
256         public Object makeObject() throws Exception
257         {
258             return objectFactory.getInstance();
259         }
260 
261         public void passivateObject(Object obj) throws Exception
262         {
263             // nothing to do
264         }
265 
266         public boolean validateObject(Object obj)
267         {
268             return true;
269         }
270 
271     }
272 
273 }