KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > rmijdbc > Driver


1
2 /**
3  * RmiJdbc client/server JDBC Driver
4  * (C) GIE Dyade (Groupe BULL / INRIA Research Center) 1997
5  *
6  * @version 1.0
7  * @author Pierre-Yves Gibello (pierreyves.gibello@experlog.com)
8  */

9
10 package org.objectweb.rmijdbc;
11
12 import java.sql.*;
13 import java.rmi.RemoteException JavaDoc;
14 import java.rmi.registry.*;
15 import java.rmi.NotBoundException JavaDoc;
16 import java.net.InetAddress JavaDoc;
17 import java.util.*;
18
19 /**
20  * <P>The Java SQL framework allows for multiple database drivers.
21  *
22  * <P>Each driver should supply a class that implements
23  * the Driver interface.
24  *
25  * <P>The DriverManager will try to load as many drivers as it can
26  * find and then for any given connection request, it will ask each
27  * driver in turn to try to connect to the target URL.
28  *
29  * <P>It is strongly recommended that each Driver class should be
30  * small and standalone so that the Driver class can be loaded and
31  * queried without bringing in vast quantities of supporting code.
32  *
33  * <P>When a Driver class is loaded, it should create an instance of
34  * itself and register it with the DriverManager. This means that a
35  * user can load and register a driver by doing
36  * Class.forName("foo.bah.Driver").
37  *
38  * @see DriverManager
39  * @see Connection
40  */

