KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > craftsman > spy > SpyDriver


1 /*
2  * Craftsman Spy.
3  * Copyright (C) 2005 Sébastien LECACHEUR
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */

19 package craftsman.spy;
20
21 import java.sql.Connection JavaDoc;
22 import java.sql.Driver JavaDoc;
23 import java.sql.DriverManager JavaDoc;
24 import java.sql.DriverPropertyInfo JavaDoc;
25 import java.sql.SQLException JavaDoc;
26 import java.util.Properties JavaDoc;
27
28 /**
29  * This classe is the implementation of the JDBC driver in order to
30  * log any JDBC action.
31  *
32  * The system property <code>spy.driver</code> MUST contains the real
33  * JDBC driver full class name in order to use the Spy driver.
34  *
35  * Another way is to use a specific JDBC url string like :
36  * <code>jdbc:spy:<i>driver_full_class_name</i>:url</code>.
37  *
38  * The two solutions can be used as the following examples :
39  * <pre>
40  * System.setProperty("spy.driver","vendor.database.Driver");// or with the -Dspy.driver=vendor.database.Driver JVM option
41  * Class.forName("craftsman.spy.SpyDriver");
42  * Connection c = DriverManager.getConnection("jdbc:database:mydata");
43  * </pre>
44  *
45  * <pre>
46  * Class.forName("craftsman.spy.SpyDriver");
47  * Connection c = DriverManager.getConnection("jdbc:spy:vendor.database.Driver:database:mydata");
48  * </pre>
49  * @author Sébastien LECACHEUR
50  */

