KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > broker > core > PersistenceBrokerFactoryDefaultImpl


1 package org.apache.ojb.broker.core;
2
3 /* Copyright 2003-2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 import java.util.Properties JavaDoc;
19
20 import org.apache.commons.lang.builder.ToStringBuilder;
21 import org.apache.commons.lang.builder.ToStringStyle;
22 import org.apache.commons.pool.KeyedObjectPool;
23 import org.apache.commons.pool.KeyedPoolableObjectFactory;
24 import org.apache.commons.pool.impl.GenericKeyedObjectPool;
25 import org.apache.ojb.broker.PBFactoryException;
26 import org.apache.ojb.broker.PBKey;
27 import org.apache.ojb.broker.PBState;
28 import org.apache.ojb.broker.PersistenceBroker;
29 import org.apache.ojb.broker.PersistenceBrokerInternal;
30 import org.apache.ojb.broker.util.BrokerHelper;
31 import org.apache.ojb.broker.util.logging.Logger;
32 import org.apache.ojb.broker.util.logging.LoggerFactory;
33
34 /**
35  * This is the default implementation of the {@link PersistenceBrokerFactoryIF}
36  * interface.
37  * <p>
38  * This implementation use a pool of {@link org.apache.ojb.broker.PersistenceBroker}
39  * instances [abbr. PB]. Each pooled PB instance (the implementation class was specified
40  * in OJB configuration file) is wrapped by {@link PoolablePersistenceBroker} class
41  * before add to pool.
42  * </p>
43  * <p>
44  * When calling {@link #createPersistenceBroker} or {@link #defaultPersistenceBroker} the pooled-PB
45  * instance (<tt>PoolablePersistenceBroker</tt>) on its part was wrapped with {@link PersistenceBrokerHandle}
46  * handle.
47  * </p>
48  * <p>
49  * When a client do a PB.close() call on the handle the wrapped <tt>PoolablePersistenceBroker</tt> will
50  * be closed and returned to pool. All further method calls on the handle
51  * (except <tt>PB.isClosed()</tt> and <tt>PB.isInTransaction()</tt>) result in an exception.
52  * </p>
53  * Each different {@link org.apache.ojb.broker.PBKey} (based on <code>PBKey.equals(...)</code> method)
54  * get its own PB-pool.
55  *
56  * @see PersistenceBrokerFactoryBaseImpl
57  *
58  * @author <a HREF="mailto:thma@apache.org">Thomas Mahler<a>
59  * @author <a HREF="mailto:armin@codeAuLait.de">Armin Waibel</a>
60  * @version $Id: PersistenceBrokerFactoryDefaultImpl.java,v 1.11.2.4 2005/12/21 22:25:00 tomdz Exp $
61  */

