KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opencms > db > CmsDbPool


1 /*
2  * File : $Source: /usr/local/cvs/opencms/src/org/opencms/db/CmsDbPool.java,v $
3  * Date : $Date: 2006/10/04 15:09:43 $
4  * Version: $Revision: 1.46 $
5  *
6  * This library is part of OpenCms -
7  * the Open Source Content Mananagement System
8  *
9  * Copyright (c) 2005 Alkacon Software GmbH (http://www.alkacon.com)
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * For further information about Alkacon Software GmbH, please see the
22  * company website: http://www.alkacon.com
23  *
24  * For further information about OpenCms, please see the
25  * project website: http://www.opencms.org
26  *
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */

31
32 package org.opencms.db;
33
34 import org.opencms.main.CmsLog;
35 import org.opencms.util.CmsStringUtil;
36
37 import java.sql.Connection JavaDoc;
38 import java.util.ArrayList JavaDoc;
39 import java.util.List JavaDoc;
40 import java.util.Map JavaDoc;
41
42 import org.apache.commons.collections.ExtendedProperties;
43 import org.apache.commons.dbcp.ConnectionFactory;
44 import org.apache.commons.dbcp.DriverManagerConnectionFactory;
45 import org.apache.commons.dbcp.PoolableConnectionFactory;
46 import org.apache.commons.dbcp.PoolingDriver;
47 import org.apache.commons.pool.impl.GenericKeyedObjectPool;
48 import org.apache.commons.pool.impl.GenericKeyedObjectPoolFactory;
49 import org.apache.commons.pool.impl.GenericObjectPool;
50
51 /**
52  * Various methods to create DBCP pools.<p>
53  *
54  * Only JDBC Driver based pools are supported currently. JNDI DataSource
55  * based pools might be added probably later.<p>
56  *
57  * <b>Please note:</b> This class is subject to change in later versions.
58  * To obtain information about the connections, please use the
59  * {@link org.opencms.db.CmsSqlManager}.<p>
60  *
61  * @author Thomas Weckert
62  *
63  * @version $Revision: 1.46 $
64  *
65  * @since 6.0.0
66  */

