KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > outerj > daisy > datasource > JdbcDataSource


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

16 package org.outerj.daisy.datasource;
17
18 import java.io.PrintWriter JavaDoc;
19 import java.sql.Connection JavaDoc;
20 import java.sql.DatabaseMetaData JavaDoc;
21 import java.sql.SQLException JavaDoc;
22 import java.sql.Statement JavaDoc;
23 import java.util.regex.Matcher JavaDoc;
24 import java.util.regex.Pattern JavaDoc;
25
26 import javax.management.MBeanServer JavaDoc;
27 import javax.management.ObjectName JavaDoc;
28
29 import org.apache.avalon.framework.activity.Disposable;
30 import org.apache.avalon.framework.activity.Initializable;
31 import org.apache.avalon.framework.configuration.Configurable;
32 import org.apache.avalon.framework.configuration.Configuration;
33 import org.apache.avalon.framework.configuration.ConfigurationException;
34 import org.apache.avalon.framework.logger.AbstractLogEnabled;
35 import org.apache.avalon.framework.service.ServiceException;
36 import org.apache.avalon.framework.service.ServiceManager;
37 import org.apache.avalon.framework.service.Serviceable;
38 import org.apache.commons.dbcp.BasicDataSource;
39
40 /**
41  * A DataSource implementation based on Jakarta Commons DBCP.
42  *
43  * <p>Originally based on the JdbcDataSource from the Apache James projects.
44  *
45  * @avalon.component version="1.0" name="datasource" lifestyle="singleton"
46  * @avalon.service type="javax.sql.DataSource"
47  */

