1 | /* |
2 | Copyright (C) 2002-2004 MySQL AB |
3 | |
4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of version 2 of the GNU General Public License as |
6 | published by the Free Software Foundation. |
7 | |
8 | There are special exceptions to the terms and conditions of the GPL |
9 | as it is applied to this software. View the full text of the |
10 | exception in file EXCEPTIONS-CONNECTOR-J in the directory of this |
11 | software distribution. |
12 | |
13 | This program is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU General Public License |
19 | along with this program; if not, write to the Free Software |
20 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | |
22 | |
23 | |
24 | */ |
25 | package com.mysql.jdbc.jdbc2.optional; |
26 | |
27 | import com.mysql.jdbc.ConnectionProperties; |
28 | import com.mysql.jdbc.NonRegisteringDriver; |
29 | |
30 | import java.io.PrintWriter; |
31 | import java.io.Serializable; |
32 | |
33 | import java.sql.SQLException; |
34 | |
35 | import java.util.Properties; |
36 | |
37 | import javax.naming.NamingException; |
38 | import javax.naming.Reference; |
39 | import javax.naming.Referenceable; |
40 | import javax.naming.StringRefAddr; |
41 | |
42 | import javax.sql.DataSource; |
43 | |
44 | /** |
45 | * A JNDI DataSource for a Mysql JDBC connection |
46 | * |
47 | * @author Mark Matthews |
48 | */ |
49 | public class MysqlDataSource extends ConnectionProperties implements |
50 | DataSource, Referenceable, Serializable { |
51 | /** The driver to create connections with */ |
52 | protected static com.mysql.jdbc.Driver mysqlDriver = null; |
53 | |
54 | static { |
55 | try { |
56 | mysqlDriver = (com.mysql.jdbc.Driver) Class.forName( |
57 | "com.mysql.jdbc.Driver").newInstance(); |
58 | } catch (Exception E) { |
59 | throw new RuntimeException( |
60 | "Can not load Driver class com.mysql.jdbc.Driver"); |
61 | } |
62 | } |
63 | |
64 | /** Log stream */ |
65 | protected PrintWriter logWriter = null; |
66 | |
67 | /** Database Name */ |
68 | protected String databaseName = null; |
69 | |
70 | /** Character Encoding */ |
71 | protected String encoding = null; |
72 | |
73 | /** Hostname */ |
74 | protected String hostName = null; |
75 | |
76 | /** Password */ |
77 | protected String password = null; |
78 | |
79 | /** The profileSql property */ |
80 | protected String profileSql = "false"; |
81 | |
82 | /** The JDBC URL */ |
83 | protected String url = null; |
84 | |
85 | /** User name */ |
86 | protected String user = null; |
87 | |
88 | /** Should we construct the URL, or has it been set explicitly */ |
89 | protected boolean explicitUrl = false; |
90 | |
91 | /** Port number */ |
92 | protected int port = 3306; |
93 | |
94 | /** |
95 | * Default no-arg constructor for Serialization |
96 | */ |
97 | public MysqlDataSource() { |
98 | } |
99 | |
100 | /** |
101 | * Creates a new connection using the already configured username and |
102 | * password. |
103 | * |
104 | * @return a connection to the database |
105 | * |
106 | * @throws SQLException |
107 | * if an error occurs |
108 | */ |
109 | public java.sql.Connection getConnection() throws SQLException { |
110 | return getConnection(this.user, this.password); |
111 | } |
112 | |
113 | /** |
114 | * Creates a new connection with the given username and password |
115 | * |
116 | * @param userID |
117 | * the user id to connect with |
118 | * @param password |
119 | * the password to connect with |
120 | * |
121 | * @return a connection to the database |
122 | * |
123 | * @throws SQLException |
124 | * if an error occurs |
125 | */ |
126 | public java.sql.Connection getConnection(String userID, String pass) |
127 | throws SQLException { |
128 | Properties props = new Properties(); |
129 | |
130 | if (userID != null) { |
131 | props.setProperty(NonRegisteringDriver.USER_PROPERTY_KEY, userID); |
132 | } |
133 | |
134 | if (pass != null) { |
135 | props.setProperty(NonRegisteringDriver.PASSWORD_PROPERTY_KEY, pass); |
136 | } |
137 | |
138 | exposeAsProperties(props); |
139 | |
140 | return getConnection(props); |
141 | } |
142 | |
143 | /** |
144 | * Sets the database name. |
145 | * |
146 | * @param dbName |
147 | * the name of the database |
148 | */ |
149 | public void setDatabaseName(String dbName) { |
150 | this.databaseName = dbName; |
151 | } |
152 | |
153 | /** |
154 | * Gets the name of the database |
155 | * |
156 | * @return the name of the database for this data source |
157 | */ |
158 | public String getDatabaseName() { |
159 | return (this.databaseName != null) ? this.databaseName : ""; |
160 | } |
161 | |
162 | /** |
163 | * Sets the log writer for this data source. |
164 | * |
165 | * @see javax.sql.DataSource#setLogWriter(PrintWriter) |
166 | */ |
167 | public void setLogWriter(PrintWriter output) throws SQLException { |
168 | this.logWriter = output; |
169 | } |
170 | |
171 | /** |
172 | * Returns the log writer for this data source |
173 | * |
174 | * @return the log writer for this data source |
175 | */ |
176 | public java.io.PrintWriter getLogWriter() { |
177 | return this.logWriter; |
178 | } |
179 | |
180 | /** |
181 | * DOCUMENT ME! |
182 | * |
183 | * @param seconds |
184 | * DOCUMENT ME! |
185 | * |
186 | * @throws SQLException |
187 | * DOCUMENT ME! |
188 | */ |
189 | public void setLoginTimeout(int seconds) throws SQLException { |
190 | } |
191 | |
192 | /** |
193 | * Returns the login timeout |
194 | * |
195 | * @return the login timeout |
196 | */ |
197 | public int getLoginTimeout() { |
198 | return 0; |
199 | } |
200 | |
201 | /** |
202 | * Sets the password |
203 | * |
204 | * @param pass |
205 | * the password |
206 | */ |
207 | public void setPassword(String pass) { |
208 | this.password = pass; |
209 | } |
210 | |
211 | /** |
212 | * Sets the database port. |
213 | * |
214 | * @param p |
215 | * the port |
216 | */ |
217 | public void setPort(int p) { |
218 | this.port = p; |
219 | } |
220 | |
221 | /** |
222 | * Returns the port number |
223 | * |
224 | * @return the port number |
225 | */ |
226 | public int getPort() { |
227 | return this.port; |
228 | } |
229 | |
230 | /** |
231 | * Sets the port number |
232 | * |
233 | * @param p |
234 | * the port |
235 | * |
236 | * @see #setPort |
237 | */ |
238 | public void setPortNumber(int p) { |
239 | setPort(p); |
240 | } |
241 | |
242 | /** |
243 | * Returns the port number |
244 | * |
245 | * @return the port number |
246 | */ |
247 | public int getPortNumber() { |
248 | return getPort(); |
249 | } |
250 | |
251 | /** |
252 | * DOCUMENT ME! |
253 | * |
254 | * @param ref |
255 | * DOCUMENT ME! |
256 | * |
257 | * @throws SQLException |
258 | * DOCUMENT ME! |
259 | */ |
260 | public void setPropertiesViaRef(Reference ref) throws SQLException { |
261 | super.initializeFromRef(ref); |
262 | } |
263 | |
264 | /** |
265 | * Required method to support this class as a <CODE>Referenceable</CODE>. |
266 | * |
267 | * @return a Reference to this data source |
268 | * |
269 | * @throws NamingException |
270 | * if a JNDI error occurs |
271 | */ |
272 | public Reference getReference() throws NamingException { |
273 | String factoryName = "com.mysql.jdbc.jdbc2.optional.MysqlDataSourceFactory"; |
274 | Reference ref = new Reference(getClass().getName(), factoryName, null); |
275 | ref.add(new StringRefAddr(NonRegisteringDriver.USER_PROPERTY_KEY, |
276 | getUser())); |
277 | ref.add(new StringRefAddr(NonRegisteringDriver.PASSWORD_PROPERTY_KEY, |
278 | this.password)); |
279 | ref.add(new StringRefAddr("serverName", getServerName())); |
280 | ref.add(new StringRefAddr("port", "" + getPort())); |
281 | ref.add(new StringRefAddr("databaseName", getDatabaseName())); |
282 | ref.add(new StringRefAddr("url", getUrl())); |
283 | ref.add(new StringRefAddr("explicitUrl", String |
284 | .valueOf(this.explicitUrl))); |
285 | |
286 | // |
287 | // Now store all of the 'non-standard' properties... |
288 | // |
289 | try { |
290 | storeToRef(ref); |
291 | } catch (SQLException sqlEx) { |
292 | throw new NamingException(sqlEx.getMessage()); |
293 | } |
294 | |
295 | return ref; |
296 | } |
297 | |
298 | /** |
299 | * Sets the server name. |
300 | * |
301 | * @param serverName |
302 | * the server name |
303 | */ |
304 | public void setServerName(String serverName) { |
305 | this.hostName = serverName; |
306 | } |
307 | |
308 | /** |
309 | * Returns the name of the database server |
310 | * |
311 | * @return the name of the database server |
312 | */ |
313 | public String getServerName() { |
314 | return (this.hostName != null) ? this.hostName : ""; |
315 | } |
316 | |
317 | // |
318 | // I've seen application servers use both formats |
319 | // URL or url (doh) |
320 | // |
321 | |
322 | /** |
323 | * Sets the URL for this connection |
324 | * |
325 | * @param url |
326 | * the URL for this connection |
327 | */ |
328 | public void setURL(String url) { |
329 | setUrl(url); |
330 | } |
331 | |
332 | /** |
333 | * Returns the URL for this connection |
334 | * |
335 | * @return the URL for this connection |
336 | */ |
337 | public String getURL() { |
338 | return getUrl(); |
339 | } |
340 | |
341 | /** |
342 | * This method is used by the app server to set the url string specified |
343 | * within the datasource deployment descriptor. It is discovered using |
344 | * introspection and matches if property name in descriptor is "url". |
345 | * |
346 | * @param url |
347 | * url to be used within driver.connect |
348 | */ |
349 | public void setUrl(String url) { |
350 | this.url = url; |
351 | this.explicitUrl = true; |
352 | } |
353 | |
354 | /** |
355 | * Returns the JDBC URL that will be used to create the database connection. |
356 | * |
357 | * @return the URL for this connection |
358 | */ |
359 | public String getUrl() { |
360 | if (!this.explicitUrl) { |
361 | String builtUrl = "jdbc:mysql://"; |
362 | builtUrl = builtUrl + getServerName() + ":" + getPort() + "/" |
363 | + getDatabaseName(); |
364 | |
365 | return builtUrl; |
366 | } |
367 | |
368 | return this.url; |
369 | } |
370 | |
371 | /** |
372 | * Sets the user ID. |
373 | * |
374 | * @param userID |
375 | * the User ID |
376 | */ |
377 | public void setUser(String userID) { |
378 | this.user = userID; |
379 | } |
380 | |
381 | /** |
382 | * Returns the configured user for this connection |
383 | * |
384 | * @return the user for this connection |
385 | */ |
386 | public String getUser() { |
387 | return this.user; |
388 | } |
389 | |
390 | /** |
391 | * Creates a connection using the specified properties. |
392 | * |
393 | * @param props |
394 | * the properties to connect with |
395 | * |
396 | * @return a connection to the database |
397 | * |
398 | * @throws SQLException |
399 | * if an error occurs |
400 | */ |
401 | protected java.sql.Connection getConnection(Properties props) |
402 | throws SQLException { |
403 | String jdbcUrlToUse = null; |
404 | |
405 | if (!this.explicitUrl) { |
406 | StringBuffer jdbcUrl = new StringBuffer("jdbc:mysql://"); |
407 | |
408 | if (this.hostName != null) { |
409 | jdbcUrl.append(this.hostName); |
410 | } |
411 | |
412 | jdbcUrl.append(":"); |
413 | jdbcUrl.append(this.port); |
414 | jdbcUrl.append("/"); |
415 | |
416 | if (this.databaseName != null) { |
417 | jdbcUrl.append(this.databaseName); |
418 | } |
419 | |
420 | jdbcUrlToUse = jdbcUrl.toString(); |
421 | } else { |
422 | jdbcUrlToUse = this.url; |
423 | } |
424 | |
425 | return mysqlDriver.connect(jdbcUrlToUse, props); |
426 | } |
427 | } |