67 public final class CmsDbPool {
68
69     /** This prefix is required to make the JDBC DriverManager return pooled DBCP connections. */
70     public static final String JavaDoc DBCP_JDBC_URL_PREFIX = "jdbc:apache:commons:dbcp:";
71
72     /** Prefix for database keys. */
73     public static final String JavaDoc KEY_DATABASE = "db.";
74
75     /** Key for the database name. */
76     public static final String JavaDoc KEY_DATABASE_NAME = KEY_DATABASE + "name";
77
78     /** Key for the pool id. */
79     public static final String JavaDoc KEY_DATABASE_POOL = KEY_DATABASE + "pool";
80
81     /** Key for statement pooling. */
82     public static final String JavaDoc KEY_DATABASE_STATEMENTS = KEY_DATABASE + "statements";
83
84     /** Key for jdbc driver. */
85     public static final String JavaDoc KEY_JDBC_DRIVER = "jdbcDriver";
86
87     /** Key for jdbc url. */
88     public static final String JavaDoc KEY_JDBC_URL = "jdbcUrl";
89
90     /** Key for jdbc url params. */
91     public static final String JavaDoc KEY_JDBC_URL_PARAMS = KEY_JDBC_URL + ".params";
92
93     /** Key for maximum active connections. */
94     public static final String JavaDoc KEY_MAX_ACTIVE = "maxActive";
95
96     /** Key for maximum idle connections. */
97     public static final String JavaDoc KEY_MAX_IDLE = "maxIdle";
98
99     /** Key for maximum wait time. */
100     public static final String JavaDoc KEY_MAX_WAIT = "maxWait";
101
102     /** Key for minimum idle time before a connection is subject to an eviction test. */
103     public static final String JavaDoc KEY_MIN_EVICTABLE_IDLE_TIME = "minEvictableIdleTime";
104
105     /** Key for minimum number of connections kept open. */
106     public static final String JavaDoc KEY_MIN_IDLE = "minIdle";
107     
108     /** Key for number of tested connections per run. */
109     public static final String JavaDoc KEY_NUM_TESTS_PER_EVICTION_RUN = "numTestsPerEvictionRun";
110
111     /** Key for database password. */
112     public static final String JavaDoc KEY_PASSWORD = "password";
113
114     /** Key for default. */
115     public static final String JavaDoc KEY_POOL_DEFAULT = "default";
116
117     /** Key for pool url. */
118     public static final String JavaDoc KEY_POOL_URL = "poolUrl";
119
120     /** Key for pool user. */
121     public static final String JavaDoc KEY_POOL_USER = "user";
122
123     /** Key for vfs pool. */
124     public static final String JavaDoc KEY_POOL_VFS = "vfs";
125
126     /** Key for pooling flag. */
127     public static final String JavaDoc KEY_POOLING = "pooling";
128
129     /** Key for test on borrow flag. */
130     public static final String JavaDoc KEY_TEST_ON_BORROW = "testOnBorrow";
131
132     /** Key for test query. */
133     public static final String JavaDoc KEY_TEST_QUERY = "testQuery";
134
135     /** Key for test while idle flag. */
136     public static final String JavaDoc KEY_TEST_WHILE_IDLE = "testWhileIdle";
137     
138     /** Key for time between two eviction runs. */
139     public static final String JavaDoc KEY_TIME_BETWEEN_EVICTION_RUNS = "timeBetweenEvictionRuns";
140     
141     /** Key for user name. */
142     public static final String JavaDoc KEY_USERNAME = "user";
143
144     /** Key for "when pool exhausted" action. */
145     public static final String JavaDoc KEY_WHEN_EXHAUSTED_ACTION = "whenExhaustedAction";
146
147     /** The name of the opencms default pool. */
148     public static final String JavaDoc OPENCMS_DEFAULT_POOL_NAME = "default";
149
150     /** The default OpenCms JDBC pool URL. */
151     public static final String JavaDoc OPENCMS_DEFAULT_POOL_URL = "opencms:default";
152
153     /** The prefix used for opencms JDBC pools. */
154     public static final String JavaDoc OPENCMS_URL_PREFIX = "opencms:";
155
156     /**
157      * Default constructor.<p>
158      *
159      * Nobody is allowed to create an instance of this class!
160      */

161     private CmsDbPool() {
162
163         super();
164     }
165
166     /**
167      * Creates a JDBC DriverManager based DBCP connection pool.<p>
168      *
169      * @param configuration the configuration (opencms.properties)
170      * @param key the key of the database pool in the configuration
171      * @return String the URL to access the created DBCP pool
172      * @throws Exception if the pool could not be initialized
173      */

174     public static PoolingDriver createDriverManagerConnectionPool(Map JavaDoc configuration, String JavaDoc key) throws Exception JavaDoc {
175
176         ExtendedProperties config;
177         if (configuration instanceof ExtendedProperties) {
178             config = (ExtendedProperties)configuration;
179         } else {
180             config = new ExtendedProperties();
181             config.putAll(configuration);
182         }
183
184         // read the values of the pool configuration specified by the given key
185
String JavaDoc jdbcDriver = config.getString(KEY_DATABASE_POOL + '.' + key + '.' + KEY_JDBC_DRIVER);
186         String JavaDoc jdbcUrl = config.getString(KEY_DATABASE_POOL + '.' + key + '.' + KEY_JDBC_URL);
187         String JavaDoc jdbcUrlParams = config.getString(KEY_DATABASE_POOL + '.' + key + '.' + KEY_JDBC_URL_PARAMS);
188         int maxActive = config.getInteger(KEY_DATABASE_POOL + '.' + key + '.' + KEY_MAX_ACTIVE, 10);
189         int maxWait = config.getInteger(KEY_DATABASE_POOL + '.' + key + '.' + KEY_MAX_WAIT, 2000);
190         int maxIdle = config.getInteger(KEY_DATABASE_POOL + '.' + key + '.' + KEY_MAX_IDLE, 5);
191         int minEvictableIdleTime = config.getInteger(KEY_DATABASE_POOL + '.' + key + '.' + KEY_MIN_EVICTABLE_IDLE_TIME, 1800000);
192         int minIdle = config.getInteger(KEY_DATABASE_POOL + '.' + key + '.' + KEY_MIN_IDLE, 0);
193         int numTestsPerEvictionRun = config.getInteger(KEY_DATABASE_POOL + '.' + key + '.' + KEY_NUM_TESTS_PER_EVICTION_RUN, 3);
194         int timeBetweenEvictionRuns = config.getInteger(KEY_DATABASE_POOL + '.' + key + '.' + KEY_TIME_BETWEEN_EVICTION_RUNS, 3600000);
195         String JavaDoc testQuery = config.getString(KEY_DATABASE_POOL + '.' + key + '.' + KEY_TEST_QUERY);
196         String JavaDoc username = config.getString(KEY_DATABASE_POOL + '.' + key + '.' + KEY_USERNAME);
197         String JavaDoc password = config.getString(KEY_DATABASE_POOL + '.' + key + '.' + KEY_PASSWORD);
198         String JavaDoc poolUrl = config.getString(KEY_DATABASE_POOL + '.' + key + '.' + KEY_POOL_URL);
199         String JavaDoc whenExhaustedActionValue = config.getString(
200             KEY_DATABASE_POOL + '.' + key + '.' + KEY_WHEN_EXHAUSTED_ACTION).trim();
201         byte whenExhaustedAction = 0;
202         boolean testOnBorrow = Boolean.valueOf(
203             config.getString(KEY_DATABASE_POOL + '.' + key + '.' + KEY_TEST_ON_BORROW, "false").trim()).booleanValue();
204         boolean testWhileIdle = Boolean.valueOf(
205             config.getString(KEY_DATABASE_POOL + '.' + key + '.' + KEY_TEST_WHILE_IDLE, "false").trim()).booleanValue();
206
207         if ("block".equalsIgnoreCase(whenExhaustedActionValue)) {
208             whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_BLOCK;
209         } else if ("fail".equalsIgnoreCase(whenExhaustedActionValue)) {
210             whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_FAIL;
211         } else if ("grow".equalsIgnoreCase(whenExhaustedActionValue)) {
212             whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW;
213         } else {
214             whenExhaustedAction = GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION;
215         }
216
217         if ("".equals(testQuery)) {
218             testQuery = null;
219         }
220
221         if (username == null) {
222             username = "";
223         }
224
225         if (password == null) {
226             password = "";
227         }
228
229         // read the values of the statement pool configuration specified by the given key
230
boolean poolingStmts = Boolean.valueOf(
231             config.getString(KEY_DATABASE_STATEMENTS + '.' + key + '.' + KEY_POOLING, CmsStringUtil.TRUE).trim()).booleanValue();
232         int maxActiveStmts = config.getInteger(KEY_DATABASE_STATEMENTS + '.' + key + '.' + KEY_MAX_ACTIVE, 25);
233         int maxWaitStmts = config.getInteger(KEY_DATABASE_STATEMENTS + '.' + key + '.' + KEY_MAX_WAIT, 250);
234         int maxIdleStmts = config.getInteger(KEY_DATABASE_STATEMENTS + '.' + key + '.' + KEY_MAX_IDLE, 15);
235         String JavaDoc whenStmtsExhaustedActionValue = config.getString(KEY_DATABASE_STATEMENTS
236             + '.'
237             + key
238             + '.'
239             + KEY_WHEN_EXHAUSTED_ACTION);
240         byte whenStmtsExhaustedAction = GenericKeyedObjectPool.WHEN_EXHAUSTED_GROW;
241         if (whenStmtsExhaustedActionValue != null) {
242             whenStmtsExhaustedActionValue = whenStmtsExhaustedActionValue.trim();
243             whenStmtsExhaustedAction = ("block".equalsIgnoreCase(whenStmtsExhaustedActionValue)) ? GenericKeyedObjectPool.WHEN_EXHAUSTED_BLOCK
244             : ("fail".equalsIgnoreCase(whenStmtsExhaustedActionValue)) ? GenericKeyedObjectPool.WHEN_EXHAUSTED_FAIL
245             : GenericKeyedObjectPool.WHEN_EXHAUSTED_GROW;
246         }
247
248         // create an instance of the JDBC driver
249
Class.forName(jdbcDriver).newInstance();
250
251         // initialize a keyed object pool to store connections
252
GenericObjectPool connectionPool = new GenericObjectPool(null);
253
254         /* Abandoned pool configuration:
255          *
256          * In case the systems encounters "pool exhaustion" (runs out of connections),
257          * comment the above line with "new GenericObjectPool(null)" and uncomment the
258          * 5 lines below. This will generate an "abandoned pool" configuration that logs
259          * abandoned connections to the System.out. Unfortunatly this code is deprecated,
260          * so to avoid code warnings it's also disabled here.
261          * Tested with commons-pool v 1.2.
262          */

263
264         // AbandonedConfig abandonedConfig = new AbandonedConfig();
265
// abandonedConfig.setLogAbandoned(true);
266
// abandonedConfig.setRemoveAbandoned(true);
267
// abandonedConfig.setRemoveAbandonedTimeout(5);
268
// GenericObjectPool connectionPool = new AbandonedObjectPool(null, abandonedConfig);
269
// initialize an object pool to store connections
270
connectionPool.setMaxActive(maxActive);
271         connectionPool.setMaxIdle(maxIdle);
272         connectionPool.setMinIdle(minIdle);
273         connectionPool.setMaxWait(maxWait);
274         connectionPool.setWhenExhaustedAction(whenExhaustedAction);
275
276         if (testQuery != null) {
277             connectionPool.setTestOnBorrow(testOnBorrow);
278             connectionPool.setTestWhileIdle(testWhileIdle);
279             connectionPool.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRuns);
280             connectionPool.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
281             connectionPool.setMinEvictableIdleTimeMillis(minEvictableIdleTime);
282         }
283
284         // initialize a connection factory to make the DriverManager taking connections from the pool
285
if (jdbcUrlParams != null) {
286             jdbcUrl += jdbcUrlParams;
287         }
288
289         ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(jdbcUrl, username, password);
290
291         // Set up statement pool, if desired
292
GenericKeyedObjectPoolFactory statementFactory = null;
293         if (poolingStmts) {
294             statementFactory = new GenericKeyedObjectPoolFactory(
295                 null,
296                 maxActiveStmts,
297                 whenStmtsExhaustedAction,
298                 maxWaitStmts,
299                 maxIdleStmts);
300         }
301
302         // initialize a factory to obtain pooled connections and prepared statements
303
new PoolableConnectionFactory(connectionFactory, connectionPool, statementFactory, testQuery, false, true);
304
305         // initialize a new pooling driver using the pool
306
PoolingDriver driver = new PoolingDriver();
307         driver.registerPool(poolUrl, connectionPool);
308
309         // try to connect once to the database to ensure it can be connected to at all
310
Connection JavaDoc con = connectionFactory.createConnection();
311         con.close();
312
313         if (CmsLog.INIT.isInfoEnabled()) {
314             CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_JDBC_POOL_2, poolUrl, jdbcUrl));
315         }
316         return driver;
317     }
318
319     /**
320      * Returns the database pool name for a given configuration key.<p>
321      *
322      * @param configuration the configuration
323      * @param key a db pool configuration key
324      * @return the database pool name
325      */

