KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > JDBCTask


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18
19 package org.apache.tools.ant.taskdefs;
20
21 import java.sql.Connection JavaDoc;
22 import java.sql.DatabaseMetaData JavaDoc;
23 import java.sql.Driver JavaDoc;
24 import java.sql.SQLException JavaDoc;
25 import java.util.Hashtable JavaDoc;
26 import java.util.Properties JavaDoc;
27 import java.util.Locale JavaDoc;
28
29 import org.apache.tools.ant.AntClassLoader;
30 import org.apache.tools.ant.BuildException;
31 import org.apache.tools.ant.Project;
32 import org.apache.tools.ant.Task;
33 import org.apache.tools.ant.types.Path;
34 import org.apache.tools.ant.types.Reference;
35
36 /**
37  * Handles JDBC configuration needed by SQL type tasks.
38  * <p>
39  * The following example class prints the contents of the first column of each row in TableName.
40  *</p>
41  *<code><pre>
42 package examples;
43 import java.sql.Connection;
44 import java.sql.ResultSet;
45 import java.sql.SQLException;
46 import java.sql.Statement;
47
48 import org.apache.tools.ant.BuildException;
49 import org.apache.tools.ant.taskdefs.JDBCTask;
50
51 public class SQLExampleTask extends JDBCTask {
52
53     private String tableName;
54
55     public void execute() throws BuildException {
56         Connection conn = getConnection();
57         Statement stmt=null;
58         try {
59             if (tableName == null) {
60                 throw new BuildException("TableName must be specified",location);
61             }
62             String sql = "SELECT * FROM "+tableName;
63             stmt= conn.createStatement();
64             ResultSet rs = stmt.executeQuery(sql);
65             while (rs.next()) {
66                 log(rs.getObject(1).toString());
67             }
68         } catch (SQLException e) {
69
70         } finally {
71             if (stmt != null) {
72                 try {stmt.close();}catch (SQLException ingore) {}
73             }
74             if (conn != null) {
75                 try {conn.close();}catch (SQLException ingore) {}
76             }
77         }
78     }
79     public void setTableName(String tableName) {
80         this.tableName = tableName;
81     }
82
83 }
84
85
86 </pre></code>
87
88
89
90  * @since Ant 1.5
91  *
92  */

