KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > james > util > dbcp > JdbcDataSource


1 /***********************************************************************
2  * Copyright (c) 2000-2004 The Apache Software Foundation. *
3  * All rights reserved. *
4  * ------------------------------------------------------------------- *
5  * Licensed under the Apache License, Version 2.0 (the "License"); you *
6  * may not use this file except in compliance with the License. You *
7  * may obtain a copy of the License at: *
8  * *
9  * http://www.apache.org/licenses/LICENSE-2.0 *
10  * *
11  * Unless required by applicable law or agreed to in writing, software *
12  * distributed under the License is distributed on an "AS IS" BASIS, *
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or *
14  * implied. See the License for the specific language governing *
15  * permissions and limitations under the License. *
16  ***********************************************************************/

17
18 package org.apache.james.util.dbcp;
19
20 import java.io.PrintWriter JavaDoc;
21 import java.io.StringWriter JavaDoc;
22
23 import java.sql.Connection JavaDoc;
24 import java.sql.SQLException JavaDoc;
25
26 import java.util.Vector JavaDoc;
27
28 import javax.naming.Context JavaDoc;
29 import javax.naming.NamingException JavaDoc;
30 import javax.naming.InitialContext JavaDoc;
31
32 //import javax.sql.DataSource;
33

34 import org.apache.commons.dbcp.BasicDataSource;
35 //import org.apache.commons.dbcp.cpdsadapter.DriverAdapterCPDS;
36
//import org.apache.commons.pool.impl.GenericObjectPool;
37
//import org.apache.commons.dbcp.ConnectionFactory;
38
//import org.apache.commons.dbcp.DriverManagerConnectionFactory;
39
//import org.apache.commons.dbcp.PoolingDataSource;
40
//import org.apache.commons.dbcp.PoolableConnectionFactory;
41

42
43 import org.apache.avalon.excalibur.datasource.DataSourceComponent;
44 import org.apache.avalon.framework.activity.Disposable;
45 import org.apache.avalon.framework.configuration.Configurable;
46 import org.apache.avalon.framework.configuration.Configuration;
47 import org.apache.avalon.framework.configuration.ConfigurationException;
48 import org.apache.avalon.framework.logger.AbstractLogEnabled;
49
50 /**
51  * <p>
52  * This is a reliable DataSource implementation, based on the pooling logic provided by <a
53  * HREF="http://jakarta.apache.org/commons/dbcp.html">DBCP</a> and the configuration found in
54  * Avalon's excalibur code.
55  * </p>
56  *
57  * <p>
58  * This uses the normal <code>java.sql.Connection</code> object and
59  * <code>java.sql.DriverManager</code>. The Configuration is like this:
60  * <pre>
61  * &lt;jdbc&gt;
62
63  * &lt;pool-controller min="<i>5</i>" max="<i>10</i>" connection-class="<i>my.overrided.ConnectionClass</i>"&gt;
64  * &lt;keep-alive&gt;select 1&lt;/keep-alive&gt;
65  * &lt;/pool-controller&gt;
66
67  * &lt;driver&gt;<i>com.database.jdbc.JdbcDriver</i>&lt;/driver&gt;
68  * &lt;dburl&gt;<i>jdbc:driver://host/mydb</i>&lt;/dburl&gt;
69  * &lt;user&gt;<i>username</i>&lt;/user&gt;
70  * &lt;password&gt;<i>password</i>&lt;/password&gt;
71  * &lt;/jdbc&gt;
72  * </pre>
73  * </p>
74  * <p>
75  * These configuration settings are available:
76  * <ul>
77  * <li><b>driver</b> - The class name of the JDBC driver</li>
78  * <li><b>dburl</b> - The JDBC URL for this connection</li>
79  * <li><b>user</b> - The username to use for this connection</li>
80  * <li><b>password</b> - The password to use for this connection</li>
81  * <li><b>keep-alive</b> - The SQL query that will be used to validate connections from this pool before returning them to the caller. If specified, this query <strong>MUST</strong> be an SQL SELECT statement that returns at least one row.</li>
82  * <li><b>max</b> - The maximum number of active connections allowed in the pool. 0 means no limit. (default 2)</li>
83  * <li><b>max_idle</b> - The maximum number of idle connections. 0 means no limit. (default 0)</li>
84  * </ul>
85  *
86  * @version CVS $Revision: 1.1.2.3 $
87  */

