View Javadoc

1   /*
2    * Copyright 2006 Outsource Cafe, Inc.
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.javagen.agile.db.util;
17  
18  import java.io.PrintWriter;
19  import java.sql.Connection;
20  import java.sql.DriverManager;
21  import java.sql.SQLException;
22  import java.util.Properties;
23  
24  import javax.sql.DataSource;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  
29  /***
30   * A generic way to access database drivers given the driver class name, url, username and password.
31   * <p>
32   * Compiled from code found in the Spring Framework.
33   *
34   * @author Richard Easterling
35   */
36  public class DriverManagerDataSource implements DataSource {
37  
38  	private static final Log log = LogFactory.getLog(DriverManagerDataSource.class);
39  
40  	private String driverClassName;
41  
42  	private String url;
43  
44  	private String username;
45  
46  	private String password;
47  
48  	private Properties connectionProperties;
49  
50  
51  	/***
52  	 * Constructor for bean-style configuration.
53  	 */
54  	public DriverManagerDataSource() {
55  	}
56  
57  	/***
58  	 * Create a new DriverManagerDataSource with the given standard
59  	 * DriverManager parameters.
60  	 * @param driverClassName the JDBC driver class name
61  	 * @param url the JDBC URL to use for accessing the DriverManager
62  	 * @param username the JDBC username to use for accessing the DriverManager
63  	 * @param password the JDBC password to use for accessing the DriverManager
64  	 * @see java.sql.DriverManager#getConnection(String, String, String)
65  	 */
66  	public DriverManagerDataSource(String driverClassName, String url, String username, String password)
67  			throws SQLException {
68  		setDriverClassName(driverClassName);
69  		setUrl(url);
70  		setUsername(username);
71  		setPassword(password);
72  	}
73  
74  	/***
75  	 * Create a new DriverManagerDataSource with the given standard
76  	 * DriverManager parameters.
77  	 * @param url the JDBC URL to use for accessing the DriverManager
78  	 * @param username the JDBC username to use for accessing the DriverManager
79  	 * @param password the JDBC password to use for accessing the DriverManager
80  	 * @see java.sql.DriverManager#getConnection(String, String, String)
81  	 */
82  	public DriverManagerDataSource(String url, String username, String password)
83  			throws SQLException {
84  		setUrl(url);
85  		setUsername(username);
86  		setPassword(password);
87  	}
88  
89  	/***
90  	 * Create a new DriverManagerDataSource with the given JDBC URL,
91  	 * not specifying a username or password for JDBC access.
92  	 * @param url the JDBC URL to use for accessing the DriverManager
93  	 * @see java.sql.DriverManager#getConnection(String)
94  	 */
95  	public DriverManagerDataSource(String url)
96  			throws SQLException {
97  		setUrl(url);
98  	}
99  
100 
101 	/***
102 	 * Set the JDBC driver class name. This driver will get initialized
103 	 * on startup, registering itself with the JDK's DriverManager.
104 	 * <p>Alternatively, consider initializing the JDBC driver yourself
105 	 * before instantiating this DataSource.
106 	 * @see Class#forName(String)
107 	 * @see java.sql.DriverManager#registerDriver(java.sql.Driver)
108 	 */
109 	public void setDriverClassName(String driverClassName) throws SQLException {
110 		if (driverClassName==null || driverClassName.trim().length()==0) {
111 			throw new IllegalArgumentException("driverClassName must not be empty");
112 		}
113 		this.driverClassName = driverClassName;
114 		try {
115 			Class.forName(this.driverClassName, true, getDefaultClassLoader());
116 		}
117 		catch (ClassNotFoundException e) {
118 			SQLException ex = new SQLException("Could not load JDBC driver class [" + this.driverClassName + "]: "+e.getMessage());
119 			ex.initCause(e);
120 			throw ex;
121 		}
122 		if (log.isInfoEnabled()) {
123 			log.info("Loaded JDBC driver: " + this.driverClassName);
124 		}
125 	}
126 
127 	/***
128 	 * Return the JDBC driver class name, if any.
129 	 */
130 	public String getDriverClassName() {
131 		return driverClassName;
132 	}
133 
134 	/***
135 	 * Set the JDBC URL to use for accessing the DriverManager.
136 	 * @see java.sql.DriverManager#getConnection(String, String, String)
137 	 */
138 	public void setUrl(String url) {
139 		if (url==null || url.trim().length()==0) {
140 			throw new IllegalArgumentException("url must not be empty");
141 		}
142 		this.url = url;
143 	}
144 
145 	/***
146 	 * Return the JDBC URL to use for accessing the DriverManager.
147 	 */
148 	public String getUrl() {
149 		return url;
150 	}
151 
152 	/***
153 	 * Set the JDBC username to use for accessing the DriverManager.
154 	 * @see java.sql.DriverManager#getConnection(String, String, String)
155 	 */
156 	public void setUsername(String username) {
157 		this.username = username;
158 	}
159 
160 	/***
161 	 * Return the JDBC username to use for accessing the DriverManager.
162 	 */
163 	public String getUsername() {
164 		return username;
165 	}
166 
167 	/***
168 	 * Set the JDBC password to use for accessing the DriverManager.
169 	 * @see java.sql.DriverManager#getConnection(String, String, String)
170 	 */
171 	public void setPassword(String password) {
172 		this.password = password;
173 	}
174 
175 	/***
176 	 * Return the JDBC password to use for accessing the DriverManager.
177 	 */
178 	public String getPassword() {
179 		return password;
180 	}
181 
182 	/***
183 	 * Specify arbitrary connection properties as key/value pairs,
184 	 * to be passed to the DriverManager.
185 	 * <p>Can also contain "user" and "password" properties. However,
186 	 * any "username" and "password" bean properties specified on this
187 	 * DataSource will override the respective connection properties.
188 	 * @see java.sql.DriverManager#getConnection(String, java.util.Properties)
189 	 */
190 	public void setConnectionProperties(Properties connectionProperties) {
191 		this.connectionProperties = connectionProperties;
192 	}
193 
194 	/***
195 	 * Return the connection properties to be passed to the DriverManager,
196 	 * if any.
197 	 */
198 	public Properties getConnectionProperties() {
199 		return connectionProperties;
200 	}
201 
202 
203 	/***
204 	 * This implementation delegates to <code>getConnectionFromDriverManager</code>,
205 	 * using the default username and password of this DataSource.
206 	 * @see #getConnectionFromDriverManager()
207 	 */
208 	public Connection getConnection() throws SQLException {
209 		return getConnectionFromDriverManager();
210 	}
211 
212 	/***
213 	 * This implementation delegates to <code>getConnectionFromDriverManager</code>,
214 	 * using the given username and password.
215 	 * @see #getConnectionFromDriverManager(String, String)
216 	 */
217 	public Connection getConnection(String username, String password) throws SQLException {
218 		return getConnectionFromDriverManager(username, password);
219 	}
220 
221 	/***
222 	 * Get a Connection from the DriverManager,
223 	 * using the default username and password of this DataSource.
224 	 * @see #getConnectionFromDriverManager(String, String)
225 	 */
226 	protected Connection getConnectionFromDriverManager() throws SQLException {
227 		return getConnectionFromDriverManager(getUsername(), getPassword());
228 	}
229 
230 	/***
231 	 * Build properties for the DriverManager, including the given username
232 	 * and password (if any).
233 	 * @see #getConnectionFromDriverManager(String, java.util.Properties)
234 	 */
235 	protected Connection getConnectionFromDriverManager(String username, String password)
236 	    throws SQLException {
237 
238 		Properties props = new Properties(getConnectionProperties());
239 		if (username != null) {
240 			props.setProperty("user", username);
241 		}
242 		if (password != null) {
243 			props.setProperty("password", password);
244 		}
245 		return getConnectionFromDriverManager(getUrl(), props);
246 	}
247 
248 	/***
249 	 * Getting a connection using the nasty static from DriverManager is extracted
250 	 * into a protected method to allow for easy unit testing.
251 	 * @see java.sql.DriverManager#getConnection(String, java.util.Properties)
252 	 */
253 	protected Connection getConnectionFromDriverManager(String url, Properties props)
254 	    throws SQLException {
255 
256 		if (log.isDebugEnabled()) {
257 			log.debug("Creating new JDBC Connection to [" + url + "]");
258 		}
259 		return DriverManager.getConnection(url, props);
260 	}
261 
262 	/***
263 	 * Returns 0: means use default system timeout.
264 	 */
265 	public int getLoginTimeout() throws SQLException {
266 		return 0;
267 	}
268 
269 	public void setLoginTimeout(int timeout) throws SQLException {
270 		throw new UnsupportedOperationException("setLoginTimeout");
271 	}
272 
273 	/***
274 	 * LogWriter methods are unsupported.
275 	 */
276 	public PrintWriter getLogWriter() {
277 		throw new UnsupportedOperationException("getLogWriter");
278 	}
279 
280 	/***
281 	 * LogWriter methods are unsupported.
282 	 */
283 	public void setLogWriter(PrintWriter pw) throws SQLException {
284 		throw new UnsupportedOperationException("setLogWriter");
285 	}
286 
287     public static ClassLoader getDefaultClassLoader() {
288         ClassLoader cl = Thread.currentThread().getContextClassLoader();
289         if (cl == null) {
290             // No thread context class loader -> use class loader of this class.
291             cl = DriverManagerDataSource.class.getClassLoader();
292         }
293         return cl;
294     }
295 }