KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > sql > DriverConfig


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.sql;
31
32 import com.caucho.config.BuilderProgram;
33 import com.caucho.config.BuilderProgramContainer;
34 import com.caucho.config.Config;
35 import com.caucho.config.ConfigException;
36 import com.caucho.config.StringAttributeProgram;
37 import com.caucho.config.types.InitParam;
38 import com.caucho.log.Log;
39 import com.caucho.management.j2ee.J2EEManagedObject;
40 import com.caucho.management.j2ee.JDBCDriver;
41 import com.caucho.naming.Jndi;
42 import com.caucho.tools.profiler.ConnectionPoolDataSourceWrapper;
43 import com.caucho.tools.profiler.DriverWrapper;
44 import com.caucho.tools.profiler.ProfilerPoint;
45 import com.caucho.tools.profiler.ProfilerPointConfig;
46 import com.caucho.tools.profiler.XADataSourceWrapper;
47 import com.caucho.util.L10N;
48
49 import javax.resource.spi.ManagedConnectionFactory JavaDoc;
50 import javax.sql.ConnectionPoolDataSource JavaDoc;
51 import javax.sql.PooledConnection JavaDoc;
52 import javax.sql.XADataSource JavaDoc;
53 import java.sql.Connection JavaDoc;
54 import java.sql.Driver JavaDoc;
55 import java.sql.SQLException JavaDoc;
56 import java.util.HashMap JavaDoc;
57 import java.util.Iterator JavaDoc;
58 import java.util.Properties JavaDoc;
59 import java.util.logging.Level JavaDoc;
60 import java.util.logging.Logger JavaDoc;
61
62 /**
63  * Configures the database driver.
64  */

