KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > tigris > scarab > migration > JDBCTask


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2002-2003 The Apache Software Foundation. All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  *
19  * 3. The end-user documentation included with the redistribution, if
20  * any, must include the following acknowlegement:
21  * "This product includes software developed by the
22  * Apache Software Foundation (http://www.apache.org/)."
23  * Alternately, this acknowlegement may appear in the software itself,
24  * if and wherever such third-party acknowlegements normally appear.
25  *
26  * 4. The names "Ant" and "Apache Software
27  * Foundation" must not be used to endorse or promote products derived
28  * from this software without prior written permission. For written
29  * permission, please contact apache@apache.org.
30  *
31  * 5. Products derived from this software may not be called "Apache"
32  * nor may "Apache" appear in their names without prior written
33  * permission of the Apache Group.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Apache Software Foundation. For more
51  * information on the Apache Software Foundation, please see
52  * <http://www.apache.org/>.
53  */

54
55 package org.tigris.scarab.migration;
56
57 import java.sql.Connection JavaDoc;
58 import java.sql.DatabaseMetaData JavaDoc;
59 import java.sql.Driver JavaDoc;
60 import java.sql.SQLException JavaDoc;
61 import java.util.Hashtable JavaDoc;
62 import java.util.Properties JavaDoc;
63 import org.apache.tools.ant.AntClassLoader;
64 import org.apache.tools.ant.BuildException;
65 import org.apache.tools.ant.Project;
66 import org.apache.tools.ant.Task;
67 import org.apache.tools.ant.types.Path;
68 import org.apache.tools.ant.types.Reference;
69
70 /**
71  * This is a copy of a class available in Ant 1.5, it should retain the
72  * copyright notice above and we should remove this class as soon as support
73  * for Ant 1.4 is removed.
74  */

75 public abstract class JDBCTask extends Task {
76
77
78     /**
79      * Used for caching loaders / driver. This is to avoid
80      * getting an OutOfMemoryError when calling this task
81      * multiple times in a row.
82      */

83     private static Hashtable JavaDoc loaderMap = new Hashtable JavaDoc(3);
84
85     private boolean caching = true;
86
87     private Path classpath;
88
89     private AntClassLoader loader;
90
91     /**
92      * Autocommit flag. Default value is false
93      */

94     private boolean autocommit = false;
95
96     /**
97      * DB driver.
98      */

99     private String JavaDoc driver = null;
100
101     /**
102      * DB url.
103      */

104     private String JavaDoc url = null;
105
106     /**
107      * User name.
108      */

109     private String JavaDoc userId = null;
110
111     /**
112      * Password
113      */

114     private String JavaDoc password = null;
115
116     /**
117      * RDBMS Product needed for this SQL.
118      **/

119     private String JavaDoc rdbms = null;
120
121     /**
122      * RDBMS Version needed for this SQL.
123      **/

124     private String JavaDoc version = null;
125
126     /**
127      * Sets the classpath for loading the driver.
128      * @param classpath The classpath to set
129      */

130     public void setClasspath(Path classpath) {
131         this.classpath = classpath;
132     }
133
134     /**
135      * Caching loaders / driver. This is to avoid
136      * getting an OutOfMemoryError when calling this task
137      * multiple times in a row; default: true
138      * @param enable
139      */

140     public void setCaching(boolean enable) {
141         caching = enable;
142     }
143
144     /**
145      * Add a path to the classpath for loading the driver.
146      */

147     public Path createClasspath() {
148         if (this.classpath == null) {
149             this.classpath = new Path(getProject());
150         }
151         return this.classpath.createPath();
152     }
153
154     /**
155      * Set the classpath for loading the driver
156      * using the classpath reference.
157      */

158     public void setClasspathRef(Reference r) {
159         createClasspath().setRefid(r);
160     }
161
162     /**
163      * Class name of the JDBC driver; required.
164      * @param driver The driver to set
165      */

166     public void setDriver(String JavaDoc driver) {
167         this.driver = driver;
168     }
169
170     /**
171      * Sets the database connection URL; required.
172      * @param url The url to set
173      */

174     public void setUrl(String JavaDoc url) {
175         this.url = url;
176     }
177
178     /**
179      * Sets the password; required.
180      * @param password The password to set
181      */

182     public void setPassword(String JavaDoc password) {
183         this.password = password;
184     }
185
186     /**
187      * Auto commit flag for database connection;
188      * optional, default false.
189      * @param autocommit The autocommit to set
190      */

191     public void setAutocommit(boolean autocommit) {
192         this.autocommit = autocommit;
193     }
194
195     /**
196      * Execute task only if the lower case product name
197      * of the DB matches this
198      * @param rdbms The rdbms to set
199      */

200     public void setRdbms(String JavaDoc rdbms) {
201         this.rdbms = rdbms;
202     }
203
204     /**
205      * Sets the version string, execute task only if
206      * rdbms version match; optional.
207      * @param version The version to set
208      */

209     public void setVersion(String JavaDoc version) {
210         this.version = version;
211     }
212
213     /**
214      * Verify we are connected to the correct RDBMS
215      */

216     protected boolean isValidRdbms(Connection JavaDoc conn) {
217         if (rdbms == null && version == null) {
218             return true;
219         }
220
221         try {
222             DatabaseMetaData JavaDoc dmd = conn.getMetaData();
223
224             if (rdbms != null) {
225                 String JavaDoc theVendor = dmd.getDatabaseProductName().toLowerCase();
226
227                 log("RDBMS = " + theVendor, Project.MSG_VERBOSE);
228                 if (theVendor == null || theVendor.indexOf(rdbms) < 0) {
229                     log("Not the required RDBMS: " + rdbms, Project.MSG_VERBOSE);
230                     return false;
231                 }
232             }
233
234             if (version != null) {
235                 // XXX maybe better toLowerCase(Locale.US)
236
String JavaDoc theVersion = dmd.getDatabaseProductVersion().toLowerCase();
237
238                 log("Version = " + theVersion, Project.MSG_VERBOSE);
239                 if (theVersion == null
240                         || !(theVersion.startsWith(version) || theVersion.indexOf(" " + version) >= 0)) {
241                     log("Not the required version: \"" + version + "\"", Project.MSG_VERBOSE);
242                     return false;
243                 }
244             }
245         } catch (SQLException JavaDoc e) {
246             // Could not get the required information
247
log("Failed to obtain required RDBMS information", Project.MSG_ERR);
248             return false;
249         }
250
251         return true;
252     }
253
254     protected static Hashtable JavaDoc getLoaderMap() {
255         return loaderMap;
256     }
257
258     protected AntClassLoader getLoader() {
259         return loader;
260     }
261
262     /**
263      * Creates a new Connection as using the driver, url, userid and password specified.
264      * The calling method is responsible for closing the connection.
265      * @return Connection the newly created connection.
266      * @throws BuildException if the UserId/Password/Url is not set or there is no suitable driver or the driver fails to load.
267      */

268     protected Connection JavaDoc getConnection() throws BuildException {
269         if (userId == null) {
270             throw new BuildException("User Id attribute must be set!", getLocation());
271         }
272         if (password == null) {
273             throw new BuildException("Password attribute must be set!", getLocation());
274         }
275         if (url == null) {
276             throw new BuildException("Url attribute must be set!", getLocation());
277         }
278         try {
279
280             log("connecting to " + getUrl(), Project.MSG_VERBOSE);
281             Properties JavaDoc info = new Properties JavaDoc();
282             info.put("user", getUserId());
283             info.put("password", getPassword());
284             Connection JavaDoc conn = getDriver().connect(getUrl(), info);
285
286             if (conn == null) {
287                 // Driver doesn't understand the URL
288
throw new SQLException JavaDoc("No suitable Driver for " + url);
289             }
290
291             conn.setAutoCommit(autocommit);
292             return conn;
293         } catch (SQLException JavaDoc e) {
294             throw new BuildException(e, getLocation());
295         }
296
297     }
298
299     /**
300      * Gets an instance of the required driver.
301      * Uses the ant class loader and the optionally the provided classpath.
302      * @return Driver
303      * @throws BuildException
304      */

305     private Driver JavaDoc getDriver() throws BuildException {
306         if (driver == null) {
307             throw new BuildException("Driver attribute must be set!", getLocation());
308         }
309
310         Driver JavaDoc driverInstance = null;
311         try {
312             Class JavaDoc dc;
313             if (classpath != null) {
314                 // check first that it is not already loaded otherwise
315
// consecutive runs seems to end into an OutOfMemoryError
316
// or it fails when there is a native library to load
317
// several times.
318
// this is far from being perfect but should work
319
// in most cases.
320
synchronized (loaderMap) {
321                     if (caching) {
322                         loader = (AntClassLoader) loaderMap.get(driver);
323                     }
324                     if (loader == null) {
325                         log(
326                                 "Loading " + driver + " using AntClassLoader with classpath " + classpath,
327                                 Project.MSG_VERBOSE);
328                         // jdm - modified for usage with Ant 1.4
329
// loader = getProject().createClassLoader(classpath);
330
loader = new AntClassLoader(project, classpath);
331                         if (caching) {
332                             loaderMap.put(driver, loader);
333                         }
334                     } else {
335                         log(
336                                 "Loading " + driver + " using a cached AntClassLoader.",
337                                 Project.MSG_VERBOSE);
338                     }
339                 }
340                 dc = loader.loadClass(driver);
341             } else {
342                 log("Loading " + driver + " using system loader.", Project.MSG_VERBOSE);
343                 dc = Class.forName(driver);
344             }
345             driverInstance = (Driver JavaDoc) dc.newInstance();
346         } catch (ClassNotFoundException JavaDoc e) {
347             throw new BuildException(
348                     "Class Not Found: JDBC driver " + driver + " could not be loaded",
349                     getLocation());
350         } catch (IllegalAccessException JavaDoc e) {
351             throw new BuildException(
352                     "Illegal Access: JDBC driver " + driver + " could not be loaded",
353                     getLocation());
354         } catch (InstantiationException JavaDoc e) {
355             throw new BuildException(
356                     "Instantiation Exception: JDBC driver " + driver + " could not be loaded",
357                     getLocation());
358         }
359         return driverInstance;
360     }
361
362
363     public void isCaching(boolean value) {
364         caching = value;
365     }
366
367     /**
368      * Gets the classpath.
369      * @return Returns a Path
370      */

371     public Path getClasspath() {
372         return classpath;
373     }
374
375     /**
376      * Gets the autocommit.
377      * @return Returns a boolean
378      */

379     public boolean isAutocommit() {
380         return autocommit;
381     }
382
383     /**
384      * Gets the url.
385      * @return Returns a String
386      */

387     public String JavaDoc getUrl() {
388         return url;
389     }
390
391     /**
392      * Gets the userId.
393      * @return Returns a String
394      */

395     public String JavaDoc getUserId() {
396         return userId;
397     }
398
399     /**
400      * Set the user name for the connection; required.
401      * @param userId The userId to set
402      */

403     public void setUserid(String JavaDoc userId) {
404         this.userId = userId;
405     }
406
407     /**
408      * Gets the password.
409      * @return Returns a String
410      */

411     public String JavaDoc getPassword() {
412         return password;
413     }
414
415     /**
416      * Gets the rdbms.
417      * @return Returns a String
418      */

419     public String JavaDoc getRdbms() {
420         return rdbms;
421     }
422
423     /**
424      * Gets the version.
425      * @return Returns a String
426      */

427     public String JavaDoc getVersion() {
428         return version;
429     }
430
431 }
432
Popular Tags