View Javadoc

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