KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opensubsystems > core > persist > db > connectionpool > C3P0DatabaseConnectionFactoryImpl


1 /*
2  * Copyright (c) 2003 - 2007 OpenSubsystems s.r.o. Slovak Republic. All rights reserved.
3  *
4  * Project: OpenSubsystems
5  *
6  * $Id: C3P0DatabaseConnectionFactoryImpl.java,v 1.6 2007/01/07 06:14:58 bastafidli Exp $
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; version 2 of the License.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */

21
22 package org.opensubsystems.core.persist.db.connectionpool;
23
24 import java.sql.Connection JavaDoc;
25
26 import org.opensubsystems.core.error.OSSConfigException;
27 import org.opensubsystems.core.error.OSSDatabaseAccessException;
28 import org.opensubsystems.core.error.OSSException;
29 import org.opensubsystems.core.persist.db.DatabaseImpl;
30 import org.opensubsystems.core.persist.db.DatabaseTransactionFactoryImpl;
31
32 import com.mchange.v2.c3p0.ComboPooledDataSource;
33 import com.mchange.v2.c3p0.PooledDataSource;
34
35 /**
36  * Implementation of connection pool using C3P0 connection pool.
37  * (http://sourceforge.net/projects/c3p0/)
38  *
39  * @version $Id: C3P0DatabaseConnectionFactoryImpl.java,v 1.6 2007/01/07 06:14:58 bastafidli Exp $
40  * @author Julo Legeny
41  * @code.reviewer Miro Halas
42  * @code.reviewed 1.3 2006/04/11 07:16:22 bastafidli
43  */

