KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * Copyright (c) 2003 - 2007 OpenSubsystems s.r.o. Slovak Republic. All rights reserved.
3  *
4  * Project: OpenSubsystems
5  *
6  * $Id: PooledDatabaseConnectionFactorySetupReader.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 import java.util.HashMap JavaDoc;
26 import java.util.Map JavaDoc;
27 import java.util.logging.Logger JavaDoc;
28
29 import org.opensubsystems.core.util.Log;
30 import org.opensubsystems.core.util.SetupReader;
31
32 /**
33  * Class that reads setup for database connection pools from properties. Each
34  * pool have unique name. For this name class will find all properties for
35  * name or wil use default values if property with name is not present.
36  *
37  * The DBCP configuration is available at
38  * http://jakarta.apache.org/commons/dbcp/configuration.html
39  * The XAPool configuration is available at
40  * file:///e:/Development/OpenSubsystems/external/xapool/jdoc/index.html
41  * see classes StandardXADataSource, StandardXAPoolDataSource
42  * The C3P0 configuration is available at
43  * http://www.mchange.com/projects/c3p0/index.html#appendix_a
44  * The Proxool configuraion is available at
45  * http://proxool.sourceforge.net/properties.html
46  *
47  * @version $Id: PooledDatabaseConnectionFactorySetupReader.java,v 1.6 2007/01/07 06:14:58 bastafidli Exp $
48  * @author Miro Halas
49  * @code.reviewer Miro Halas
50  * @code.reviewed 1.2 2006/04/27 13:31:23 bastafidli
51  */