41 public class Driver implements java.sql.Driver JavaDoc, java.io.Serializable JavaDoc {
42
43   static {
44     try {
45       // register the driver with the JDBC DriverManager
46
DriverManager.registerDriver(new org.objectweb.rmijdbc.Driver());
47     } catch (Exception JavaDoc e) {
48       e.printStackTrace();
49     }
50   }
51
52   public Driver() throws Exception JavaDoc {}
53
54   private static int RMI_REGISTRY = 0;
55   private static int RMI_ADDRESS = 1;
56   private static int JDBC_URL = 2;
57
58   private String JavaDoc[] splitURL(String JavaDoc url) {
59
60     /* The url has the format:
61        "jdbc:rmi://<serverHostName[:port]>/<serverJdbcDriverName>"
62        First, get a reference to the RJDriverServer
63        running on computer <serverHostName>.
64        Then, connect using the server's registered jdbc driver */

65
66     String JavaDoc serverHostName, jdbcUrl;
67     if(url.substring(9,11).equals("//")) {
68       try {
69         serverHostName = url.substring(9, url.indexOf("/",11));
70       } catch(Exception JavaDoc e) { serverHostName = url.substring(9); }
71       try {
72         jdbcUrl = url.substring(url.indexOf("/",11)+1);
73       } catch(Exception JavaDoc e) { jdbcUrl = null; }
74     } else {
75       try {
76         serverHostName = "//" + InetAddress.getLocalHost().getHostName();
77       } catch(Exception JavaDoc e) {
78         System.err.println(
79          "WARNING: can\'t retrieve local host name, //localhost will be used !"
80          + " Exception follows:");
81         e.printStackTrace();
82         serverHostName = "//localhost";
83       }
84
85       jdbcUrl = url.substring(9);
86
87       // Check if there was something wierd in the RMI URL part:
88
// If so, skip it!
89
if(! jdbcUrl.toLowerCase().startsWith("jdbc")) {
90         System.err.println(
91           "WARNING: Wierd RMI server URL: localhost will be used.");
92         jdbcUrl = url.substring(url.indexOf("/", 9) + 1);
93       }
94     }
95     String JavaDoc rmiAddr = serverHostName + "/RmiJdbcServer";
96
97     String JavaDoc split[] = new String JavaDoc[3];
98     split[RMI_REGISTRY] = serverHostName.substring(2);
99     split[RMI_ADDRESS] = rmiAddr;
100     split[JDBC_URL] = jdbcUrl;
101     return split;
102   }
103
104   private RJDriverInterface lookupDriver(String JavaDoc url) throws Exception JavaDoc {
105     String JavaDoc split[] = splitURL(url);
106
107     // Reg is of the form: host[:port]
108
StringTokenizer st = new StringTokenizer(split[RMI_REGISTRY], ":");
109     if(!st.hasMoreTokens()) {
110       throw new SQLException("No RMI server host specified in JDBC URL");
111     }
112     String JavaDoc host = st.nextToken();
113     int port = 1099;
114     if(st.hasMoreTokens()) {
115       try {
116         port = Integer.parseInt(st.nextToken());
117       } catch(NumberFormatException JavaDoc e) {
118         port = 1099;
119       }
120     }
121
122     Registry registry = LocateRegistry.getRegistry(host, port);
123
124     // rmiAddr is an RMI object name (ex. //host/objName)
125
// Note that:
126
// An internal registry registers //host/objName as "//host/objName"
127
// An external registry registers //host/objName as "objName"
128
RJDriverInterface theDriver;
129     try {
130       theDriver = (RJDriverInterface)registry.lookup(split[RMI_ADDRESS]);
131     } catch(NotBoundException JavaDoc e) {
132       String JavaDoc obj;
133       int pos = split[RMI_ADDRESS].lastIndexOf("/");
134       if(pos < 0) obj = split[RMI_ADDRESS];
135       else obj = split[RMI_ADDRESS].substring(pos+1);
136       theDriver = (RJDriverInterface)registry.lookup(obj);
137     }
138
139     return theDriver;
140   }
141
142
143   /**
144    * Administrative methods
145    */

146   public void shutdown(String JavaDoc url, String JavaDoc pwd) throws RemoteException JavaDoc {
147
148     try {
149
150       RJDriverInterface drv = lookupDriver(url);
151       if(drv != null) {
152         try {
153           drv.shutdown(pwd);
154         } catch(java.rmi.UnmarshalException JavaDoc e) {
155           // ignore
156
}
157       }
158
159     } catch(RemoteException JavaDoc e) {
160       throw e;
161     } catch(Exception JavaDoc e) {
162       throw new RemoteException JavaDoc(e.getMessage());
163     }
164   }
165
166     /**
167      * Try to make a database connection to the given URL.
168      * The driver should return "null" if it realizes it is the wrong kind
169      * of driver to connect to the given URL. This will be common, as when
170      * the JDBC driver manager is asked to connect to a given URL it passes
171      * the URL to each loaded driver in turn.
172      *
173      * <P>The driver should raise a SQLException if it is the right
174      * driver to connect to the given URL, but has trouble connecting to
175      * the database.
176      *
177      * <P>The java.util.Properties argument can be used to passed arbitrary
178      * string tag/value pairs as connection arguments.
179      * Normally at least "user" and "password" properties should be
180      * included in the Properties.
181      *
182      * @param url The URL of the database to connect to
183      *
184      * @param info a list of arbitrary string tag/value pairs as
185      * connection arguments; normally at least a "user" and
186      * "password" property should be included
187      *
188      * @return a Connection to the URL
189      */

190   public java.sql.Connection JavaDoc connect(String JavaDoc url,Properties info)
191   throws SQLException {
192
193     if (!acceptsURL(url))
194       return null; //Will cause a "No suitable driver" upon DriverManager call
195

196     String JavaDoc split[] = splitURL(url);
197     try {
198       // url and info are JDBC data
199
return new RJConnection(lookupDriver(url), split[JDBC_URL], info);
200
201     } catch(SQLException e) {
202       e.printStackTrace();
203       throw e;
204     } catch(Exception JavaDoc e) {
205       e.printStackTrace();
206       throw new SQLException(e.getMessage());
207     }
208   }
209
210   /**
211    * Returns true if the driver thinks that it can open a connection
212    * to the given URL. Typically drivers will return true if they
213    * understand the subprotocol specified in the URL and false if
214    * they don't.
215    *
216    * @param url The URL of the database.
217    * @return True if this driver can connect to the given URL.
218    */

219   public boolean acceptsURL(String JavaDoc url) throws SQLException {
220     return url.startsWith("jdbc:rmi:");
221   }
222
223   /**
224    * <p>The getPropertyInfo method is intended to allow a generic GUI tool to
225    * discover what properties it should prompt a human for in order to get
226    * enough information to connect to a database. Note that depending on
227    * the values the human has supplied so far, additional values may become
228    * necessary, so it may be necessary to iterate though several calls
229    * to getPropertyInfo.
230    *
231    * @param url The URL of the database to connect to.
232    * @param info A proposed list of tag/value pairs that will be sent on
233    * connect open.
234    * @return An array of DriverPropertyInfo objects describing possible
235    * properties. This array may be an empty array if no properties
236    * are required.
237    */

238   public java.sql.DriverPropertyInfo JavaDoc[] getPropertyInfo(String JavaDoc url,
239   java.util.Properties JavaDoc info) throws SQLException {
240     try {
241
242       RJDriverInterface drv = lookupDriver(url);
243       String JavaDoc split[] = splitURL(url);
244
245       // DriverPropertyInfo is not serializable:
246
// the reason for RJDriverPropertyInfo !
247
RJDriverPropertyInfo infos[] = drv.getPropertyInfo(split[JDBC_URL], info);
248       if(infos == null) return null;
249       DriverPropertyInfo dpis[] = new DriverPropertyInfo[infos.length];
250       for(int i=0; i<infos.length; i++) {
251         if(infos[i] == null) dpis[i] = null;
252         dpis[i] = infos[i].getPropertyInfo();
253       }
254       return dpis;
255
256     } catch(RemoteException JavaDoc e) {
257       throw new SQLException("[RemoteException] " + e.getMessage());
258     } catch(java.rmi.NotBoundException JavaDoc e) {
259       throw new SQLException("[java.rmi.NotBoundException] " + e.getMessage());
260     } catch(Exception JavaDoc e) {
261       throw new SQLException(e.getMessage());
262     }
263   }
264
265
266   /**
267    * Get the driver's major version number. Initially this should be 1.
268    */

269   public int getMajorVersion() {
270     return 1;
271   }
272
273   /**
274    * Get the driver's minor version number. Initially this should be 0.
275    */

276   public int getMinorVersion() {
277     return 0;
278   }
279
280
281   /**
282    * Report whether the Driver is a genuine JDBC COMPLIANT (tm) driver.
283    * A driver may only report "true" here if it passes the JDBC compliance
284    * tests, otherwise it is required to return false.
285    *
286    * JDBC compliance requires full support for the JDBC API and full support
287    * for SQL 92 Entry Level. It is expected that JDBC compliant drivers will
288    * be available for all the major commercial databases.
289    *
290    * This method is not intended to encourage the development of non-JDBC
291    * compliant drivers, but is a recognition of the fact that some vendors
292    * are interested in using the JDBC API and framework for lightweight
293    * databases that do not support full database functionality, or for
294    * special databases such as document information retrieval where a SQL
295    * implementation may not be feasible.
296    */

297   public boolean jdbcCompliant() {
298     return true;
299   }
300
301 };
302
303
Popular Tags