48 public class JdbcDataSource extends AbstractLogEnabled implements javax.sql.DataSource JavaDoc, Configurable,
49         Disposable, Serviceable, Initializable, JdbcDataSourceMBean {
50
51     private BasicDataSource source = null;
52     private ServiceManager serviceManager;
53     private boolean isMySQL = false;
54
55     public void configure(Configuration configuration) throws ConfigurationException {
56         //Configure the DBCP
57
try {
58             source = new BasicDataSource();
59
60             String JavaDoc url = configuration.getChild("url").getValue(null);
61             source.setUrl(url);
62             String JavaDoc username = configuration.getChild("username").getValue(null);
63             source.setUsername(username);
64             String JavaDoc password = configuration.getChild("password").getValue(null);
65             source.setPassword(password);
66
67             int maxActive = configuration.getChild("maxActive").getValueAsInteger(8);
68             int maxIdle = configuration.getChild("maxIdle").getValueAsInteger(8);
69             int minIdle = configuration.getChild("minIdle").getValueAsInteger(0);
70             int maxWait = configuration.getChild("maxWait").getValueAsInteger(5000);
71
72             source.setMaxActive(maxActive);
73             source.setMaxIdle(maxIdle);
74             source.setMinIdle(minIdle);
75             source.setMaxWait(maxWait);
76
77             Configuration propertyConf[] = configuration.getChild("connectionProperties").getChildren("property");
78             for (int i = 0; i < propertyConf.length; i++) {
79                 source.addConnectionProperty(propertyConf[i].getName(), propertyConf[i].getValue());
80             }
81
82             // DBCP uses a PrintWriter approach to logging. This
83
// Writer class will bridge between DBCP and Avalon
84
// Logging. Unfortunately, DBCP 1.0 is clueless about the
85
// concept of a log level.
86
final java.io.Writer JavaDoc writer = new java.io.CharArrayWriter JavaDoc() {
87                 public void flush() {
88                     // flush the stream to the log
89
if (JdbcDataSource.this.getLogger().isErrorEnabled()) {
90                         JdbcDataSource.this.getLogger().error(toString());
91                     }
92                     reset(); // reset the contents for the next message
93
}
94             };
95
96             source.setLogWriter(new PrintWriter JavaDoc(writer, true));
97
98             //Get a connection and close it, just to test that we connected and to determine if it is MySQL.
99
Connection JavaDoc conn = source.getConnection();
100             try {
101                 DatabaseMetaData JavaDoc metaData = conn.getMetaData();
102                 if (getLogger().isInfoEnabled())
103                     getLogger().info("Running on database: \"" + metaData.getDatabaseProductName() + "\" version \"" + metaData.getDatabaseProductVersion() + "\".");
104                 if (metaData.getDatabaseProductName().equals("MySQL")) {
105                     Pattern JavaDoc versionPattern = Pattern.compile("([0-9]+)\\.([0-9]+)\\.([0-9]+).*");
106                     Matcher JavaDoc versionMatcher = versionPattern.matcher(metaData.getDatabaseProductVersion());
107                     if (versionMatcher.matches()) {
108                         int majorVersion = Integer.parseInt(versionMatcher.group(1));
109                         int minorVersion = Integer.parseInt(versionMatcher.group(2));
110                         if ((majorVersion == 4 && minorVersion >= 1) || majorVersion > 4) {
111                             isMySQL = true;
112                         }
113                     }
114                 }
115             } finally {
116                 conn.close();
117             }
118         } catch (Exception JavaDoc e) {
119             throw new ConfigurationException("Error configurable datasource", e);
120         }
121     }
122
123     /**
124      * @avalon.dependency key="mbeanserver" type="javax.management.MBeanServer"
125      * @avalon.dependency key="driverregistrar" type="org.outerj.daisy.datasource.DriverRegistrar"
126      */

127     public void service(ServiceManager serviceManager) throws ServiceException {
128         this.serviceManager = serviceManager;
129     }
130
131     public void initialize() throws Exception JavaDoc {
132         MBeanServer JavaDoc mbeanServer = (MBeanServer JavaDoc)serviceManager.lookup("mbeanserver");
133         try {
134             mbeanServer.registerMBean(this, new ObjectName JavaDoc("Daisy:name=JdbcDataSource"));
135         } finally {
136             serviceManager.release(mbeanServer);
137         }
138     }
139
140     public void dispose() {
141         try {
142             source.close();
143         } catch (Throwable JavaDoc e) {
144             getLogger().error("Error disposing pool.", e);
145         }
146     }
147
148     public int getLoginTimeout() throws SQLException JavaDoc {
149         return source.getLoginTimeout();
150     }
151
152     public void setLoginTimeout(int seconds) throws SQLException JavaDoc {
153         source.setLoginTimeout(seconds);
154     }
155
156     public PrintWriter JavaDoc getLogWriter() throws SQLException JavaDoc {
157         return source.getLogWriter();
158     }
159
160     public void setLogWriter(PrintWriter JavaDoc out) throws SQLException JavaDoc {
161         throw new RuntimeException JavaDoc("I won't let you overwrite my log writer.");
162     }
163
164     public Connection JavaDoc getConnection() throws SQLException JavaDoc {
165         Connection JavaDoc conn = source.getConnection();
166         if (isMySQL) {
167             Statement JavaDoc stmt = null;
168             try {
169                 stmt = conn.createStatement();
170                 // Since we use double quotes to escape field names which are reserved names in Oracle,
171
// we need to set this option for MySQL
172
stmt.execute("SET sql_mode='ANSI_QUOTES'");
173             } finally {
174                 if (stmt != null)
175                     stmt.close();
176             }
177         }
178         return conn;
179     }
180
181     public Connection JavaDoc getConnection(String JavaDoc username, String JavaDoc password) throws SQLException JavaDoc {
182         return source.getConnection(username, password);
183     }
184
185     public int getNumActive() {
186         return source.getNumActive();
187     }
188
189     public int getNumIdle() {
190         return source.getNumIdle();
191     }
192
193     public String JavaDoc getUrl() {
194         return source.getUrl();
195     }
196
197     public String JavaDoc getUserName() {
198         return source.getUsername();
199     }
200
201     public int getMinIdle() {
202         return source.getMinIdle();
203     }
204
205     public int getMaxIdle() {
206         return source.getMaxIdle();
207     }
208
209     public int getMaxActive() {
210         return source.getMaxActive();
211     }
212 }
213
Popular Tags