62 public class PersistenceBrokerFactoryDefaultImpl extends PersistenceBrokerFactoryBaseImpl
63 {
64     private static Logger log = LoggerFactory.getLogger(PersistenceBrokerFactoryDefaultImpl.class);
65     private GenericKeyedObjectPool brokerPool;
66     private PBPoolInfo poolConfig;
67
68     public PersistenceBrokerFactoryDefaultImpl()
69     {
70         super();
71         // get PB-pool configuration properties from OJB.properties
72
poolConfig = new PBPoolInfo();
73         // setup pool for PB instances
74
brokerPool = this.createPool();
75         log.info("Create PersistenceBroker instance pool, pool configuration was " + getPoolConfiguration());
76     }
77
78     /**
79      * Return broker instance from pool. If given {@link PBKey} was not found in pool
80      * a new pool for given
81      * @param pbKey
82      * @return
83      * @throws PBFactoryException
84      */

85     public PersistenceBrokerInternal createPersistenceBroker(PBKey pbKey) throws PBFactoryException
86     {
87         if (log.isDebugEnabled()) log.debug("Obtain broker from pool, used PBKey is " + pbKey);
88         PersistenceBrokerInternal broker = null;
89
90         /*
91         try to find a valid PBKey, if given key does not full match
92         */

93         pbKey = BrokerHelper.crossCheckPBKey(pbKey);
94
95         try
96         {
97             /*
98             get a pooled PB instance, the pool is reponsible to create new
99             PB instances if not found in pool
100             */

101             broker = ((PersistenceBrokerInternal) brokerPool.borrowObject(pbKey));
102             /*
103             now warp pooled PB instance with a handle to avoid PB corruption
104             of closed PB instances.
105             */

106             broker = wrapRequestedBrokerInstance(broker);
107
108         }
109         catch (Exception JavaDoc e)
110         {
111             try
112             {
113                 // if something going wrong, tryto close broker
114
if(broker != null) broker.close();
115             }
116             catch (Exception JavaDoc ignore)
117             {
118                 //ignore it
119
}
120             throw new PBFactoryException("Borrow broker from pool failed, using PBKey " + pbKey, e);
121         }
122         return broker;
123     }
124
125     /**
126      * Each real pooled {@link PersistenceBroker} instance was wrapped by a
127      * pooling handle when a new instance was created.
128      *
129      * @see PoolablePersistenceBroker
130      * @param broker real {@link PersistenceBroker} instance
131      * @param pool use {@link KeyedObjectPool}
132      * @return wrapped broker instance
133      */

134     protected PersistenceBrokerInternal wrapBrokerWithPoolingHandle(PersistenceBrokerInternal broker, KeyedObjectPool pool)
135     {
136         return new PoolablePersistenceBroker(broker, pool);
137     }
138
139     /**
140      * Wraps the requested pooled broker instance. The returned handle
141      * warps a pooled broker instance to avoid corruption
142      * of already closed broker instances.
143      *
144      * @see PersistenceBrokerHandle
145      * @param broker
146      * @return The broker handle.
147      */

148     protected PersistenceBrokerInternal wrapRequestedBrokerInstance(PersistenceBrokerInternal broker)
149     {
150         return new PersistenceBrokerHandle(broker);
151     }
152
153     /**
154      * @see PersistenceBrokerFactoryIF#releaseAllInstances()
155      */

156     public synchronized void releaseAllInstances()
157     {
158         log.warn("Release all instances referenced by this object");
159         super.releaseAllInstances();
160         try
161         {
162             brokerPool.close();
163             brokerPool = this.createPool();
164         }
165         catch (Exception JavaDoc e)
166         {
167             log.error("Error while release all pooled broker instances and refresh pool", e);
168         }
169     }
170
171     public void shutdown()
172     {
173         try
174         {
175             brokerPool.close();
176             brokerPool = null;
177         }
178         catch(Exception JavaDoc e)
179         {
180             log.error("Error while shutdown of broker pool", e);
181         }
182         super.shutdown();
183     }
184
185     public int activePersistenceBroker()
186     {
187         return brokerPool.getNumActive();
188     }
189
190     /**
191      * could be used for monitoring
192      * TODO: is this useful?
193      */

194     public Properties JavaDoc getPoolConfiguration()
195     {
196         return poolConfig;
197     }
198
199     /**
200      * could be used for runtime configuration
201      * TODO: is this useful?
202      */

203     public void setPoolConfiguration(Properties JavaDoc prop)
204     {
205         poolConfig = new PBPoolInfo(prop);
206         log.info("Change pooling configuration properties: " + poolConfig.getKeyedObjectPoolConfig());
207         brokerPool.setConfig(poolConfig.getKeyedObjectPoolConfig());
208     }
209
210
211     /**
212      * Create the {@link org.apache.commons.pool.KeyedObjectPool}, pooling
213      * the {@link PersistenceBroker} instances - override this method to
214      * implement your own pool and {@link org.apache.commons.pool.KeyedPoolableObjectFactory}.
215      */

216     private GenericKeyedObjectPool createPool()
217     {
218         GenericKeyedObjectPool.Config conf = poolConfig.getKeyedObjectPoolConfig();
219         if (log.isDebugEnabled())
220             log.debug("PersistenceBroker pool will be setup with the following configuration " +
221                     ToStringBuilder.reflectionToString(conf, ToStringStyle.MULTI_LINE_STYLE));
222         GenericKeyedObjectPool pool = new GenericKeyedObjectPool(null, conf);
223         pool.setFactory(new PersistenceBrokerFactoryDefaultImpl.PBKeyedPoolableObjectFactory(this, pool));
224         return pool;
225     }
226
227 //**************************************************************************************
228
// Inner classes
229
//**************************************************************************************
230
//
231

232     /**
233      * This is a {@link org.apache.commons.pool.KeyedPoolableObjectFactory} implementation,
234      * manage the life-cycle of {@link PersistenceBroker} instances
235      * hold in an {@link org.apache.commons.pool.KeyedObjectPool}.
236      *
237      * @author <a HREF="mailto:armin@codeAuLait.de">Armin Waibel</a>
238      */

239     class PBKeyedPoolableObjectFactory implements KeyedPoolableObjectFactory
240     {
241         private PersistenceBrokerFactoryDefaultImpl pbf;
242         private KeyedObjectPool pool;
243
244         public PBKeyedPoolableObjectFactory(PersistenceBrokerFactoryDefaultImpl pbf, KeyedObjectPool pool)
245         {
246             this.pbf = pbf;
247             this.pool = pool;
248         }
249
250         public Object JavaDoc makeObject(Object JavaDoc key) throws Exception JavaDoc
251         {
252             return wrapBrokerWithPoolingHandle(pbf.createNewBrokerInstance((PBKey) key), pool);
253         }
254
255         /**
256          * Do all cleanup stuff here.
257          */

258         public void destroyObject(Object JavaDoc key, Object JavaDoc obj) throws Exception JavaDoc
259         {
260             PoolablePersistenceBroker pb = (PoolablePersistenceBroker) obj;
261             PersistenceBroker broker = pb.getInnermostDelegate();
262             if (broker instanceof PersistenceBrokerImpl)
263             {
264                 log.info("Destroy PersistenceBroker instance " + obj);
265                 ((PersistenceBrokerImpl) broker).destroy();
266             }
267             pb.destroy();
268         }
269
270         /**
271          * Check if the given PersistenceBroker instance
272          * was already in transaction.
273          * Was called when
274          * {@link PBPoolInfo#init}
275          * method does set <code>testOnBorrow(true)</code>.
276          * (Default was false, thus this method wasn't called)
277          * See documentation jakarta-connons-pool api.
278          */

279         public boolean validateObject(Object JavaDoc key, Object JavaDoc obj)
280         {
281             // here we could validate the PB instance
282
// if corresponding configuration properties are set
283
if (((PersistenceBroker) obj).isInTransaction())
284             {
285                 log.error("Illegal broker state! This broker instance was already in transaction.");
286                 return false;
287             }
288             return true;
289         }
290
291         /**
292          * Called before borrow object from pool.
293          */

294         public void activateObject(Object JavaDoc key, Object JavaDoc obj) throws Exception JavaDoc
295         {
296             ((PBState) obj).setClosed(false);
297         }
298
299         /**
300          * Called before return object to pool.
301          */

302         public void passivateObject(Object JavaDoc key, Object JavaDoc obj) throws Exception JavaDoc
303         {
304             ((PBState) obj).setClosed(true);
305         }
306     }
307 }
308
Popular Tags