51 public class SpyDriver implements Driver JavaDoc {
52     /**
53      * The real JDBC driver instance.
54      */

55     private Driver JavaDoc real = null;
56
57
58     /**
59      * The property name of the real JDBC driver full class name.
60      */

61     private final static String JavaDoc DRIVER_CLASS_NAME_PROPERTY = "spy.driver";
62
63
64     /**
65      * The property name of the SQL query to get the JDBC connection ID.
66      *
67      * This query can be :
68      * <ul>
69      * <li><code>select @@spid</code> for Sybase</li>
70      * <li><code>select @@spid</code> for MS SQL-Server</li>
71      * <li><code>select @@session.identity</code> for MySQL</li>
72      * <li><code>select @@spidExec</code> for Oracle</li>
73      * </ul>
74      */

75     private final static String JavaDoc CONNECTION_ID_SQL_PROPERTY = "spy.connection.id";
76
77
78     /**
79      * The prefix of accepted JDBC url by the Spy JDBC driver when the real driver
80      * is no selected with the <code>spy.driver</code> system property.
81      */

82     private final static String JavaDoc URL_PREFIX = "jdbc:spy:";
83
84
85     static {
86         try {
87             new SpyDriver();
88         } catch ( Exception JavaDoc e) {
89             e.printStackTrace();
90         }
91     }
92
93
94     /**
95      * Constructs a new Spy JDBC driver.
96      * @throws ClassNotFoundException When the real JDBC driver class was not found.
97      * @throws InstantiationException When the real JDBC driver cannot be instancied.
98      * @throws IllegalAccessException When cannot create a new instance of the real
99      * JDBC driver.
100      * @throws SQLException When cannot register the Spy JDBC driver or deregistrer
101      * the real JDBC driver.
102      */

103     public SpyDriver () throws ClassNotFoundException JavaDoc, InstantiationException JavaDoc, IllegalAccessException JavaDoc, SQLException JavaDoc {
104         init();
105     }
106
107
108     /**
109      * Initializes the Spy JDBC driver.
110      * @throws ClassNotFoundException When the real JDBC driver class was not found.
111      * @throws InstantiationException When the real JDBC driver cannot be instancied.
112      * @throws IllegalAccessException When cannot create a new instance of the real
113      * JDBC driver.
114      * @throws SQLException When cannot register the Spy JDBC driver or deregistrer
115      * the real JDBC driver.
116      */

117     private void init() throws ClassNotFoundException JavaDoc, InstantiationException JavaDoc, IllegalAccessException JavaDoc, SQLException JavaDoc {
118         DriverManager.registerDriver(this);
119         registerRealDriver(System.getProperty(DRIVER_CLASS_NAME_PROPERTY));
120     }
121
122
123     /**
124      * Register the real JDBC driver in the Spy JDBC driver. Create a new instance
125      * of the real JDBC driver, store it and deregister this one from the driver
126      * manager.
127      * @param className String The full name of the real JDBC driver.
128      * @throws ClassNotFoundException When the real JDBC driver class was not found.
129      * @throws InstantiationException When the real JDBC driver cannot be instancied.
130      * @throws IllegalAccessException When cannot create a new instance of the real
131      * JDBC driver.
132      * @throws SQLException When cannot deregistrer
133      * the real JDBC driver.
134      */

135     private void registerRealDriver ( String JavaDoc className) throws InstantiationException JavaDoc, IllegalAccessException JavaDoc, ClassNotFoundException JavaDoc, SQLException JavaDoc {
136         if ( className!=null) {
137             real = (Driver JavaDoc)Class.forName(className).newInstance();
138             DriverManager.deregisterDriver(real);
139         }
140     }
141
142
143     /**
144      * Extracts from a JDBC url the real driver full class name.
145      * @param url String The JDBC url from which extract the
146      * driver full class name.
147      * @return String The full class name otherwise <code>null</code>.
148      */

149     private String JavaDoc getRealDriverClassName(String JavaDoc url) {
150         String JavaDoc result = null;
151         int index = url.indexOf(':',URL_PREFIX.length()+1);
152
153         if ( index!=-1) {
154             result = url.substring(URL_PREFIX.length(),index);
155         }
156
157         return result;
158     }
159
160
161     /**
162      * Returns the real JDBC url from the given url. Extracts the
163      * real url from a "spy url".
164      * @param url The JDBC url from which get the real url.
165      * @return String The real url otherwise the same.
166      */

167     private String JavaDoc getRealUrl(String JavaDoc url) {
168         return url!=null?url.startsWith(URL_PREFIX)?("jdbc"+url.substring(url.indexOf(':',URL_PREFIX.length()+1))):url:url;
169     }
170
171
172     /**
173      * Retrieves the real driver's major version number. Initially
174      * this should be <code>1</code>.
175      * @return int This driver's major version number.
176      * @see Driver#getMajorVersion()
177      */

178     public int getMajorVersion() {
179         return real!=null?real.getMajorVersion():1;
180     }
181
182
183     /**
184      * Gets the real driver's minor version number. Initially this
185      * should be <code>0</code>.
186      * @return int This driver's minor version number.
187      * @see Driver#getMinorVersion()
188      */

189     public int getMinorVersion() {
190         return real!=null?real.getMinorVersion():0;
191     }
192
193
194     /**
195      * Reports whether thz real driver is a genuine JDBC Compliant driver.
196      * @return boolean <code>true</code> if this driver is JDBC Compliant;
197      * <code>false</code> otherwise.
198      * @see Driver#jdbcCompliant()
199      */

200     public boolean jdbcCompliant() {
201         return real.jdbcCompliant();
202     }
203
204
205     /**
206      * Retrieves whether the real driver thinks that it can open a
207      * connection to the given URL.
208      * @param url String The URL of the database
209      * @return boolean <code>true</code> if this driver understands
210      * the given URL; <code>false</code> otherwise.
211      * @throws SQLException If a database access error occurs.
212      * @see Driver#acceptsURL(java.lang.String)
213      */

214     public boolean acceptsURL(String JavaDoc url) throws SQLException JavaDoc {
215         boolean result = false;
216
217
218         if ( real==null && url.startsWith(URL_PREFIX)) {
219             try {
220                 registerRealDriver(getRealDriverClassName(url));
221             } catch ( IllegalAccessException JavaDoc e) {
222                 e.printStackTrace();
223             } catch ( InstantiationException JavaDoc e) {
224                 e.printStackTrace();
225             } catch ( ClassNotFoundException JavaDoc e) {
226                 e.printStackTrace();
227             }
228         }
229
230         if ( real!=null) {
231             result = real.acceptsURL(getRealUrl(url));
232         }
233
234         return result;
235     }
236
237
238     /**
239      * Attempts to make a database connection to the given URL.
240      * @param url String The URL of the database to which to connect.
241      * @param info Properties A list of arbitrary string tag/value
242      * pairs as connection arguments.
243      * @return Connection A Connection object that represents a
244      * connection to the URL.
245      * @throws SQLException If a database access error occurs.
246      * @see Driver#connect(java.lang.String, java.util.Properties)
247      */

248     public Connection JavaDoc connect(String JavaDoc url, Properties JavaDoc info) throws SQLException JavaDoc {
249         Connection JavaDoc con = null;
250
251
252         if ( real==null && url.startsWith(URL_PREFIX)) {
253             try {
254                 registerRealDriver(getRealDriverClassName(url));
255             } catch ( IllegalAccessException JavaDoc e) {
256                 e.printStackTrace();
257             } catch ( InstantiationException JavaDoc e) {
258                 e.printStackTrace();
259             } catch ( ClassNotFoundException JavaDoc e) {
260                 e.printStackTrace();
261             }
262         }
263
264         if ( real!=null) {
265             con = new SpyConnection ( real.connect(getRealUrl(url),info),System.getProperty(CONNECTION_ID_SQL_PROPERTY));
266         }
267
268         return con;
269     }
270
271
272     /**
273      * Gets information about the possible properties for the real driver.
274      * @param url String The URL of the database to which to connect.
275      * @param info Properties A proposed list of tag/value pairs that will
276      * be sent on connect open.
277      * @return DriverPropertyInfo[] An array of DriverPropertyInfo objects
278      * describing possible properties.
279      * @throws SQLException If a database access error occurs.
280      * @see Driver#getPropertyInfo(java.lang.String, java.util.Properties)
281      */

282     public DriverPropertyInfo JavaDoc[] getPropertyInfo(String JavaDoc url, Properties JavaDoc info) throws SQLException JavaDoc {
283         return real!=null?real.getPropertyInfo(url,info):null;
284     }
285 }
286
Popular Tags