KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > continuent > sequoia > controller > connection > DriverManager


1 /**
2  * Sequoia: Database clustering technology.
3  * Copyright (C) 2002-2004 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Copyright (C) 2005 AmicoSoft, Inc. dba Emic Networks
6  * Contact: sequoia@continuent.org
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  * Initial developer(s): Marc Wick.
21  * Contributor(s): ______________________.
22  */

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

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

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

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

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

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

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