326     public static String JavaDoc getDbPoolName(Map JavaDoc configuration, String JavaDoc key) {
327
328         // TODO: name should be refactored to getDbPoolUrl
329
// changed KEY_JDBC_URL to KEY_POOL_URL
330
return configuration.get(KEY_DATABASE_POOL + '.' + key + '.' + KEY_POOL_URL).toString();
331
332         /*
333          String jdbcUrl = configuration.get(KEY_DATABASE_POOL + '.' + key + '.' + KEY_JDBC_URL).toString();
334          if (jdbcUrl.startsWith(OPENCMS_URL_PREFIX)) {
335          return jdbcUrl.substring(jdbcUrl.indexOf(':'));
336          } else {
337          return jdbcUrl;
338          }
339          */

340     }
341
342     /**
343      * Returns a list of available database pool names.<p>
344      *
345      * @param configuration the configuration
346      * @return a list of database pool names
347      */

348     public static List JavaDoc getDbPoolNames(Map JavaDoc configuration) {
349
350         // TODO: name should be refactored to getDbPoolUrls
351
ExtendedProperties config;
352         if (configuration instanceof ExtendedProperties) {
353             config = (ExtendedProperties)configuration;
354         } else {
355             config = new ExtendedProperties();
356             config.putAll(configuration);
357         }
358
359         List JavaDoc dbPoolNames = new ArrayList JavaDoc();
360         String JavaDoc[] driverPoolNames = config.getStringArray(CmsDriverManager.CONFIGURATION_DB + ".pools");
361
362         for (int i = 0; i < driverPoolNames.length; i++) {
363             dbPoolNames.add(getDbPoolName(configuration, driverPoolNames[i]));
364         }
365
366         return dbPoolNames;
367     }
368
369     /**
370      * Returns the name of the default database connection pool.<p>
371      *
372      * @return the name of the default database connection pool
373      */

374     public static String JavaDoc getDefaultDbPoolName() {
375
376         return OPENCMS_DEFAULT_POOL_NAME;
377     }
378 }
Popular Tags