93
94 public abstract class JDBCTask extends Task {
95
96
97     /**
98      * Used for caching loaders / driver. This is to avoid
99      * getting an OutOfMemoryError when calling this task
100      * multiple times in a row.
101      */

102     private static Hashtable JavaDoc loaderMap = new Hashtable JavaDoc(3);
103
104     private boolean caching = true;
105
106     private Path classpath;
107
108     private AntClassLoader loader;
109
110     /**
111      * Autocommit flag. Default value is false
112      */

113     private boolean autocommit = false;
114
115     /**
116      * DB driver.
117      */

118     private String JavaDoc driver = null;
119
120     /**
121      * DB url.
122      */

123     private String JavaDoc url = null;
124
125     /**
126      * User name.
127      */

128     private String JavaDoc userId = null;
129
130     /**
131      * Password
132      */

133     private String JavaDoc password = null;
134
135     /**
136      * RDBMS Product needed for this SQL.
137      **/

138     private String JavaDoc rdbms = null;
139
140     /**
141      * RDBMS Version needed for this SQL.
142      **/

143     private String JavaDoc version = null;
144
145     /**
146      * Sets the classpath for loading the driver.
147      * @param classpath The classpath to set
148      */

149     public void setClasspath(Path classpath) {
150         this.classpath = classpath;
151     }
152
153     /**
154      * Caching loaders / driver. This is to avoid
155      * getting an OutOfMemoryError when calling this task
156      * multiple times in a row; default: true
157      * @param enable a <code>boolean</code> value
158      */

159     public void setCaching(boolean enable) {
160         caching = enable;
161     }
162
163     /**
164      * Add a path to the classpath for loading the driver.
165      * @return a path to be configured
166      */

167     public Path createClasspath() {
168         if (this.classpath == null) {
169             this.classpath = new Path(getProject());
170         }
171         return this.classpath.createPath();
172     }
173
174     /**
175      * Set the classpath for loading the driver
176      * using the classpath reference.
177      * @param r a reference to a classpath
178      */

179     public void setClasspathRef(Reference r) {
180         createClasspath().setRefid(r);
181     }
182
183     /**
184      * Class name of the JDBC driver; required.
185      * @param driver The driver to set
186      */

187     public void setDriver(String JavaDoc driver) {
188         this.driver = driver.trim();
189     }
190
191     /**
192      * Sets the database connection URL; required.
193      * @param url The url to set
194      */

195     public void setUrl(String JavaDoc url) {
196         this.url = url;
197     }
198
199     /**
200      * Sets the password; required.
201      * @param password The password to set
202      */

203     public void setPassword(String JavaDoc password) {
204         this.password = password;
205     }
206
207     /**
208      * Auto commit flag for database connection;
209      * optional, default false.
210      * @param autocommit The autocommit to set
211      */

212     public void setAutocommit(boolean autocommit) {
213         this.autocommit = autocommit;
214     }
215
216     /**
217      * Execute task only if the lower case product name
218      * of the DB matches this
219      * @param rdbms The rdbms to set
220      */

221     public void setRdbms(String JavaDoc rdbms) {
222         this.rdbms = rdbms;
223     }
224
225     /**
226      * Sets the version string, execute task only if
227      * rdbms version match; optional.
228      * @param version The version to set
229      */

230     public void setVersion(String JavaDoc version) {
231         this.version = version;
232     }
233
234     /**
235      * Verify we are connected to the correct RDBMS
236      * @param conn the jdbc connection
237      * @return true if we are connected to the correct RDBMS
238      */

239     protected boolean isValidRdbms(Connection JavaDoc conn) {
240         if (rdbms == null && version == null) {
241             return true;
242         }
243
244         try {
245             DatabaseMetaData JavaDoc dmd = conn.getMetaData();
246
247             if (rdbms != null) {
248                 String JavaDoc theVendor = dmd.getDatabaseProductName().toLowerCase();
249
250                 log("RDBMS = " + theVendor, Project.MSG_VERBOSE);
251                 if (theVendor == null || theVendor.indexOf(rdbms) < 0) {
252                     log("Not the required RDBMS: " + rdbms, Project.MSG_VERBOSE);
253                     return false;
254                 }
255             }
256
257             if (version != null) {
258                 String JavaDoc theVersion = dmd.getDatabaseProductVersion().toLowerCase(Locale.ENGLISH);
259
260                 log("Version = " + theVersion, Project.MSG_VERBOSE);
261                 if (theVersion == null
262                         || !(theVersion.startsWith(version)
263                         || theVersion.indexOf(" " + version) >= 0)) {
264                     log("Not the required version: \"" + version + "\"", Project.MSG_VERBOSE);
265                     return false;
266                 }
267             }
268         } catch (SQLException JavaDoc e) {
269             // Could not get the required information
270
log("Failed to obtain required RDBMS information", Project.MSG_ERR);
271             return false;
272         }
273
274         return true;
275     }
276
277     /**
278      * Get the cache of loaders and drivers.
279      * @return a hashtable
280      */

281     protected static Hashtable JavaDoc getLoaderMap() {
282         return loaderMap;
283     }
284
285     /**
286      * Get the classloader used to create a driver.
287      * @return the classloader
288      */

289     protected AntClassLoader getLoader() {
290         return loader;
291     }
292
293     /**
294      * Creates a new Connection as using the driver, url, userid and password
295      * specified.
296      *
297      * The calling method is responsible for closing the connection.
298      *
299      * @return Connection the newly created connection.
300      * @throws BuildException if the UserId/Password/Url is not set or there
301      * is no suitable driver or the driver fails to load.
302      */

303     protected Connection JavaDoc getConnection() throws BuildException {
304         if (userId == null) {
305             throw new BuildException("UserId attribute must be set!", getLocation());
306         }
307         if (password == null) {
308             throw new BuildException("Password attribute must be set!", getLocation());
309         }
310         if (url == null) {
311             throw new BuildException("Url attribute must be set!", getLocation());
312         }
313         try {
314
315             log("connecting to " + getUrl(), Project.MSG_VERBOSE);
316             Properties JavaDoc info = new Properties JavaDoc();
317             info.put("user", getUserId());
318             info.put("password", getPassword());
319             Connection JavaDoc conn = getDriver().connect(getUrl(), info);
320
321             if (conn == null) {
322                 // Driver doesn't understand the URL
323
throw new SQLException JavaDoc("No suitable Driver for " + url);
324             }
325
326             conn.setAutoCommit(autocommit);
327             return conn;
328         } catch (SQLException JavaDoc e) {
329             throw new BuildException(e, getLocation());
330         }
331
332     }
333
334     /**
335      * Gets an instance of the required driver.
336      * Uses the ant class loader and the optionally the provided classpath.
337      * @return Driver
338      * @throws BuildException
339      */

340     private Driver JavaDoc getDriver() throws BuildException {
341         if (driver == null) {
342             throw new BuildException("Driver attribute must be set!", getLocation());
343         }
344
345         Driver JavaDoc driverInstance = null;
346         try {
347             Class JavaDoc dc;
348             if (classpath != null) {
349                 // check first that it is not already loaded otherwise
350
// consecutive runs seems to end into an OutOfMemoryError
351
// or it fails when there is a native library to load
352
// several times.
353
// this is far from being perfect but should work
354
// in most cases.
355
synchronized (loaderMap) {
356                     if (caching) {
357                         loader = (AntClassLoader) loaderMap.get(driver);
358                     }
359                     if (loader == null) {
360                         log("Loading " + driver
361                             + " using AntClassLoader with classpath "
362                             + classpath, Project.MSG_VERBOSE);
363                         loader = getProject().createClassLoader(classpath);
364                         if (caching) {
365                             loaderMap.put(driver, loader);
366                         }
367                     } else {
368                         log("Loading " + driver
369                             + " using a cached AntClassLoader.",
370                                 Project.MSG_VERBOSE);
371                     }
372                 }
373                 dc = loader.loadClass(driver);
374             } else {
375                 log("Loading " + driver + " using system loader.",
376                     Project.MSG_VERBOSE);
377                 dc = Class.forName(driver);
378             }
379             driverInstance = (Driver JavaDoc) dc.newInstance();
380         } catch (ClassNotFoundException JavaDoc e) {
381             throw new BuildException(
382                     "Class Not Found: JDBC driver " + driver + " could not be loaded",
383                     e,
384                     getLocation());
385         } catch (IllegalAccessException JavaDoc e) {
386             throw new BuildException(
387                     "Illegal Access: JDBC driver " + driver + " could not be loaded",
388                     e,
389                     getLocation());
390         } catch (InstantiationException JavaDoc e) {
391             throw new BuildException(
392                     "Instantiation Exception: JDBC driver " + driver + " could not be loaded",
393                     e,
394                     getLocation());
395         }
396         return driverInstance;
397     }
398
399
400     /**
401      * Set the caching attribute.
402      * @param value a <code>boolean</code> value
403      */

404     public void isCaching(boolean value) {
405         caching = value;
406     }
407
408     /**
409      * Gets the classpath.
410      * @return Returns a Path
411      */

412     public Path getClasspath() {
413         return classpath;
414     }
415
416     /**
417      * Gets the autocommit.
418      * @return Returns a boolean
419      */

420     public boolean isAutocommit() {
421         return autocommit;
422     }
423
424     /**
425      * Gets the url.
426      * @return Returns a String
427      */

428     public String JavaDoc getUrl() {
429         return url;
430     }
431
432     /**
433      * Gets the userId.
434      * @return Returns a String
435      */

436     public String JavaDoc getUserId() {
437         return userId;
438     }
439
440     /**
441      * Set the user name for the connection; required.
442      * @param userId The userId to set
443      */

444     public void setUserid(String JavaDoc userId) {
445         this.userId = userId;
446     }
447
448     /**
449      * Gets the password.
450      * @return Returns a String
451      */

452     public String JavaDoc getPassword() {
453         return password;
454     }
455
456     /**
457      * Gets the rdbms.
458      * @return Returns a String
459      */

460     public String JavaDoc getRdbms() {
461         return rdbms;
462     }
463
464     /**
465      * Gets the version.
466      * @return Returns a String
467      */

468     public String JavaDoc getVersion() {
469         return version;
470     }
471
472 }
473
Popular Tags