88 public class JdbcDataSource extends AbstractLogEnabled
89     implements Configurable,
90                Disposable,
91                DataSourceComponent {
92
93     BasicDataSource source = null;
94     //Jdbc2PoolDataSource source = null;
95
//PoolingDataSource source = null;
96

97     /**
98      * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
99      */

100     public void configure(final Configuration configuration)
101                    throws ConfigurationException {
102         //Configure the DBCP
103
try {
104             String JavaDoc driver = configuration.getChild("driver").getValue(null);
105             Class.forName(driver);
106
107             String JavaDoc dburl = configuration.getChild("dburl").getValue(null);
108             String JavaDoc user = configuration.getChild("user").getValue(null);
109             String JavaDoc password = configuration.getChild("password").getValue(null);
110
111             // This inner class extends DBCP's BasicDataSource, and
112
// turns on validation (using Connection.isClosed()), so
113
// that the pool can recover from a server outage.
114
source = new BasicDataSource() {
115                 protected synchronized javax.sql.DataSource JavaDoc createDataSource()
116                         throws SQLException JavaDoc {
117                     if (dataSource != null) {
118                         return (dataSource);
119                     } else {
120                         javax.sql.DataSource JavaDoc ds = super.createDataSource();
121                         connectionPool.setTestOnBorrow(true);
122                         connectionPool.setTestOnReturn(true);
123                         return ds;
124                     }
125                 }
126             };
127
128             source.setDriverClassName(driver);
129             source.setUrl(dburl);
130             source.setUsername(user);
131             source.setPassword(password);
132             source.setMaxActive(configuration.getChild("max").getValueAsInteger(2));
133             source.setMaxIdle(configuration.getChild("max_idle").getValueAsInteger(0));
134             source.setValidationQuery(configuration.getChild("keep-alive").getValue(null));
135             //Unsupported
136
//source.setLoginTimeout(configuration.getChild("login_timeout").getValueAsInteger(0));
137

138             //This is necessary, otherwise a connection could hang forever
139
source.setMaxWait(configuration.getChild("max_wait").getValueAsInteger(5000));
140
141             // DBCP uses a PrintWriter approach to logging. This
142
// Writer class will bridge between DBCP and Avalon
143
// Logging. Unfortunately, DBCP 1.0 is clueless about the
144
// concept of a log level.
145
final java.io.Writer JavaDoc writer = new java.io.CharArrayWriter JavaDoc() {
146                 public void flush() {
147                     // flush the stream to the log
148
if (JdbcDataSource.this.getLogger().isErrorEnabled()) {
149                         JdbcDataSource.this.getLogger().error(toString());
150                     }
151                     reset(); // reset the contents for the next message
152
}
153             };
154
155             source.setLogWriter(new PrintWriter JavaDoc(writer, true));
156
157             /*
158             Extra debug for first cut
159             System.err.println("max wait: " + source.getMaxWait());
160             System.err.println("max idle: " + source.getMaxIdle());
161             System.err.println("max active: " + source.getMaxActive());
162             System.err.println("getRemoveAbandonedTimeout: " + source.getRemoveAbandonedTimeout());
163             System.err.println("getRemoveAbandoned(): " + source.getRemoveAbandoned());
164             System.err.println("getNumTestsPerEvictionRun(): " + source.getNumTestsPerEvictionRun());
165             System.err.println("getMinEvictableIdleTimeMillis(): " + source.getMinEvictableIdleTimeMillis());
166             System.err.println("getTimeBetweenEvictionRunsMillis(): " + source.getTimeBetweenEvictionRunsMillis());
167             */

168
169             /*
170             //Another sample that doesn't work
171             GenericObjectPool connectionPool = new GenericObjectPool(null);
172             ConnectionFactory connectionFactory =
173                     new DriverManagerConnectionFactory(dburl, user, password);
174             PoolableConnectionFactory poolableConnectionFactory =
175                     new PoolableConnectionFactory(connectionFactory, connectionPool, null, null, false, true);
176             PoolingDataSource dataSource = new PoolingDataSource(connectionPool);
177             source = dataSource;
178             */

179
180             /*
181              As documented on the DBCP website, which is wrong
182             DriverAdapterCPDS cpds = new DriverAdapterCPDS();
183             cpds.setDriver(configuration.getChild("driver").getValue(null));
184             cpds.setUrl(configuration.getChild("dburl").getValue(null));
185             cpds.setUsername(configuration.getChild("user").getValue(null));
186             cpds.setPassword(configuration.getChild("password").getValue(null));
187
188             source = new Jdbc2PoolDataSource();
189             source.setConnectionPoolDataSource(cpds);
190             source.setDefaultMaxActive(10);
191             source.setDefaultMaxWait(50);
192             */

193
194
195             //Get a connection and close it, just to test that we connected.
196
source.getConnection().close();
197         } catch (Exception JavaDoc e) {
198             throw new ConfigurationException("Error configurable datasource", e);
199         }
200     }
201
202     /**
203      * @see org.apache.avalon.framework.configuration.Configurable#dispose()
204      */

205     public void dispose() {
206         //Close all database connections
207
try {
208             source.close();
209         } catch (SQLException JavaDoc sqle) {
210             sqle.printStackTrace();
211         }
212     }
213
214     /**
215      *
216      */

217     public Connection JavaDoc getConnection() throws SQLException JavaDoc {
218         return source.getConnection();
219     }
220 }
221
Popular Tags