KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > controller > connection > DriverManager


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2002-2005 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: c-jdbc@objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or any later
10  * version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20  *
21  * Initial developer(s): Marc Wick.
22  * Contributor(s): ______________________.
23  */

24
25 package org.objectweb.cjdbc.controller.connection;
26
27 import java.io.File JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.net.URL JavaDoc;
30 import java.sql.Connection JavaDoc;
31 import java.sql.Driver JavaDoc;
32 import java.sql.SQLException JavaDoc;
33 import java.util.HashMap JavaDoc;
34 import java.util.HashSet JavaDoc;
35 import java.util.Map JavaDoc;
36 import java.util.Set JavaDoc;
37
38 import org.objectweb.cjdbc.common.i18n.Translate;
39 import org.objectweb.cjdbc.common.log.Trace;
40 import org.objectweb.cjdbc.controller.core.Controller;
41 import org.objectweb.cjdbc.controller.core.ControllerConstants;
42
43 /**
44  * This class defines a DriverManager. In contrast to java.sql.DriverManager
45  * this class allows to use Drivers with the same name but with different
46  * versions, if no drivername is used it is a wrapper around
47  * java.sql.DriverManager.
48  *
49  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
50  * @version 1.0
51  */

52 public class DriverManager
53 {
54
55   /** Logger instance. */
56   static Trace logger = Trace
57                                         .getLogger("org.objectweb.cjdbc.controller.connection.DriverManager");
58
59   /**
60    * Driver class names read from default drivers, without driverPath
61    */

62   private static Set JavaDoc defaultDrivers = new HashSet JavaDoc();
63
64   /**
65    * We keep a reference to already loaded named drivers. Each named driver has
66    * been loaded with a separate classloader.
67    */

68   private static Map JavaDoc namedDrivers = new HashMap JavaDoc();
69
70   /**
71    * Attempts to establish a connection to the given database URL. The
72    * <code>DriverManager</code> attempts to select an appropriate driver from
73    * the set of registered JDBC drivers.
74    *
75    * @param url a database url of the form
76    * <code>jdbc:<em>subprotocol</em>:<em>subname</em></code>
77    * @param user the database user on whose behalf the connection is being made
78    * @param password the user's password
79    * @param driverPathName the path where the driver classes are located, null
80    * if default directory
81    * @param driverClassName the class name of the driver
82    * @return a connection to the URL
83    * @exception SQLException if a database access error occurs
84    */

85   public static Connection JavaDoc getConnection(String JavaDoc url, String JavaDoc user,
86       String JavaDoc password, String JavaDoc driverPathName, String JavaDoc driverClassName)
87       throws SQLException JavaDoc
88   {
89     Driver JavaDoc driver = null;
90     boolean isDefaultPath = false;
91
92     if (driverPathName == null)
93     {
94       // no path specified
95
// have we already loaded this driver
96
driver = (Driver JavaDoc) namedDrivers.get(driverClassName);
97       if (driver == null)
98       {
99         // the driver has not yet been loaded
100
// first we try to load class from classpath
101
try
102         {
103           if (driverClassName != null)
104           {
105             loadDriverClass(driverClassName);
106           }
107           return java.sql.DriverManager.getConnection(url, user, password);
108         }
109         catch (ClassNotFoundException JavaDoc e)
110         {
111           if (driverClassName == null)
112           {
113             throw new SQLException JavaDoc(
114                 "could not load driver as no class name is specified ");
115           }
116           try
117           {
118             driverPathName = getDriversDir().getAbsolutePath();
119             isDefaultPath = true;
120           }
121           catch (IOException JavaDoc ioExc)
122           {
123             throw new SQLException JavaDoc("could not find default drivers directory");
124           }
125         }
126       }
127     }
128
129     if (driver == null)
130     {
131       // have we already loaded this named driver ?
132
driver = (Driver JavaDoc) namedDrivers.get(driverPathName);
133     }
134
135     if (driver == null)
136     {
137       // no driver with this name has been loaded so far
138
try
139       {
140         File JavaDoc path = convertToAbsolutePath(driverPathName);
141         // we load the driver now
142
if (logger.isDebugEnabled())
143         {
144           logger.debug("loading driver with name " + driverPathName
145               + " for class " + driverClassName);
146         }
147         driver = loadDriver(path, driverClassName);
148       }
149       catch (Exception JavaDoc e)
150       {
151         logger.error("Could not load driver for class " + driverClassName, e);
152         throw new SQLException JavaDoc("could not load driver for class name "
153             + driverClassName + " and driverPath " + driverPathName);
154       }
155
156       // driver has been loaded successfully, we cache it for
157
// further use
158
if (isDefaultPath)
159       {// we cache it with the class name
160
namedDrivers.put(driverClassName, driver);
161       }
162       else
163       {
164         // we cache it with the pathName
165
namedDrivers.put(driverPathName, driver);
166       }
167     }
168
169     return getConnectionForDriver(url, user, password, driver);
170   }
171
172   /**
173    * Load the driver class
174    *
175    * @param driverClassName the class name of the driver
176    * @throws ClassNotFoundException if the class could not be found
177    */

178   public static void loadDriverClass(String JavaDoc driverClassName)
179       throws ClassNotFoundException JavaDoc
180   {
181     if (!defaultDrivers.contains(driverClassName))
182     {
183       if (logger.isDebugEnabled())
184       {
185         logger.debug("we are using default classloader and driverClassName ="
186             + driverClassName);
187       }
188       Class.forName(driverClassName);
189       if (logger.isDebugEnabled())
190         logger.debug(Translate.get("backend.driver.loaded", driverClassName));
191       // the driver was successfully loaded
192
defaultDrivers.add(driverClassName);
193     }
194   }
195
196   /**
197    * convert a path into an absolute path if the path is already an absolute
198    * path, it is just returned otherwise a relative path is considered to be
199    * relative to the drivers directory
200    *
201    * @param pathName the relativ or absolute path
202    * @return the converted path
203    * @throws IOException if the converted path does not exist
204    */

205   public static File JavaDoc convertToAbsolutePath(String JavaDoc pathName) throws IOException JavaDoc
206   {
207     File JavaDoc dir = null;
208
209     if (pathName != null)
210     {
211       File JavaDoc path = new File JavaDoc(pathName);
212       if (path.canRead())
213         return path;
214       else
215         throw new IOException JavaDoc("Invalid path name " + pathName);
216     }
217     else
218     {
219       dir = getDriversDir();
220     }
221
222     if (!dir.canRead())
223     {
224       String JavaDoc msg = Translate.get("controller.driver.dir.not.found");
225       logger.error(msg);
226       throw new IOException JavaDoc(msg);
227     }
228
229     return dir;
230   }
231
232   private static File JavaDoc getDriversDir() throws IOException JavaDoc
233   {
234     URL JavaDoc url = Controller.class
235         .getResource(ControllerConstants.C_JDBC_DRIVER_JAR_FILE);
236     if (url == null)
237     {
238       String JavaDoc msg = Translate.get("controller.driver.dir.not.found");
239       logger.error(msg);
240       throw new IOException JavaDoc(msg);
241     }
242
243     File JavaDoc driversDir = new File JavaDoc(url.getFile()).getParentFile();
244
245     if (!driversDir.exists())
246     {
247       String JavaDoc msg = Translate.get("controller.driver.dir.not.found");
248       logger.error(msg);
249       throw new IOException JavaDoc(msg);
250     }
251     return driversDir;
252   }
253
254   private static Connection JavaDoc getConnectionForDriver(String JavaDoc url, String JavaDoc user,
255       String JavaDoc password, Driver JavaDoc driver) throws SQLException JavaDoc
256   {
257     java.util.Properties JavaDoc info = new java.util.Properties JavaDoc();
258     if (user != null)
259     {
260       info.put("user", user);
261     }
262     if (password != null)
263     {
264       info.put("password", password);
265     }
266
267     return driver.connect(url, info);
268   }
269
270   private static Driver JavaDoc loadDriver(File JavaDoc path, String JavaDoc driverClassName)
271       throws ClassNotFoundException JavaDoc, InstantiationException JavaDoc,
272       IllegalAccessException JavaDoc
273   {
274     ClassLoader JavaDoc loader = new DriverClassLoader(null, path);
275
276     // load java.sql.DriverManager with the new classloader
277
// Driver instances register with the DriverManager and we want the new
278
// Driver to register with its own DriverManager
279
// Otherwise the new Driver would register with the default DriverManager
280
// and possibly overwrite an other driver with the same name
281
Class.forName(java.sql.DriverManager JavaDoc.class.getName(), true, loader);
282
283     // load class
284
Class JavaDoc driverClass = Class.forName(driverClassName, true, loader);
285
286     if (logger.isDebugEnabled())
287       logger.debug(Translate.get("backend.driver.loaded", driverClassName));
288
289     // get an instance of the class and return it
290
return (Driver JavaDoc) driverClass.newInstance();
291
292   }
293
294 }
295
Popular Tags