View Javadoc

1   /*
2    * Copyright (c) 2003, Henri Yandell
3    * All rights reserved.
4    * 
5    * Redistribution and use in source and binary forms, with or 
6    * without modification, are permitted provided that the 
7    * following conditions are met:
8    * 
9    * + Redistributions of source code must retain the above copyright notice, 
10   *   this list of conditions and the following disclaimer.
11   * 
12   * + Redistributions in binary form must reproduce the above copyright notice, 
13   *   this list of conditions and the following disclaimer in the documentation 
14   *   and/or other materials provided with the distribution.
15   * 
16   * + Neither the name of Simple-JNDI nor the names of its contributors 
17   *   may be used to endorse or promote products derived from this software 
18   *   without specific prior written permission.
19   * 
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
23   * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
30   * POSSIBILITY OF SUCH DAMAGE.
31   */
32  
33  package org.osjava.sj.loader;
34  
35  import java.sql.SQLException;
36  import java.sql.DriverManager;
37  import java.util.Properties;
38  
39  // gives us pooling
40  import org.apache.commons.pool.impl.GenericObjectPool;
41  import org.apache.commons.dbcp.ConnectionFactory;
42  import org.apache.commons.dbcp.PoolingDriver;
43  import org.apache.commons.dbcp.PoolableConnectionFactory;
44  import org.apache.commons.dbcp.DriverManagerConnectionFactory;
45  
46  /***
47   * This is a wrapper for the Pooling functionality, currently provided 
48   * by Jakarta DBCP. Having the wrapper allows the dependency to be 
49   * optional. 
50   */
51  public class PoolSetup {
52  
53      public static void setupConnection(String pool, String url, String username, String password, Properties properties) throws SQLException {
54          // we have a pool-name to setup using dbcp
55          GenericObjectPool connectionPool = new GenericObjectPool(null, 
56              toInt(properties.getProperty("dbcpMaxActive"), GenericObjectPool.DEFAULT_MAX_ACTIVE),
57              (byte) toInt(properties.getProperty("dbcpWhenExhaustedAction"), GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION),
58              toLong(properties.getProperty("dbcpMaxWait"), GenericObjectPool.DEFAULT_MAX_WAIT),
59              toInt(properties.getProperty("dbcpMaxIdle"), GenericObjectPool.DEFAULT_MAX_IDLE),
60              toInt(properties.getProperty("dbcpMinIdle"), GenericObjectPool.DEFAULT_MIN_IDLE),
61              toBoolean(properties.getProperty("dbcpTestOnBorrow"), GenericObjectPool.DEFAULT_TEST_ON_BORROW),
62              toBoolean(properties.getProperty("dbcpTestOnReturn"), GenericObjectPool.DEFAULT_TEST_ON_RETURN),
63              toLong(properties.getProperty("dbcpTimeBetweenEvictionRunsMillis"), GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS),
64              toInt(properties.getProperty("dbcpNumTestsPerEvictionRun"), GenericObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN),
65              toLong(properties.getProperty("dbcpMinEvictableIdleTimeMillis"), GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS),
66              toBoolean(properties.getProperty("dbcpTestWhileIdle"), GenericObjectPool.DEFAULT_TEST_WHILE_IDLE),
67              toLong(properties.getProperty("dbcpSoftMinEvictableIdleTimeMillis"), GenericObjectPool.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS)
68          );
69  //            toBoolean(properties.getProperty("dbcpLifo"), GenericObjectPool.DEFAULT_LIFO)
70  
71          ConnectionFactory connectionFactory = null;
72          if(username == null || password == null) {
73              // TODO: Suck configuration in and build a Properties to replace the null below
74              connectionFactory = new DriverManagerConnectionFactory(url, null);
75          } else {
76              connectionFactory = new DriverManagerConnectionFactory(url, username, password);
77          }
78          new PoolableConnectionFactory(connectionFactory, connectionPool, null, properties.getProperty("dbcpValidationQuery"), toBoolean(properties.getProperty("dbcpDefaultReadOnly"), false), toBoolean(properties.getProperty("dbcpDefaultAutoCommit"), true));
79          try {
80              Class.forName("org.apache.commons.dbcp.PoolingDriver");
81          } catch(ClassNotFoundException cnfe) {
82              // not too good
83              System.err.println("WARNING: DBCP needed but not in the classpath. ");
84          }
85          PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");
86          driver.registerPool(pool, connectionPool);
87  
88      //  Runtime.getRuntime().addShutdownHook( new ShutdownDbcpThread(pool) );
89      }
90  
91      public static String getUrl(String pool) {
92          return "jdbc:apache:commons:dbcp:"+pool;
93      }
94  
95      private static int toInt(String str, int def) {
96          if(str == null) {
97              return def;
98          }
99          try {
100             return Integer.parseInt(str);
101         } catch(NumberFormatException nfe) {
102             throw new RuntimeException("Unable to parse as int: '" + str + "'", nfe);
103         }
104     }
105 
106     private static long toLong(String str, long def) {
107         if(str == null) {
108             return def;
109         }
110         try {
111             return Long.parseLong(str);
112         } catch(NumberFormatException nfe) {
113             throw new RuntimeException("Unable to parse as long: '" + str + "'", nfe);
114         }
115     }
116 
117     private static boolean toBoolean(String str, boolean def) {
118         if(str == null) {
119             return def;
120         } else
121         if("true".equals(str)) {
122             return true;
123         } else
124         if("false".equals(str)) {
125             return false;
126         } else {
127             throw new RuntimeException("Unable to parse as boolean: '" + str + "'");
128         }
129     }
130 
131 }
132 
133 /*
134 // this is not available in the version of DBCP being used.
135 class ShutdownDbcpThread extends Thread {
136     
137     private String pool;
138 
139     public ShutdownDbcpThread(String pool) {
140         this.pool = pool;
141     }
142 
143     public void run() {
144         try {
145             PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");
146             driver.closePool(this.pool);
147         } catch(SQLException sqle) {
148             // failed to close
149         } catch(ClassNotFoundException cnfe) {
150             // oops, unable to close pools, sorry DBA
151         }
152     }
153 }
154 */
155