44 public class C3P0DatabaseConnectionFactoryImpl extends PooledDatabaseConnectionFactoryImpl
45 {
46    // Constructors /////////////////////////////////////////////////////////////
47

48    /**
49     * Constructor for new instance using default database properties.
50     *
51     * @throws OSSConfigException - if there was an error accessing default database
52     * properties
53     * @throws OSSDatabaseAccessException - problem accessing the database
54     */

55    public C3P0DatabaseConnectionFactoryImpl(
56    ) throws OSSConfigException,
57             OSSDatabaseAccessException
58    {
59       super();
60       
61       // Use the default database properties
62
loadDefaultDatabaseProperties();
63
64       // Do not start it now because when we are creating pool we need to know
65
// what database we are running on and it would create circular dependency
66
// with DatabaseImpl
67
// start();
68
}
69    
70    /**
71     * Constructor for new instance using default database properties.
72     *
73     * @param transactionFactory - transaction factory to use for this
74     * connection factory, can be null
75     * @throws OSSConfigException - if there was an error accessing default database
76     * properties
77     * @throws OSSDatabaseAccessException - problem accessing the database
78     */

79    public C3P0DatabaseConnectionFactoryImpl(
80       DatabaseTransactionFactoryImpl transactionFactory
81    ) throws OSSConfigException,
82             OSSDatabaseAccessException
83    {
84       super(transactionFactory);
85
86       // Use the default database properties
87
loadDefaultDatabaseProperties();
88
89       // Do not start it know because when we are creating pool we need to know
90
// what database we are running on and it would create circular dependency
91
// with DatabaseImpl
92
// start();
93
}
94    
95    /**
96     * Constructor for new instance using explicitely specified properties.
97     *
98     * @param strDriver - JDBC driver to connect to the database
99     * @param strURL - URL of database to connect to
100     * @param strUser - user name to connect to the database
101     * @param strPassword - password to the database
102     * @param transactionFactory - transaction factory to use for this
103     * connection factory, can be null
104     * @throws OSSConfigException - problem accessing or locating the config file.
105     * @throws OSSDatabaseAccessException - problem accessing the database
106     */

107    public C3P0DatabaseConnectionFactoryImpl(
108       String JavaDoc strDriver,
109       String JavaDoc strURL,
110       String JavaDoc strUser,
111       String JavaDoc strPassword,
112       DatabaseTransactionFactoryImpl transactionFactory
113    ) throws OSSConfigException,
114             OSSDatabaseAccessException
115    {
116       super(strDriver, strURL, strUser, strPassword, transactionFactory);
117       
118       // Do not start it now because when we are creating pool we need to know
119
// what database we are running on and it would create circular dependency
120
// with DatabaseImpl
121
// start();
122
}
123
124    // Helper methods ///////////////////////////////////////////////////////////
125

126    /**
127     * {@inheritDoc}
128     */

129    protected Connection JavaDoc getPooledConnection(
130       ConnectionPoolDefinition connectionpool
131    ) throws OSSDatabaseAccessException
132    {
133       Connection JavaDoc conReturn;
134       
135       try
136       {
137          conReturn = (Connection JavaDoc)((PooledDataSource)
138                          connectionpool.getConnectionPool()).getConnection();
139       }
140       catch (Exception JavaDoc eExc)
141       {
142          // ComboPooledDataSource throws Exception so convert it to something more meaningful here
143
throw new OSSDatabaseAccessException("Cannot get database connection from pool.",
144                                               eExc);
145       }
146       
147       return conReturn;
148    }
149
150    /**
151     * {@inheritDoc}
152     */

153    protected Connection JavaDoc getPooledConnection(
154       ConnectionPoolDefinition connectionpool,
155       String JavaDoc strUser,
156       String JavaDoc strPassword
157    ) throws OSSDatabaseAccessException
158    {
159       Connection JavaDoc conReturn;
160       
161       try
162       {
163          conReturn = (Connection JavaDoc)((PooledDataSource)
164                          connectionpool.getConnectionPool()).getConnection(strUser,
165                                                                            strPassword);
166       }
167       catch (Exception JavaDoc eExc)
168       {
169          // ComboPooledDataSource throws Exception so convert it to something more meaningful here
170
throw new OSSDatabaseAccessException("Cannot get database connection from pool.",
171                                               eExc);
172       }
173       
174       return conReturn;
175    }
176
177    /**
178     * {@inheritDoc}
179     */

180    protected Object JavaDoc createConnectionPool(
181       String JavaDoc strConnectionPoolName,
182       String JavaDoc strDriverName,
183       String JavaDoc strUrl,
184       String JavaDoc strUser,
185       String JavaDoc strPassword
186    ) throws OSSException
187    {
188       PooledDatabaseConnectionFactorySetupReader setupReader
189           = new PooledDatabaseConnectionFactorySetupReader(strConnectionPoolName);
190
191       int iInitialPoolSize = setupReader.getIntegerParameterValue(
192                PooledDatabaseConnectionFactorySetupReader.DBPOOL_INITIAL_SIZE).intValue();
193       int iMinimalPoolSize = setupReader.getIntegerParameterValue(
194                PooledDatabaseConnectionFactorySetupReader.DBPOOL_MIN_SIZE).intValue();
195       int iMaximalPoolSize = setupReader.getIntegerParameterValue(
196                PooledDatabaseConnectionFactorySetupReader.DBPOOL_MAX_SIZE).intValue();
197 // boolean bCanGrow = setupReader.getBooleanParameterValue(
198
// PooledDatabaseConnectionFactorySetupReader.DBPOOL_CAN_GROW).booleanValue();
199
long lMaxWaitTimeForConnection = setupReader.getLongParameterValue(
200                PooledDatabaseConnectionFactorySetupReader.DBPOOL_WAIT_PERIOD).longValue();
201       boolean bValidateOnBorrow = setupReader.getBooleanParameterValue(
202                PooledDatabaseConnectionFactorySetupReader.DBPOOL_VALIDATE_BORROW).booleanValue();
203       boolean bValidateOnReturn = setupReader.getBooleanParameterValue(
204                PooledDatabaseConnectionFactorySetupReader.DBPOOL_VALIDATE_RETURN).booleanValue();
205       int iRetryCountForConnection = setupReader.getIntegerParameterValue(
206                PooledDatabaseConnectionFactorySetupReader.DBPOOL_RETRY_COUNT).intValue();
207       long lRetryTimeForConnection = setupReader.getLongParameterValue(
208                PooledDatabaseConnectionFactorySetupReader.DBPOOL_RETRY_PERIOD).longValue();
209       long lTimeBetweenEvictionRunsMillis = setupReader.getLongParameterValue(
210                PooledDatabaseConnectionFactorySetupReader.DBPOOL_IDLE_CHECK_PERIOD).longValue();
211       long lMinEvictableIdleTimeMillis = setupReader.getLongParameterValue(
212                PooledDatabaseConnectionFactorySetupReader.DBPOOL_IDLE_PERIOD).longValue();
213 // int iTransactionIsolation
214
// = DatabaseImpl.getInstance().getTransactionIsolation(
215
// PooledDatabaseConnectionFactorySetupReader.convertTransactionIsolationToConstant(
216
// setupReader.getStringParameterValue(
217
// PooledDatabaseConnectionFactorySetupReader.DBPOOL_TRANSACTION_ISOLATION)
218
// .toString()));
219
int iPreparedStatementCacheSize = setupReader.getIntegerParameterValue(
220                PooledDatabaseConnectionFactorySetupReader.DBPOOL_PREPSTATEMENT_CACHE_SIZE
221                   ).intValue();
222
223       ComboPooledDataSource pooledDS = null;
224
225       // Description of configuration properties is available at
226
// http://www.mchange.com/projects/c3p0/index.html#appendix_a
227
pooledDS = new ComboPooledDataSource();
228       pooledDS.setJdbcUrl(strUrl);
229       pooledDS.setUser(strUser);
230       pooledDS.setPassword(strPassword);
231       
232       // Create custom configured pooled data source
233
pooledDS.setInitialPoolSize(iInitialPoolSize);
234       pooledDS.setMinPoolSize(iMinimalPoolSize);
235       pooledDS.setMaxPoolSize(iMaximalPoolSize);
236       pooledDS.setMaxStatements(iPreparedStatementCacheSize);
237       // pooledDS.setMaxStatementsPerConnection() - not used since we support only global cache
238

239       // bCanGrow is not supported, c3p0 pool size cannot grow when all connections
240
// are already requested.
241
pooledDS.setAcquireIncrement(1);
242       pooledDS.setAcquireRetryAttempts(iRetryCountForConnection);
243       pooledDS.setAcquireRetryDelay((int)lRetryTimeForConnection);
244       // Do not automatically comit since our database layer should take care of this
245
pooledDS.setAutoCommitOnClose(false);
246       // pooledDS.setAutomaticTestTable - not used since we are using setPreferredTestQuery
247
pooledDS.setBreakAfterAcquireFailure(false);
248       pooledDS.setCheckoutTimeout((int)lMaxWaitTimeForConnection);
249       // pooledDS.setConnectionTesterClassName() - not used since we are using setPreferredTestQuery
250
// pooledDS.setFactoryClassLocation() - not used since I do not understand what it is
251
// pooledDS.setForceIgnoreUnresolvedTransactions() - not used since it is no clear
252
// C3P0 requires this time to be in seconds so convert it from milliseconds
253
pooledDS.setIdleConnectionTestPeriod((int)lTimeBetweenEvictionRunsMillis / 1000);
254       // C3P0 requires this time to be in seconds so convert it from milliseconds
255
pooledDS.setMaxIdleTime((int)lMinEvictableIdleTimeMillis / 1000);
256       // pooledDS.setNumHelperThreads() - left default value since it is hard to judge what to set
257
pooledDS.setPreferredTestQuery(DatabaseImpl.getInstance().getConnectionTestStatement());
258       // pooledDS.setPropertyCycle() - not used since it is ignored by C3P0
259
pooledDS.setTestConnectionOnCheckin(bValidateOnReturn);
260       pooledDS.setTestConnectionOnCheckout(bValidateOnBorrow);
261       // pooledDS.setUsesTraditionalReflectiveProxies() - not used only for backward compatibility
262

263       return pooledDS;
264    }
265
266    /**
267     * {@inheritDoc}
268     */

269    protected void closeConnectionPool(
270       ConnectionPoolDefinition connectionpool
271    ) throws OSSException
272    {
273       try
274       {
275          ((PooledDataSource)connectionpool.getConnectionPool()).close();
276          // We need to wait because c3p0 closes the connections
277
// asynchronously and we may get unexpected errors, e.g. when we want
278
// to drop user in test since the connection is still open for some time
279
// TODO: Improve: Either make this configurable or figure out a way
280
// how we can wait until the pool is really destroyed
281
Thread.sleep(1000);
282       }
283       catch (Exception JavaDoc eExc)
284       {
285          // ComboPooledDataSource throws Exception so convert it to something more meaningful here
286
throw new OSSDatabaseAccessException("Cannot close connection pool.", eExc);
287       }
288    }
289 }
290
Popular Tags