1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.dbforms.config;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29 import org.dbforms.conprovider.ConnectionFactory;
30 import org.dbforms.conprovider.ConnectionProviderPrefs;
31
32 import org.dbforms.util.Util;
33
34 import java.io.PrintWriter;
35
36 import java.sql.Connection;
37 import java.sql.DriverManager;
38 import java.sql.SQLException;
39
40 import java.util.Properties;
41
42 import javax.naming.Context;
43 import javax.naming.InitialContext;
44 import javax.naming.NamingException;
45
46 import javax.sql.DataSource;
47
48
49
50 /***
51 * This class represents datastructures like to following examples: <br>
52 * <pre>
53 *
54 * <dbconnection
55 * name = "jdbc/dbformstest"
56 * isJndi = "true"
57 * />
58 * </pre>
59 *
60 * <p>
61 * (in the example above dbforms asumes that the jndi-entry "jdbc/dbformstest"
62 * is correctly configured in the application-server's database configuration
63 * [i.e. date-sources.xml])
64 * </p>
65 *
66 * <p>
67 * or:
68 * </p>
69 * <pre>
70 * <dbconnection
71 * name = "jdbc:poolman://dbformstest"
72 * isJndi = "false"
73 * class = "com.codestudio.sql.PoolMan"
74 * />
75 * </pre>
76 *
77 * <p>
78 * (in the example above dbforms asumes that the connectionpool-entry
79 * "dbformstest" is correctly configured in the associated connection pool
80 * properties file).
81 * </p>
82 *
83 * <p>
84 * As these examples show, the configuration of datasources is beyond the scope
85 * of dbforms. That is a task of the underlying applicationserver/jsp-engine!
86 * </p>
87 *
88 * @author Joe Peer
89 * @version 0.8.3 Kevin Dangoor added Username and Passwort properties
90 */
91 public class DbConnection implements javax.sql.DataSource {
92 private static Log logCat = LogFactory.getLog(DbConnection.class);
93
94 /*** connection factory instance */
95 private ConnectionFactory connectionFactory = ConnectionFactory.instance();
96
97 /*** connection pool properties */
98 private Properties poolProperties;
99
100 /*** JDBC properties */
101 private Properties properties;
102
103 /*** JDBC drivermanager class */
104 private String conClass;
105
106 /*** connection provider URL */
107 private String connectionPoolURL;
108
109 /*** connection provider class */
110 private String connectionProviderClass;
111
112 /***
113 * ContextDS flag. If set, an existing DataSource from Context-Scope would
114 * be used (e.g. from Struts)
115 */
116 private String contextDataSource;
117
118 /*** connection id */
119 private String id;
120
121 /*** JNDI flag */
122 private String isJndi = "false";
123
124 /*** connection name */
125 private String name;
126
127 /*** database password */
128 private String password;
129
130 /*** database user name */
131 private String username;
132
133 /*** default connection flag */
134 private boolean defaultConnection = false;
135
136 /***
137 * connection factory configuration flag. If true, the connection factory is
138 * already configured
139 */
140 private boolean isFactorySetup = false;
141
142 /*** */
143 private boolean isPropSetup = false;
144
145 /*** JNDI flag. Sei it to true to get connection objects from a JNDI service */
146 private boolean jndi = false;
147
148 /***
149 * connection factory flag. Set it to true to use connection factory to get
150 * JDBC connection objects
151 */
152 private boolean pow2 = false;
153
154 /***
155 * Constructor.
156 */
157 public DbConnection() {
158 properties = new java.util.Properties();
159 poolProperties = new java.util.Properties();
160 }
161
162 /***
163 * Sets the conClass attribute of the DbConnection object
164 *
165 * @param conClass The new conClass value
166 */
167 public void setConClass(String conClass) {
168 this.conClass = conClass;
169 }
170
171
172 /***
173 * Gets the conClass attribute of the DbConnection object
174 *
175 * @return The conClass value
176 */
177 public String getConClass() {
178 return conClass;
179 }
180
181
182 /***
183 * Gets a JDBC connection object.
184 *
185 * @return the connection object, or null if any error occurs
186 */
187 public Connection getConnection() {
188 Connection con = null;
189
190
191
192 if (jndi) {
193 con = getConnectionFromJNDI(name);
194 }
195
196
197 else if (pow2) {
198 con = getConnectionFromFactory();
199 }
200
201 else {
202 con = getConnectionFromDriverManager();
203 }
204
205 return con;
206 }
207
208
209 /***
210 * returns a Connection
211 *
212 * @param username DOCUMENT ME!
213 * @param password DOCUMENT ME!
214 *
215 * @return DOCUMENT ME!
216 */
217 public Connection getConnection(String p_username,
218 String p_password) throws SQLException {
219 setUsername(p_username);
220 setPassword(p_password);
221
222 return getConnection();
223 }
224
225
226 /***
227 * Sets the connectionPoolURL attribute of the DbConnection object
228 *
229 * @param url The new connectionPoolURL value
230 */
231 public void setConnectionPoolURL(String url) {
232 connectionPoolURL = url;
233 }
234
235
236 /***
237 * Gets the connectionPoolURL attribute of the DbConnection object
238 *
239 * @return The connectionPoolURL value
240 */
241 public String getConnectionPoolURL() {
242 return connectionPoolURL;
243 }
244
245
246 /***
247 * Sets the connectionProviderClass attribute of the DbConnection object
248 *
249 * @param cpc The new connectionProviderClass value
250 */
251 public void setConnectionProviderClass(String cpc) {
252 connectionProviderClass = cpc;
253 }
254
255
256 /***
257 * Gets the connectionProviderClass attribute of the DbConnection object
258 *
259 * @return The connectionProviderClass value
260 */
261 public String getConnectionProviderClass() {
262 return connectionProviderClass;
263 }
264
265
266 /***
267 * sets the name of the parameter from context-Scope which contains a
268 * DataSource-Object
269 *
270 * @param contextDataSource
271 */
272 public void setContextDataSource(String contextDataSource) {
273 this.contextDataSource = contextDataSource;
274 }
275
276
277 /***
278 * returns the name of the parameter from context-Scope which contains a
279 * DataSource-Object
280 *
281 * @return contextDataSource - the name
282 */
283 public String getContextDataSource() {
284 return contextDataSource;
285 }
286
287
288 /***
289 * Sets the defaultConnection attribute of the DbConnection object
290 *
291 * @param defaultConnection The new defaultConnection value
292 */
293 public void setDefaultConnection(boolean defaultConnection) {
294 this.defaultConnection = defaultConnection;
295 }
296
297
298 /***
299 * Gets the defaultConnection attribute of the DbConnection object
300 *
301 * @return The defaultConnection value
302 */
303 public boolean isDefaultConnection() {
304 return defaultConnection;
305 }
306
307
308 /***
309 * DataSource interface
310 *
311 * @param driverClassName DOCUMENT ME!
312 */
313 public void setDriverClassName(String driverClassName) {
314 setConClass(driverClassName);
315 }
316
317
318 /***
319 * Sets the id attribute of the DbConnection object
320 *
321 * @param id The new id value
322 */
323 public void setId(String id) {
324 this.id = id;
325 }
326
327
328 /***
329 * Gets the id attribute of the DbConnection object
330 *
331 * @return The id value
332 */
333 public String getId() {
334 return id;
335 }
336
337
338 /***
339 * Sets the isJndi attribute of the DbConnection object
340 *
341 * @param isJndi The new isJndi value
342 */
343 public void setIsJndi(String isJndi) {
344 this.isJndi = isJndi;
345 jndi = Util.getTrue(isJndi);
346 }
347
348
349 /***
350 * Sets the isPow2 attribute of the DbConnection object
351 *
352 * @param isPow2 The new isPow2 value
353 */
354 public void setIsPow2(String isPow2) {
355 pow2 = Util.getTrue(isPow2);
356 }
357
358
359 /***
360 * DOCUMENT ME!
361 *
362 * @param jdbcURL DOCUMENT ME!
363 */
364 public void setJdbcURL(String jdbcURL) {
365 setName(jdbcURL);
366 }
367
368
369 /***
370 * Always throws a SQLException. Not supported.
371 *
372 * @param out DOCUMENT ME!
373 */
374 public void setLogWriter(PrintWriter out) throws SQLException {
375 throw new SQLException("dbforms.error.not_supported");
376 }
377
378
379 /***
380 * Always throws a SQLException. Not supported.
381 *
382 * @return DOCUMENT ME!
383 */
384 public PrintWriter getLogWriter() throws SQLException {
385 throw new SQLException("dbforms.error.not_supported");
386 }
387
388
389 /***
390 * Always throws a SQLException. Not supported.
391 *
392 * @param seconds DOCUMENT ME!
393 */
394 public void setLoginTimeout(int seconds) throws SQLException {
395 throw new SQLException("dbforms.error.not_supported");
396 }
397
398
399 /***
400 * Always throws a SQLException. Not supported.
401 *
402 * @return DOCUMENT ME!
403 */
404 public int getLoginTimeout() throws SQLException {
405 throw new SQLException("dbforms.error.not_supported");
406 }
407
408
409 /***
410 * Sets the name attribute of the DbConnection object
411 *
412 * @param name The new name value
413 */
414 public void setName(String name) {
415 this.name = name;
416 }
417
418
419 /***
420 * Gets the name attribute of the DbConnection object
421 *
422 * @return The name value
423 */
424 public String getName() {
425 return name;
426 }
427
428
429 /***
430 * Sets the password attribute of the DbConnection object
431 *
432 * @param newpass The new password value
433 */
434 public void setPassword(String newpass) {
435 this.password = newpass;
436 }
437
438
439 /***
440 * Gets the password attribute of the DbConnection object
441 *
442 * @return The password value
443 */
444 public String getPassword() {
445 return password;
446 }
447
448
449 /***
450 * Sets the username attribute of the DbConnection object
451 *
452 * @param newuser The new username value
453 */
454 public void setUsername(String newuser) {
455 this.username = newuser;
456 }
457
458
459 /***
460 * Gets the username attribute of the DbConnection object
461 *
462 * @return The username value
463 */
464 public String getUsername() {
465 return username;
466 }
467
468
469 /***
470 * Adds a new pool property - used while parsing XML file
471 *
472 * @param prop The feature to be added to the PoolProperty attribute
473 */
474 public void addPoolProperty(String name, String prop) {
475 poolProperties.put(prop, prop);
476 }
477
478
479 /***
480 * Adds a new property - used while parsing XML file
481 *
482 * @param prop The feature to be added to the Property attribute
483 */
484 public void addProperty(String name, String prop) {
485 properties.put(prop, prop);
486 }
487
488
489 /***
490 * Description of the Method
491 *
492 * @return Description of the Return Value
493 */
494 public String getisJndi() {
495 return isJndi;
496 }
497
498
499 /***
500 * Gets the string representation of this object.
501 *
502 * @return the string representation of this object
503 */
504 public String toString() {
505 StringBuffer buf = new StringBuffer("DbConnection = ");
506
507 buf.append("id=" + id)
508 .append(", name=" + name)
509 .append(", jndi=" + isJndi)
510 .append(", conClass=" + conClass)
511 .append(", username=" + username)
512 .append(", default=" + defaultConnection);
513
514 if (pow2) {
515 buf.append(", connectionProviderClass=" + connectionProviderClass)
516 .append(", connectionPoolURL=" + connectionPoolURL);
517 }
518
519 if (!properties.isEmpty()) {
520 buf.append(", jdbc properties: ")
521 .append(properties);
522 }
523
524 if (!poolProperties.isEmpty()) {
525 buf.append(", connection pool properties: ")
526 .append(poolProperties);
527 }
528
529
530 return buf.toString();
531 }
532
533
534 /***
535 * Gets a JDBC connection object from the DriverManager class specified by
536 * the conClass member attribute.
537 *
538 * @return the JDBC connection object, or null if any error occurs
539 */
540 private Connection getConnectionFromDriverManager() {
541 Connection con = null;
542
543 try {
544 Class.forName(conClass)
545 .newInstance();
546
547 if (!properties.isEmpty()) {
548 if (!isPropSetup) {
549 properties.put("user", getUsername());
550 properties.put("password", getPassword());
551 isPropSetup = true;
552 }
553
554 con = DriverManager.getConnection(name, properties);
555 } else if (username != null) {
556 con = DriverManager.getConnection(name, username, password);
557 } else {
558 con = DriverManager.getConnection(name);
559 }
560 } catch (Exception e) {
561 logCat.error("::getConnectionFromDriverManager - cannot retrieve a connection from DriverManager",
562 e);
563 }
564
565 return con;
566 }
567
568
569 /***
570 * Gets a JDBC connection object from the connection factory.
571 *
572 * @return the JDBC connection object, or null if any error occurs
573 */
574 private Connection getConnectionFromFactory() {
575 Connection con = null;
576
577 try {
578 if (!isFactorySetup) {
579 setupConnectionFactory();
580 }
581
582 con = connectionFactory.getConnection();
583 } catch (Exception se) {
584 logCat.error("::getConnectionFromFactory - cannot retrieve a connection from the connectionFactory",
585 se);
586 }
587
588 return con;
589 }
590
591
592 /***
593 * PRIVATE METHODs here
594 *
595 * @param lookupString DOCUMENT ME!
596 *
597 * @return DOCUMENT ME!
598 */
599 /***
600 * Gets a JDBC connection object from a JNDI server.
601 *
602 * @param lookupString the string used to lookup the datasource object from
603 * the JNDI server
604 *
605 * @return the JDBC connection object, or null if the lookup fails
606 */
607 private Connection getConnectionFromJNDI(String lookupString) {
608 Connection con = null;
609
610
611
612 try {
613 Context ctx = new InitialContext();
614 DataSource ds = (DataSource) ctx.lookup(lookupString);
615
616 if (ds != null) {
617 con = ds.getConnection();
618 } else {
619 logCat.error("::getConnectionFromJNDI - DataSource object is null");
620 }
621 } catch (NamingException ne) {
622 logCat.error("::getConnectionFromJNDI - cannot retrieve a connection from JNDI:",
623 ne);
624 } catch (Exception e) {
625 logCat.error("::getConnectionFromJNDI - exception:", e);
626 }
627
628 return con;
629 }
630
631
632 /***
633 * Set up the ConnectionFactory
634 *
635 * @exception Exception if any error occurs
636 */
637 private void setupConnectionFactory() throws Exception {
638 ConnectionProviderPrefs prefs = new ConnectionProviderPrefs();
639
640 prefs.setConnectionProviderClass(connectionProviderClass);
641 prefs.setConnectionPoolURL(connectionPoolURL);
642 prefs.setJdbcDriver(conClass);
643 prefs.setJdbcURL(name);
644 prefs.setUser(username);
645 prefs.setPassword(password);
646 prefs.setProperties(properties);
647 prefs.setPoolProperties(poolProperties);
648 prefs.setServletContext(DbFormsConfigRegistry.instance().lookup().getServletContext());
649 connectionFactory.setProvider(prefs);
650 isFactorySetup = true;
651 }
652 }