52 public class PooledDatabaseConnectionFactorySetupReader extends SetupReader
53 {
54    // TODO: Feature: Allow to override JDBC driver properties set in
55
// DatabaseConnectionFactoryImpl
56

57    // Configuration settings ///////////////////////////////////////////////////
58

59    /**
60     * base path for all properties
61     */

62    public static final String JavaDoc DATABASE_POOL_BASE_PATH = "oss.datasource.pool";
63
64    // Configuration parameters names
65

66    /**
67     * Initial size of the connection pool. How many connections are created
68     * in the pool when the pool is started.
69     *
70     * Connection pool specific terminology:
71     * DBCP: initialSize - if 0 - no initial connections created
72     * XAPool: StandardXAPoolDataSource(iInitialPoolSize)
73     * C3P0: initialPoolSize
74     * Proxool: No support
75     */

76    public static final String JavaDoc DBPOOL_INITIAL_SIZE = "initialsize";
77
78    /**
79     * Minimal size of the connection pool. Number of connections in the pool
80     * should not fall under this threshold regardless if they are used or not.
81     * This is not the same as the initial/optimal size.
82     *
83     * Connection pool specific terminology:
84     * DBCP: minIdle - if 0 - pool can become empty
85     * XAPool: StandardXAPoolDataSource.setMinSize
86     * C3P0: minPoolSize
87     * Proxool: minimum-connection-count
88     */

89    public static final String JavaDoc DBPOOL_MIN_SIZE = "minsize";
90
91    /**
92     * Maximal size of the connection pool. How many connections can be taken out
93     * of the pool or can exist in the pool idle.
94     *
95     * Connection pool specific terminology:
96     * DBCP: maxActive, maxIdle - if 0 - no limit
97     * XAPool: StandardXAPoolDataSource.setMaxSize
98     * C3P0: maxPoolSize
99     * Proxool: maximum-connection-count
100     */

101    public static final String JavaDoc DBPOOL_MAX_SIZE = "maxsize";
102    
103    /**
104     * Can the connection pool grow above maximal size or should it block. This
105     * can be useful if we want to have soft max limit but still allow to satisfy
106     * request when load increases and then maybe in the future readjust the
107     * settings. If we do not allow growing, then the caller will be blocked until
108     * connection becomes available.
109     *
110     * Connection pool specific terminology:
111     * DBCP: GenericObjectPool(...whenExhaustedAction...)
112     * XAPool: No support
113     * C3P0: No support
114     * Proxool: No support
115     */

116    public static final String JavaDoc DBPOOL_CAN_GROW = "cangrow";
117
118    /**
119     * If the pool should block when it reaches maximal size, how long can wait
120     * at most for a connection. Time is in miliseconds.
121     *
122     * Connection pool specific terminology:
123     * DBCP: maxWait - if -1 - wait indefinitely
124     * XAPool: StandardXAPoolDataSource.setDeadLockMaxWait
125     * C3P0: checkoutTimeout - if 0 - wait indefinitely
126     * Proxool: No support
127     */

128    public static final String JavaDoc DBPOOL_WAIT_PERIOD = "waitperiod";
129
130    /**
131     * If getting connection from the pool fails (e.g. in case of C3P0 even for
132     * some other reason than the pool is exhaused, such as temporary database
133     * outage) how long to wait until the pool tries to acquire another connection.
134     * Time is in miliseconds.
135     *
136     * Connection pool specific terminology:
137     * DBCP: No support
138     * XAPool: StandardXAPoolDataSource.setDeadLockRetryWait
139     * C3P0: acquireRetryDelay
140     * Proxool: No support
141     */

142    public static final String JavaDoc DBPOOL_RETRY_PERIOD = "retryperiod";
143
144    /**
145     * If getting connection from the pool fails (e.g. in case of C3P0 even for
146     * some other reason than the pool is exhaused, such as temporary database
147     * outage) how many times to try to acquire another connection.
148     *
149     * Connection pool specific terminology:
150     * DBCP: No support
151     * XAPool: No support
152     * C3P0: acquireRetryAttempts - if less or equal to 0 - try indefinitely
153     * Proxool: No support
154     */

155    public static final String JavaDoc DBPOOL_RETRY_COUNT = "retrycount";
156
157    /**
158     * Should the pool validate connection immmediately before it is borrowed
159     * from the pool. This is quite expensive to do by default and often it is
160     * better to let pool check on idle connection if such option is available.
161     *
162     * Connection pool specific terminology:
163     * DBCP: testOnBorrow
164     * XAPool: No support
165     * C3P0: testConnectionOnCheckout
166     * Proxool: test-before-use
167     */

168    public static final String JavaDoc DBPOOL_VALIDATE_BORROW = "validate.borrow";
169
170    /**
171     * Should the pool validate connection when it is returned to the pool.
172     *
173     * Connection pool specific terminology:
174     * DBCP: testOnReturn
175     * XAPool: No support
176     * C3P0: testConnectionOnCheckin
177     * Proxool: test-after-use
178     */

179    public static final String JavaDoc DBPOOL_VALIDATE_RETURN = "validate.return";
180
181    /**
182     * Should the pool validate connection when it is idle. This is the most
183     * efficient way of conection testing and if you do decide to test connections
184     * you may consider doing so while they are idle.
185     *
186     * Connection pool specific terminology:
187     * DBCP: testWhileIdle
188     * XAPool: No support
189     * C3P0: just set value for idleConnectionTestPeriod
190     * Proxool: Just set value for idlecheckperiod
191     */

192    public static final String JavaDoc DBPOOL_VALIDATE_IDLE = "validate.idle";
193
194    /**
195     * How thoroughly to validate the objects in the pool. Since this is the only
196     * way provided by XAPool to configure connection testing, we provide this
197     * attribute, even though it has no meaning for other pools.
198     *
199     * Connection pool specific terminology:
200     * DBCP: No support
201     * XAPool: StandardXAPoolDataSource.setCheckLevelObject
202     * C3P0: No support
203     * Proxool: No support
204     *
205     * From XAPool JavaDoc:
206     * 0 = no special checking
207     * 1 = just a check on an object
208     * 2 = test the object
209     * 3 = just a check on an object (for all the objects)
210     * 4 = test the object (for all the objects)
211     */

212    public static final String JavaDoc DBPOOL_CHECK_LEVEL = "validate.level";
213    
214    /**
215     * How often to validate idle connections. Validating idles connections is
216     * the most efficient way of validating connections since it doesn't affect
217     * requesting of returning of connections and therefore performance of the
218     * application. Time is in miliseconds (even though some pools expect it in
219     * seconds, it will be converted from milliseconds as needed). Alternative
220     * is to set idlechecksize if the connection pool supports it.
221     *
222     * Connection pool specific terminology:
223     * DBCP: timeBetweenEvictionRunsMillis - if less or equal to 0 - do not check
224     * XAPool: No support
225     * C3P0: idleConnectionTestPeriod - if less or equal to 0 - do not check
226     * Proxool: house-keeping-sleep-time
227     */

228    public static final String JavaDoc DBPOOL_IDLE_CHECK_PERIOD = "idlecheckperiod";
229
230    /**
231     * How many of the idle connections to test during one test run. This is
232     * an alternative of idlecheckperiod.
233     *
234     * Connection pool specific terminology:
235     * DBCP: numTestsPerEvictionRun
236     * XAPool: No support
237     * C3P0: No support
238     * Proxool: No support
239     */

240    public static final String JavaDoc DBPOOL_IDLE_CHECK_SIZE = "idlechecksize";
241
242    /**
243     * How long can connection sit in the pool before it is considered idle. Time
244     * is in miliseconds (even though some pools expect it in seconds, it will be
245     * converted from milliseconds as needed).
246     *
247     * Connection pool specific terminology:
248     * DBCP: minEvictableIdleTimeMillis
249     * XAPool: No support
250     * C3P0: maxIdleTime - 0 means connections will never expire
251     * Proxool: No support
252     */

253    public static final String JavaDoc DBPOOL_IDLE_PERIOD = "idleperiod";
254    
255    /**
256     * Default transaction isolation level. Settings are commited, uncommited,
257     * repeatable, serializable.
258     *
259     * Connection pool specific terminology:
260     * DBCP: defaultTransactionIsolation
261     * XAPool: StandardXADataSource.setTransactionIsolation
262     * C3P0: No support
263     * Proxool: No support
264     */

265    public static final String JavaDoc DBPOOL_TRANSACTION_ISOLATION = "transaction.isolation";
266    
267    /**
268     * Should the connection pool cache prepared statements and if so how many.
269     *
270     * Connection pool specific terminology:
271     * DBCP: maxOpenPreparedStatements - if 0 - cache and do not impose any limit
272     * - if less than 0 - do no cache
273     * XAPool: StandardXADataSource.setPreparedStmtCacheSize - if less or equal
274     * to 0 - do not cache
275     * C3P0: maxStatements - if less or equal to 0 - do not cache
276     * Proxool: No support
277     */

278    public static final String JavaDoc DBPOOL_PREPSTATEMENT_CACHE_SIZE = "pstmtcachesize";
279    
280    // Configuration default values
281

282    /**
283     * Initial size of the connection pool. Make this 0 since if the database
284     * doesn't exist or is not started we do not want to create unnecessary error
285     * conditions due to creation of initial connections.
286     */

287    public static final int DBPOOL_INITIAL_SIZE_DEFAULT = 0;
288
289    /**
290     * Minimal size of the connection pool. Make this 0 since if the database
291     * doesn't exist or is not started we do not want to create unnecessary error
292     * conditions due to creation of initial connections.
293     */

294    public static final int DBPOOL_MIN_SIZE_DEFAULT = 0;
295
296    /**
297     * Maximal size of the connection pool. This is reasonable amount for most
298     * not high volume applications.
299     */

300    public static final int DBPOOL_MAX_SIZE_DEFAULT = 20;
301    
302    /**
303     * Can the connection pool grow above maximal size or should it block.
304     */

305    public static final boolean DBPOOL_CAN_GROW_DEFAULT = true;
306
307    /**
308     * If the pool should block when it reaches maximal size, how long can wait
309     * at most for connection.
310     */

311    public static final long DBPOOL_WAIT_PERIOD_DEFAULT = 10000L; // 10 seconds
312

313    /**
314     * If getting connection from the pool fails (e.g. in case of C3P0 even for
315     * some other reason than the pool is exhaused, such as temporary database
316     * outage) how long to wait until the pool tries to acquire another connection.
317     * Time is in miliseconds.
318     */

319    public static final long DBPOOL_RETRY_PERIOD_DEFAULT = 2000L; // 20 seconds
320

321    /**
322     * If getting connection from the pool fails (e.g. in case of C3P0 even for
323     * some other reason than the pool is exhaused, such as temporary database
324     * outage) how many times to try to acquire another connection.
325     */

326    public static final long DBPOOL_RETRY_COUNT_DEFAULT = 3; // 3 times
327

328    /**
329     * Should the pool validate connection immmediately before it is borrowed
330     * from the pool. This is quite expensive to do by default and often it is
331     * better to let pool check on idle connection if such option is available.
332     */

333    public static final boolean DBPOOL_VALIDATE_BORROW_DEFAULT = false; // no validation
334

335    /**
336     * Should the pool validate connection when it is returned to the pool.
337     */

338    public static final boolean DBPOOL_VALIDATE_RETURN_DEFAULT = false; // no validation
339

340    /**
341     * Should the pool validate connection when it is idle. This is the most
342     * efficient way of conection testing and if you do decide to test connections
343     * you may consider doing so while they are idle.
344     */

345    public static final boolean DBPOOL_VALIDATE_IDLE_DEFAULT = false; // no validation
346

347    /**
348     * How thoroughly to validate the objects in the pool. Since this is the only
349     * way provided by XAPool to configure connection testing, we provide this
350     * attribute, even though it has no meaning for other pools.
351     *
352     * From XAPool JavaDoc:
353     * 0 = no special checking
354     * 1 = just a check on an object
355     * 2 = test the object
356     * 3 = just a check on an object (for all the objects)
357     * 4 = test the object (for all the objects)
358     */

359    public static final int DBPOOL_CHECK_LEVEL_DEFAULT = 0; // no validation
360

361    /**
362     * How often to validate idle connections. Validating idles connections is
363     * the most efficient way of validating connections since it doesn't affect
364     * requesting of returning of connections and therefore performance of the
365     * application. Time is in miliseconds (even though some pools expect it in
366     * seconds, it will be converted from milliseconds as needed).
367     */

368    public static final long DBPOOL_IDLE_CHECK_PERIOD_DEFAULT = 0; // do not check
369

370    /**
371     * How much of the idle connections to test during one test run.
372     */

373    public static final int DBPOOL_IDLE_CHECK_SIZE_DEFAULT = 0; // do not check
374

375    /**
376     * How long can connection sit in the pool before it is considered idle. Time
377     * is in miliseconds (even though some pools expect it in seconds, it will be
378     * converted from milliseconds as needed).
379     */

380    public static final long DBPOOL_IDLE_PERIOD_DEFAULT = 0; // never idle
381

382    /**
383     * Default transaction isolation level. Settings are commited, uncommited,
384     * repeatable, serializable.
385     */

386    public static final String JavaDoc DBPOOL_TRANSACTION_ISOLATION_DEFAULT = "serializable";
387    
388    /**
389     * Should the connection pool cache prepared statements and if so how many.
390     *
391     * In XAPool 1.4.1 0 triggers NullPointerException in XAPool therefore
392     * we have patched StandardConnectionHandle.java:145 in 1.4.1 ourselves. This
393     * was fixed in subsequent releases of XAPool.
394     */

395    public static final int DBPOOL_PREPSTATEMENT_CACHE_SIZE_DEFAULT = -1; // do not cache
396

397    // Cached values ////////////////////////////////////////////////////////////
398

399    /**
400     * Logger for this class
401     */

402    private static Logger JavaDoc s_logger
403                            = Log.getInstance(PooledDatabaseConnectionFactorySetupReader.class);
404    
405    /**
406     * Map with all registered paremeters names (as key) and types (as Integer value)
407     * This map is common for all instances of class
408     */

409    protected static Map JavaDoc s_registeredParametersTypes;
410
411    /**
412     * Map with all registered paremeters names (as key) and default values (as String value)
413     * This map is common for all instances of class
414     */

415    protected static Map JavaDoc s_registeredParametersDefaults;
416
417    // Constructor //////////////////////////////////////////////////////////////
418

419    /**
420     * Static initializer.
421     */

422    static
423    {
424       s_registeredParametersTypes = new HashMap JavaDoc();
425       s_registeredParametersDefaults = new HashMap JavaDoc();
426    }
427
428    /**
429     * @param readerName - name of reader
430
431     * Each property name consist from three parts. base path,
432     * reader name and parameter name. Property name looks like <xxx>.<yyy>.<zzz> where
433     * xxx is base path (for example myapp.receiver) yyy is receiver name (for example
434     * defaultfax) and zzz is parameter name (for example priority). result will be
435     * myapp.receiver.defaultfax.priority
436     */

437    public PooledDatabaseConnectionFactorySetupReader(
438       String JavaDoc readerName
439    )
440    {
441       super(DATABASE_POOL_BASE_PATH, readerName);
442    }
443
444    // Helper methods //////////////////////////////////////////////////////////
445

446    /**
447     * {@inheritDoc}
448     */

449    protected void registerParameters(
450    )
451    {
452       registerParameter(DBPOOL_INITIAL_SIZE,
453                         SetupReader.PARAMETER_TYPE_INTEGER_OBJ,
454                         Integer.toString(DBPOOL_INITIAL_SIZE_DEFAULT));
455
456       registerParameter(DBPOOL_MIN_SIZE,
457                         SetupReader.PARAMETER_TYPE_INTEGER_OBJ,
458                         Integer.toString(DBPOOL_MIN_SIZE_DEFAULT));
459
460       registerParameter(DBPOOL_MAX_SIZE,
461                         SetupReader.PARAMETER_TYPE_INTEGER_OBJ,
462                         Integer.toString(DBPOOL_MAX_SIZE_DEFAULT));
463
464       registerParameter(DBPOOL_CAN_GROW,
465                         SetupReader.PARAMETER_TYPE_BOOLEAN_OBJ,
466                         Boolean.toString(DBPOOL_CAN_GROW_DEFAULT));
467
468       registerParameter(DBPOOL_WAIT_PERIOD,
469                         SetupReader.PARAMETER_TYPE_LONG_OBJ,
470                         Long.toString(DBPOOL_WAIT_PERIOD_DEFAULT));
471
472       registerParameter(DBPOOL_RETRY_PERIOD,
473                         SetupReader.PARAMETER_TYPE_LONG_OBJ,
474                         Long.toString(DBPOOL_RETRY_PERIOD_DEFAULT));
475
476       registerParameter(DBPOOL_RETRY_COUNT,
477                         SetupReader.PARAMETER_TYPE_INTEGER_OBJ,
478                         Long.toString(DBPOOL_RETRY_COUNT_DEFAULT));
479
480       registerParameter(DBPOOL_VALIDATE_BORROW,
481                         SetupReader.PARAMETER_TYPE_BOOLEAN_OBJ,
482                         Boolean.toString(DBPOOL_VALIDATE_BORROW_DEFAULT));
483
484       registerParameter(DBPOOL_VALIDATE_RETURN,
485                         SetupReader.PARAMETER_TYPE_BOOLEAN_OBJ,
486                         Boolean.toString(DBPOOL_VALIDATE_RETURN_DEFAULT));
487
488       registerParameter(DBPOOL_VALIDATE_IDLE,
489                         SetupReader.PARAMETER_TYPE_BOOLEAN_OBJ,
490                         Boolean.toString(DBPOOL_VALIDATE_IDLE_DEFAULT));
491
492       registerParameter(DBPOOL_CHECK_LEVEL,
493                         SetupReader.PARAMETER_TYPE_INTEGER_OBJ,
494                         Integer.toString(DBPOOL_CHECK_LEVEL_DEFAULT));
495    
496       registerParameter(DBPOOL_IDLE_CHECK_PERIOD,
497                         SetupReader.PARAMETER_TYPE_LONG_OBJ,
498                         Long.toString(DBPOOL_IDLE_CHECK_PERIOD_DEFAULT));
499
500       registerParameter(DBPOOL_IDLE_CHECK_SIZE,
501                         SetupReader.PARAMETER_TYPE_INTEGER_OBJ,
502                         Integer.toString(DBPOOL_IDLE_CHECK_SIZE_DEFAULT));
503
504       registerParameter(DBPOOL_IDLE_PERIOD,
505                         SetupReader.PARAMETER_TYPE_LONG_OBJ,
506                         Long.toString(DBPOOL_IDLE_PERIOD_DEFAULT));
507    
508       registerParameter(DBPOOL_TRANSACTION_ISOLATION,
509                         SetupReader.PARAMETER_TYPE_STRING_OBJ,
510                         DBPOOL_TRANSACTION_ISOLATION_DEFAULT);
511
512       registerParameter(DBPOOL_PREPSTATEMENT_CACHE_SIZE,
513                         SetupReader.PARAMETER_TYPE_INTEGER_OBJ,
514                         Integer.toString(DBPOOL_PREPSTATEMENT_CACHE_SIZE_DEFAULT));
515    }
516
517    /**
518     * {@inheritDoc}
519     */

520    protected Map JavaDoc getRegisteredParameterTypes()
521    {
522       return s_registeredParametersTypes;
523    }
524
525    /**
526     * {@inheritDoc}
527     */

528    protected Map JavaDoc getRegisteredParametersDefaults()
529    {
530       return s_registeredParametersDefaults;
531    }
532    
533    /**
534     * Translate transaction isolation setting to a Connection.TRANSACTION_XXX constant.
535     *
536     * @param strTransactionIsolation - one of the settings to set transaction isolation
537     * @return int
538     */

539    public static int convertTransactionIsolationToConstant(
540       String JavaDoc strTransactionIsolation
541    )
542    {
543       // Use the most conservative as default
544
int iTransactionIsolation = Connection.TRANSACTION_SERIALIZABLE;
545       
546       if ("uncommited".equalsIgnoreCase(strTransactionIsolation))
547       {
548          iTransactionIsolation = Connection.TRANSACTION_READ_UNCOMMITTED;
549       }
550       else if ("commited".equalsIgnoreCase(strTransactionIsolation))
551       {
552          iTransactionIsolation = Connection.TRANSACTION_READ_COMMITTED;
553       }
554       else if ("repeatable".equalsIgnoreCase(strTransactionIsolation))
555       {
556          iTransactionIsolation = Connection.TRANSACTION_REPEATABLE_READ;
557       }
558       else if ("serializable".equalsIgnoreCase(strTransactionIsolation))
559       {
560          iTransactionIsolation = Connection.TRANSACTION_SERIALIZABLE;
561       }
562       else
563       {
564          s_logger.config("Incorrect transaction isolation setting "
565                                   + strTransactionIsolation
566                                   + ". Using default serializable.");
567       }
568       
569       return iTransactionIsolation;
570    }
571 }
572
Popular Tags