65 public class DriverConfig {
66   protected static final Logger JavaDoc log = Log.open(DriverConfig.class);
67   private static final L10N L = new L10N(DriverConfig.class);
68
69   private static final int TYPE_UNKNOWN = 0;
70   private static final int TYPE_DRIVER = 1;
71   private static final int TYPE_POOL = 2;
72   private static final int TYPE_XA = 3;
73   private static final int TYPE_JCA = 4;
74
75   /**
76    * The beginning of the URL used to connect to a database with
77    * this pooled connection driver.
78    */

79   private static final String JavaDoc URL_PREFIX = "jdbc:caucho:" ;
80
81   /**
82    * The key used to look into the properties passed to the
83    * connect method to find the username.
84    */

85   public static final String JavaDoc PROPERTY_USER = "user" ;
86   /**
87    * The key used to look into the properties passed to the
88    * connect method to find the password.
89    */

90   public static final String JavaDoc PROPERTY_PASSWORD = "password" ;
91
92   private DBPoolImpl _dbPool;
93
94   private Class JavaDoc _driverClass;
95
96   private String JavaDoc _driverURL;
97   private String JavaDoc _user;
98   private String JavaDoc _password;
99   private Properties JavaDoc _info;
100
101   private BuilderProgramContainer _init = new BuilderProgramContainer();
102
103   private int _driverType;
104   private Object JavaDoc _driverObject;
105
106   private ManagedConnectionFactory JavaDoc _jcaDataSource;
107   private ConnectionPoolDataSource JavaDoc _poolDataSource;
108   private XADataSource JavaDoc _xaDataSource;
109   private Driver _driver;
110
111   private ProfilerPoint _profilerPoint;
112
113   private boolean _isInit;
114   private boolean _isStarted;
115
116   /**
117    * Null constructor for the Driver interface; called by the JNDI
118    * configuration. Applications should not call this directly.
119    */

120   public DriverConfig(DBPoolImpl pool)
121   {
122     _dbPool = pool;
123
124     _info = new Properties JavaDoc();
125   }
126
127   /**
128    * Returns the DBPool.
129    */

130   public DBPoolImpl getDBPool()
131   {
132     return _dbPool;
133   }
134
135   /**
136    * Sets the driver as data source.
137    */

138   public void setDriverType(String JavaDoc type)
139     throws ConfigException
140   {
141     if ("ConnectionPoolDataSource".equals(type)) {
142       _driverType = TYPE_POOL;
143     }
144     else if ("XADataSource".equals(type)) {
145       _driverType = TYPE_XA;
146     }
147     else if ("ManagedConnectionFactory".equals(type)) {
148       _driverType = TYPE_JCA;
149     }
150     else if ("Driver".equals(type)) {
151       _driverType = TYPE_DRIVER;
152     }
153     else
154       throw new ConfigException(L.l("'{0}' is an unknown driver type. Valid types are 'ConnectionPoolDataSource', 'XADataSource' and 'Driver'"));
155   }
156
157   /**
158    * Sets the driver as data source.
159    */

160   public void setDataSource(Object JavaDoc dataSource)
161     throws ConfigException
162   {
163     if (dataSource instanceof String JavaDoc)
164       dataSource = Jndi.lookup((String JavaDoc) dataSource);
165
166     if (_driverType == TYPE_XA)
167       _xaDataSource = (XADataSource JavaDoc) dataSource;
168     else if (_driverType == TYPE_POOL)
169       _poolDataSource = (ConnectionPoolDataSource JavaDoc) dataSource;
170     else if (dataSource instanceof XADataSource JavaDoc)
171       _xaDataSource = (XADataSource JavaDoc) dataSource;
172     else if (dataSource instanceof ConnectionPoolDataSource JavaDoc)
173       _poolDataSource = (ConnectionPoolDataSource JavaDoc) dataSource;
174     else if (dataSource instanceof ManagedConnectionFactory JavaDoc)
175       _jcaDataSource = (ManagedConnectionFactory JavaDoc) dataSource;
176     else
177       throw new ConfigException(L.l("data-source `{0}' is of type `{1}' which does not implement XADataSource or ConnectionPoolDataSource.",
178                                     dataSource,
179                                     dataSource.getClass().getName()));
180   }
181
182   /**
183    * Returns the JDBC driver class for the pooled object.
184    */

185   public Class JavaDoc getDriverClass()
186   {
187     return _driverClass;
188   }
189
190   /**
191    * Sets the JDBC driver class underlying the pooled object.
192    */

193   public void setType(Class JavaDoc driverClass)
194     throws ConfigException
195   {
196     _driverClass = driverClass;
197
198     if (! Driver.class.isAssignableFrom(driverClass) &&
199         ! XADataSource JavaDoc.class.isAssignableFrom(driverClass) &&
200         ! ConnectionPoolDataSource JavaDoc.class.isAssignableFrom(driverClass) &&
201         ! ManagedConnectionFactory JavaDoc.class.isAssignableFrom(driverClass))
202       throw new ConfigException(L.l("`{0}' is not a valid database type.",
203                                     driverClass.getName()));
204
205     Config.checkCanInstantiate(driverClass);
206   }
207
208   /**
209    * Returns the connection's JDBC url.
210    */

211   public String JavaDoc getURL()
212   {
213     return _driverURL;
214   }
215
216   /**
217    * Sets the connection's JDBC url.
218    */

219   public void setURL(String JavaDoc url)
220   {
221     _driverURL = url;
222   }
223
224   /**
225    * Adds to the builder program.
226    */

227   public void addBuilderProgram(BuilderProgram program)
228   {
229     _init.addProgram(program);
230   }
231
232   /**
233    * Returns the connection's user.
234    */

235   public String JavaDoc getUser()
236   {
237     return _user;
238   }
239
240   /**
241    * Sets the connection's user.
242    */

243   public void setUser(String JavaDoc user)
244   {
245     _user = user;
246   }
247
248   /**
249    * Returns the connection's password
250    */

251   public String JavaDoc getPassword()
252   {
253     return _password;
254   }
255
256   /**
257    * Sets the connection's password
258    */

259   public void setPassword(String JavaDoc password)
260   {
261     _password = password;
262   }
263
264   /**
265    * Sets a property from the underlying driver. Used to set driver
266    * properties not handled by DBPool.
267    *
268    * @param name property name for the driver
269    * @param value the driver's value of the property name
270    */

271   public void setInitParam(InitParam initParam)
272   {
273     validateInitParam();
274     
275     HashMap JavaDoc<String JavaDoc,String JavaDoc> paramMap = initParam.getParameters();
276
277     Iterator JavaDoc<String JavaDoc> iter = paramMap.keySet().iterator();
278     while (iter.hasNext()) {
279       String JavaDoc key = iter.next();
280
281       _info.setProperty(key, paramMap.get(key));
282     }
283   }
284
285   /**
286    * Sets a property from the underlying driver. Used to set driver
287    * properties not handled by DBPool.
288    *
289    * @param name property name for the driver
290    * @param value the driver's value of the property name
291    */

292   public void setInitParam(String JavaDoc key, String JavaDoc value)
293   {
294     _info.setProperty(key, value);
295   }
296
297   /**
298    * Returns the properties.
299    */

300   public Properties JavaDoc getInfo()
301   {
302     return _info;
303   }
304
305   /**
306    * Returns the driver object.
307    */

308   public Driver getDriver()
309     throws SQLException JavaDoc
310   {
311     Object JavaDoc obj = getDriverObject();
312
313     if (obj instanceof Driver)
314       return (Driver) obj;
315     else
316       return null;
317   }
318
319   /**
320    * Sets the driver object.
321    */

322   public void setDriver(Driver driver)
323     throws SQLException JavaDoc
324   {
325     _driver = driver;
326     _driverObject = driver;
327   }
328
329   /**
330    * Returns the driver pool.
331    */

332   public ConnectionPoolDataSource JavaDoc getPoolDataSource()
333     throws SQLException JavaDoc
334   {
335     return _poolDataSource;
336   }
337
338   /**
339    * Sets the pooled data source driver.
340    */

341   public void setPoolDataSource(ConnectionPoolDataSource JavaDoc pDataSource)
342     throws SQLException JavaDoc
343   {
344     _poolDataSource = pDataSource;
345     _driverObject = _poolDataSource;
346   }
347
348   /**
349    * Returns any XADataSource.
350    */

351   public XADataSource JavaDoc getXADataSource()
352   {
353     return _xaDataSource;
354   }
355
356   /**
357    * Sets the xa data source driver.
358    */

359   public void setXADataSource(XADataSource JavaDoc xaDataSource)
360     throws SQLException JavaDoc
361   {
362     _xaDataSource = xaDataSource;
363     _driverObject = _xaDataSource;
364   }
365
366   /**
367    * Returns the managed connection factory.
368    */

369   public ManagedConnectionFactory JavaDoc getManagedConnectionFactory()
370   {
371     return _jcaDataSource;
372   }
373
374   /**
375    * Returns true if the driver is XA enabled.
376    */

377   public boolean isXATransaction()
378   {
379     return _xaDataSource != null && _dbPool.isXA();
380   }
381
382   /**
383    * Returns true if the driver is XA enabled.
384    */

385   public boolean isLocalTransaction()
386   {
387     return _dbPool.isXA();
388   }
389
390   /**
391    * Configure a ProfilerPointConfig, used to create a ProfilerPoint
392    * that is then passed to setProfiler().
393    * The returned ProfilerPointConfig has a default name set to the URL of
394    * this driver,
395    */

396   public ProfilerPointConfig createProfilerPoint()
397   {
398     ProfilerPointConfig profilerPointConfig = new ProfilerPointConfig();
399
400     profilerPointConfig.setName(getURL());
401     profilerPointConfig.setCategorizing(true);
402
403     return profilerPointConfig;
404   }
405
406   /**
407    * Enables profiling for this driver.
408    */

409   public void setProfilerPoint(ProfilerPoint profilerPoint)
410   {
411     _profilerPoint = profilerPoint;
412   }
413
414   /**
415    * Initialize the pool's data source
416    *
417    * <ul>
418    * <li>If data-source is set, look it up in JNDI.
419    * <li>Else if the driver is a pooled or xa data source, use it.
420    * <li>Else create wrappers.
421    * </ul>
422    */

423   synchronized void initDataSource(boolean isTransactional, boolean isSpy)
424     throws SQLException JavaDoc
425   {
426     if (_isStarted)
427       return;
428
429     _isStarted = true;
430
431     if (_xaDataSource == null && _poolDataSource == null) {
432       initDriver();
433
434       Object JavaDoc driverObject = getDriverObject();
435
436       if (driverObject == null) {
437         throw new SQLExceptionWrapper(L.l("driver `{0}' has not been configured for pool {1}. <database> needs a <driver type='...'>.",
438                                           _driverClass, getDBPool().getName()));
439       }
440
441       if (_driverType == TYPE_XA)
442         _xaDataSource = (XADataSource JavaDoc) _driverObject;
443       else if (_driverType == TYPE_POOL)
444         _poolDataSource = (ConnectionPoolDataSource JavaDoc) _driverObject;
445       else if (_driverType == TYPE_DRIVER)
446         _driver = (Driver) _driverObject;
447       else if (driverObject instanceof XADataSource JavaDoc)
448         _xaDataSource = (XADataSource JavaDoc) _driverObject;
449       else if (_driverObject instanceof ConnectionPoolDataSource JavaDoc)
450         _poolDataSource = (ConnectionPoolDataSource JavaDoc) _driverObject;
451       else if (_driverObject instanceof ManagedConnectionFactory JavaDoc)
452         _jcaDataSource = (ManagedConnectionFactory JavaDoc) _driverObject;
453       else if (_driverObject instanceof Driver)
454         _driver = (Driver) _driverObject;
455       else
456         throw new SQLExceptionWrapper(L.l("driver `{0}' has not been configured for pool {1}. <database> needs a <driver type='...'>.",
457                                           _driverClass, getDBPool().getName()));
458
459       /*
460       if (! isTransactional && _xaDataSource != null) {
461     throw new SQLExceptionWrapper(L.l("XADataSource `{0}' must be configured as transactional. Either configure it with <xa>true</xa> or use the database's ConnectionPoolDataSource driver or the old java.sql.Driver driver.",
462                       _xaDataSource));
463       }
464       */

465     }
466
467     if (_profilerPoint != null) {
468       if (log.isLoggable(Level.FINE))
469         log.fine(_profilerPoint.toString());
470
471       if (_xaDataSource != null)
472         _xaDataSource = new XADataSourceWrapper(_profilerPoint, _xaDataSource);
473       else if (_poolDataSource != null)
474         _poolDataSource = new ConnectionPoolDataSourceWrapper(_profilerPoint, _poolDataSource);
475       else if (_driver != null)
476         _driver = new DriverWrapper(_profilerPoint, _driver);
477     }
478
479     if (_info.size() != 0) {
480       validateInitParam();
481     }
482
483     J2EEManagedObject.register(new JDBCDriver(this));
484   }
485
486   private void validateInitParam()
487   {
488     if (_jcaDataSource != null) {
489       throw new ConfigException(L.l("<init-param> cannot be used with a JCA data source. Use the init-param key as a tag, like <key>value</key>"));
490     }
491     else if (_poolDataSource != null) {
492       throw new ConfigException(L.l("<init-param> cannot be used with a ConnectionPoolDataSource. Use the init-param key as a tag, like <key>value</key>"));
493     }
494     else if (_xaDataSource != null) {
495       throw new ConfigException(L.l("<init-param> cannot be used with an XADataSource. Use the init-param key as a tag, like <key>value</key>"));
496     }
497   }
498
499   /**
500    * Returns the driver object configured for the database.
501    */

502   synchronized Object JavaDoc getDriverObject()
503     throws SQLException JavaDoc
504   {
505     if (_driverObject != null)
506       return _driverObject;
507     else if (_driverClass == null)
508       return null;
509
510     if (log.isLoggable(Level.CONFIG))
511       log.config("loading driver: " + _driverClass.getName());
512
513     try {
514       _driverObject = _driverClass.newInstance();
515     } catch (Exception JavaDoc e) {
516       throw new SQLExceptionWrapper(e);
517     }
518
519     return _driverObject;
520   }
521
522   /**
523    * Creates a connection.
524    */

525   PooledConnection JavaDoc createPooledConnection(String JavaDoc user, String JavaDoc password)
526     throws SQLException JavaDoc
527   {
528     PooledConnection JavaDoc conn = null;
529     if (_xaDataSource != null) {
530       if (user == null && password == null)
531         conn = _xaDataSource.getXAConnection();
532       else
533         conn = _xaDataSource.getXAConnection(user, password);
534
535       /*
536       if (! _isTransactional) {
537     throw new SQLExceptionWrapper(L.l("XADataSource `{0}' must be configured as transactional. Either configure it with <xa>true</xa> or use the database's ConnectionPoolDataSource driver or the old java.sql.Driver driver.",
538                       _xaDataSource));
539       }
540       */

541     }
542     else if (_poolDataSource != null) {
543       /*
544       if (_isTransactional) {
545     throw new SQLExceptionWrapper(L.l("ConnectionPoolDataSource `{0}' can not be configured as transactional. Either use the database's XADataSource driver or the old java.sql.Driver driver.",
546                       _poolDataSource));
547       }
548       */

549
550       if (user == null && password == null)
551         conn = _poolDataSource.getPooledConnection();
552       else
553         conn = _poolDataSource.getPooledConnection(user, password);
554     }
555
556     return conn;
557   }
558
559   /**
560    * Creates a connection.
561    */

562   Connection JavaDoc createDriverConnection(String JavaDoc user, String JavaDoc password)
563     throws SQLException JavaDoc
564   {
565     if (_xaDataSource != null || _poolDataSource != null)
566       throw new IllegalStateException JavaDoc();
567
568     if (_driver == null)
569       throw new IllegalStateException JavaDoc();
570
571     Driver driver = _driver;
572     String JavaDoc url = getURL();
573
574     if (url == null)
575       throw new SQLException JavaDoc(L.l("can't create connection with null url"));
576
577     Properties JavaDoc properties = getInfo();
578
579     if (user != null)
580       properties.put("user", user);
581     else
582       properties.put("user", "");
583
584     if (password != null)
585       properties.put("password", password);
586     else
587       properties.put("password", "");
588
589     Connection JavaDoc conn;
590     if (driver != null)
591       conn = driver.connect(url, properties);
592     else
593       conn = java.sql.DriverManager.getConnection(url, properties);
594
595     return conn;
596   }
597
598   /**
599    * Initializes the JDBC driver.
600    */

601   public void initDriver()
602     throws SQLException JavaDoc
603   {
604     if (_isInit)
605       return;
606
607     _isInit = true;
608
609     Object JavaDoc driverObject = getDriverObject();
610
611     if (driverObject != null) {
612     }
613     else if (_xaDataSource != null || _poolDataSource != null)
614       return;
615     else {
616       throw new SQLExceptionWrapper(L.l("driver `{0}' has not been configured for pool {1}. <database> needs either a <data-source> or a <type>.",
617                                         _driverClass, getDBPool().getName()));
618     }
619
620     try {
621       // server/14g1
622
if (_driverURL != null) { // && ! (driverObject instanceof Driver)) {
623
StringAttributeProgram program;
624         program = new StringAttributeProgram("url", _driverURL);
625         program.configure(driverObject);
626       }
627     } catch (Throwable JavaDoc e) {
628       if (driverObject instanceof Driver)
629         log.log(Level.FINEST, e.toString(), e);
630       else
631         throw new SQLExceptionWrapper(e);
632     }
633
634     try {
635       if (_user != null) { // && ! (driverObject instanceof Driver)) {
636
StringAttributeProgram program;
637         program = new StringAttributeProgram("user", _user);
638         program.configure(driverObject);
639       }
640     } catch (Throwable JavaDoc e) {
641       log.log(Level.FINEST, e.toString(), e);
642
643       if (! (driverObject instanceof Driver))
644         throw new SQLExceptionWrapper(e);
645     }
646
647     try {
648       if (_password != null) { // && ! (driverObject instanceof Driver)) {
649
StringAttributeProgram program;
650         program = new StringAttributeProgram("password", _password);
651         program.configure(driverObject);
652       }
653     } catch (Throwable JavaDoc e) {
654       log.log(Level.FINEST, e.toString(), e);
655
656       if (! (driverObject instanceof Driver))
657         throw new SQLExceptionWrapper(e);
658     }
659
660     try {
661       if (_init != null) {
662         _init.configure(driverObject);
663         _init = null;
664       }
665
666       Config.init(driverObject);
667     } catch (Throwable JavaDoc e) {
668       log.log(Level.FINE, e.toString(), e);
669       throw new SQLExceptionWrapper(e);
670     }
671   }
672
673   /**
674    * Returns a string description of the pool.
675    */

676   public String JavaDoc toString()
677   {
678     return "Driver[" + _driverURL + "]";
679   }
680 }
681
Popular Tags