View Javadoc

1   /* Version 1.0 based on Apache Software License 1.1
2    *
3    * Copyright (c) 2003 Piotr Maj and DBMonster developers. All rights
4    * reserved.
5    *
6    * Redistribution and use in source and binary forms, with or without
7    * modification, are permitted provided that the following conditions are
8    * met:
9    *
10   * 1. Redistributions of source code must retain the above copyright
11   *    notice, this list of conditions and the following disclaimer.
12   *
13   * 2. Redistributions in binary form must reproduce the above copyright
14   *    notice, this list of conditions and the following disclaimer in the
15   *    documentation and/or other materials provided with the distribution.
16   *
17   * 3. The end-user documentation included with the redistribution, if any,
18   *    must include the following acknowledgment:
19   *
20   *    "This product includes software developed by DBMonster developers
21   *    (http://dbmonster.kernelpanic.pl/)."
22   *
23   *  Alternately, this acknowledgment may appear in the software itself,
24   *  if and wherever such third-party acknowledgments normally appear.
25   *
26   * 4. The name "DBMonster" must not be used to endorse or promote products
27   *    derived from this software without prior written permission. For
28   *    written permission, please contact pm@jcake.com.
29   *
30   * 5. Products derived from this software may not be called "DBMonster",
31   *    nor may "DBMonster" appear in their name, without prior written
32   *    permission of Piotr Maj.
33   *
34   * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
35   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
37   * IN NO EVENT SHALL THE DBMONSTER DEVELOPERS BE LIABLE FOR ANY DIRECT,
38   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
40   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
42   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
43   * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
44   * POSSIBILITY OF SUCH DAMAGE.
45   */
46  
47  package pl.kernelpanic.dbmonster.connection;
48  
49  import java.sql.Connection;
50  import java.sql.DatabaseMetaData;
51  import java.sql.SQLException;
52  import java.util.Properties;
53  
54  import javax.sql.DataSource;
55  
56  import org.apache.commons.dbcp.ConnectionFactory;
57  import org.apache.commons.dbcp.PoolingDataSource;
58  import org.apache.commons.dbcp.PoolableConnectionFactory;
59  import org.apache.commons.dbcp.DriverManagerConnectionFactory;
60  import org.apache.commons.logging.Log;
61  import org.apache.commons.pool.ObjectPool;
62  import org.apache.commons.pool.impl.GenericObjectPool;
63  
64  /***
65   * The connection provider which uses commons-dbcp.
66   * It uses the following properties to establish connection:
67   *
68   * <ul>
69   *   <li>dbmonster.jdbc.driver (ie. org.postgresql.Driver)</li>
70   *   <li>dbmonster.jdbc.url (ie. jdbc:postgresql://127.0.0.1/dbmonster)</li>
71   *   <li>dbmonster.jdbc.username (ie. dbmonster)</li>
72   *   <li>dbmonster.jdbc.password (ie. dbmonster)</li>
73   * </ul>
74   *
75   * By default these properties are taken from System.getProperty, but you may
76   * also provide them on your own.
77   *
78   * @author Piotr Maj
79   *
80   * @version $Id: DBCPConnectionProvider.java,v 1.2 2006/01/05 16:29:37 majek Exp $
81   */
82  public class DBCPConnectionProvider implements ConnectionProvider, LogEnabled {
83  
84      /***
85       * JDBC driver name.
86       */
87      private String driver = System.getProperty("dbmonster.jdbc.driver");
88  
89      /***
90       * JDBC url.
91       */
92      private String url = System.getProperty("dbmonster.jdbc.url");
93  
94      /***
95       * JDBC user name.
96       */
97      private String username = System.getProperty("dbmonster.jdbc.username");
98  
99      /***
100      * JDBC user's password.
101      */
102     private String password = System.getProperty("dbmonster.jdbc.password");
103 
104     /***
105      * Properties used to establish connection.
106      */
107     private Properties properties = null;
108 
109     /***
110      * A datasource.
111      */
112     private DataSource dataSource = null;
113 
114      /***
115      * Logger.
116      */
117     private Log logger = null;
118 
119     /***
120      * Connection pool handler.
121      */
122     private ObjectPool pool;
123 
124     private boolean autoCommit = true;
125 
126     /***
127      * Creates new SimpleConnectionProvider.
128      *
129      * @throws Exception if driver class could not be found.
130      */
131     public DBCPConnectionProvider() throws Exception {
132         initDriver();
133         setupPool();
134     }
135 
136     /***
137      * Creates new DBCPConnectionProvider with given connection info.
138      *
139      * @param jdbcDriver JDBC driver
140      * @param jdbcUrl JDBC url
141      * @param jdbcUsername JDBC user name
142      * @param jdbcPassword JDBC password
143      *
144      * @throws Exception if the driver class could not be found.
145      */
146     public DBCPConnectionProvider(
147         String jdbcDriver,
148         String jdbcUrl,
149         String jdbcUsername,
150         String jdbcPassword) throws Exception {
151         driver = jdbcDriver;
152         url = jdbcUrl;
153         username = jdbcUsername;
154         password = jdbcPassword;
155         initDriver();
156         setupPool();
157     }
158 
159     /***
160      * Creates new DBCPConnectionProvider with properties (usefull
161      * for interbase).
162      *
163      * @param jdbcDriver JDBC driver
164      * @param jdbcUrl JDBC url
165      * @param props properties
166      *
167      * @throws Exception if driver class could not be found.
168      */
169     public DBCPConnectionProvider(
170         String jdbcDriver,
171         String jdbcUrl,
172         Properties props) throws Exception {
173         driver = jdbcDriver;
174         url = jdbcUrl;
175         properties = props;
176         initDriver();
177         setupPool();
178     }
179 
180     /***
181      * @see ConnectionProvider#getConnection()
182      */
183     public Connection getConnection() throws SQLException {
184         if (dataSource == null) {
185             throw new SQLException("Data source is null!");
186         }
187         Connection conn = dataSource.getConnection();
188         conn.setAutoCommit(autoCommit);
189         return conn;
190     }
191 
192     /***
193      * @see ConnectionProvider#testConnection()
194      */
195     public void testConnection() throws SQLException {
196         Connection conn = getConnection();
197         DatabaseMetaData dbmd = conn.getMetaData();
198         if (logger != null && logger.isInfoEnabled()) {
199             logger.info("Today we are feeding: "
200                 + dbmd.getDatabaseProductName() + " "
201                 + dbmd.getDatabaseProductVersion());
202         }
203         conn.close();
204         dbmd = null;
205         conn = null;
206     }
207 
208     /***
209      * Sets the logger.
210      *
211      * @param log a logger.
212      */
213     public void setLogger(Log log) {
214         logger = log;
215     }
216 
217     /***
218      * Shutdown this connection provider.
219      */
220     public void shutdown() {
221         try {
222             pool.close();
223         } catch (Exception e) {
224         } finally {
225             pool = null;
226         }
227         dataSource = null;
228         driver = null;
229         logger = null;
230         password = null;
231         properties = null;
232         url = null;
233         username = null;
234     }
235 
236     /***
237      * Initializes the JDBC driver.
238      *
239      * @throws ClassNotFoundException if driver class could not be found.
240      */
241     private void initDriver() throws ClassNotFoundException {
242         Class.forName(driver);
243     }
244 
245     /***
246      * Sets the pool up.
247      *
248      * @throws Exception if the pool cannot be set up
249      */
250     private void setupPool() throws Exception {
251         pool = new GenericObjectPool(null);
252         ConnectionFactory connFactory = null;
253         if (properties != null) {
254             connFactory = new DriverManagerConnectionFactory(url, properties);
255         } else {
256             connFactory =
257                 new DriverManagerConnectionFactory(url, username, password);
258         }
259         new PoolableConnectionFactory(
260             connFactory, pool, null, null, false, true);
261         dataSource = new PoolingDataSource(pool);
262     }
263 
264     public void setAutoCommit(boolean autoCommit) {
265         this.autoCommit = autoCommit;
266     }
267 }