aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/JDBCTask.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/JDBCTask.java')
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/JDBCTask.java525
1 files changed, 525 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/JDBCTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/JDBCTask.java
new file mode 100644
index 00000000..2ca6e22a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/JDBCTask.java
@@ -0,0 +1,525 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.Driver;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Properties;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+
+/**
+ * Handles JDBC configuration needed by SQL type tasks.
+ * <p>
+ * The following example class prints the contents of the first column of each row in TableName.
+ *</p>
+ *<pre>
+package examples;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.JDBCTask;
+
+public class SQLExampleTask extends JDBCTask {
+
+ private String tableName;
+
+ public void execute() throws BuildException {
+ Connection conn = getConnection();
+ Statement stmt=null;
+ try {
+ if (tableName == null) {
+ throw new BuildException("TableName must be specified",location);
+ }
+ String sql = "SELECT * FROM "+tableName;
+ stmt= conn.createStatement();
+ ResultSet rs = stmt.executeQuery(sql);
+ while (rs.next()) {
+ log(rs.getObject(1).toString());
+ }
+ } catch (SQLException e) {
+
+ } finally {
+ if (stmt != null) {
+ try {stmt.close();}catch (SQLException ignore) {}
+ }
+ if (conn != null) {
+ try {conn.close();}catch (SQLException ignore) {}
+ }
+ }
+ }
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+}
+</pre>
+ *
+ * @since Ant 1.5
+ *
+ */
+public abstract class JDBCTask extends Task {
+ private static final int HASH_TABLE_SIZE = 3;
+
+ /**
+ * Used for caching loaders / driver. This is to avoid
+ * getting an OutOfMemoryError when calling this task
+ * multiple times in a row.
+ */
+ private static Hashtable<String, AntClassLoader> LOADER_MAP = new Hashtable<String, AntClassLoader>(HASH_TABLE_SIZE);
+
+ private boolean caching = true;
+
+ private Path classpath;
+
+ private AntClassLoader loader;
+
+ /**
+ * Autocommit flag. Default value is false
+ */
+ private boolean autocommit = false;
+
+ /**
+ * DB driver.
+ */
+ private String driver = null;
+
+ /**
+ * DB url.
+ */
+ private String url = null;
+
+ /**
+ * User name.
+ */
+ private String userId = null;
+
+ /**
+ * Password
+ */
+ private String password = null;
+
+ /**
+ * RDBMS Product needed for this SQL.
+ **/
+ private String rdbms = null;
+
+ /**
+ * RDBMS Version needed for this SQL.
+ **/
+ private String version = null;
+
+ /**
+ * whether the task fails when ant fails to connect to the database.
+ * @since Ant 1.8.0
+ */
+ private boolean failOnConnectionError = true;
+
+ /**
+ * Additional properties to put into the JDBC connection string.
+ *
+ * @since Ant 1.8.0
+ */
+ private List<Property> connectionProperties = new ArrayList<Property>();
+
+ /**
+ * Sets the classpath for loading the driver.
+ * @param classpath The classpath to set
+ */
+ public void setClasspath(Path classpath) {
+ this.classpath = classpath;
+ }
+
+ /**
+ * Caching loaders / driver. This is to avoid
+ * getting an OutOfMemoryError when calling this task
+ * multiple times in a row; default: true
+ * @param enable a <code>boolean</code> value
+ */
+ public void setCaching(boolean enable) {
+ caching = enable;
+ }
+
+ /**
+ * Add a path to the classpath for loading the driver.
+ * @return a path to be configured
+ */
+ public Path createClasspath() {
+ if (this.classpath == null) {
+ this.classpath = new Path(getProject());
+ }
+ return this.classpath.createPath();
+ }
+
+ /**
+ * Set the classpath for loading the driver
+ * using the classpath reference.
+ * @param r a reference to a classpath
+ */
+ public void setClasspathRef(Reference r) {
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * Class name of the JDBC driver; required.
+ * @param driver The driver to set
+ */
+ public void setDriver(String driver) {
+ this.driver = driver.trim();
+ }
+
+ /**
+ * Sets the database connection URL; required.
+ * @param url The url to set
+ */
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ /**
+ * Sets the password; required.
+ * @param password The password to set
+ */
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ /**
+ * Auto commit flag for database connection;
+ * optional, default false.
+ * @param autocommit The autocommit to set
+ */
+ public void setAutocommit(boolean autocommit) {
+ this.autocommit = autocommit;
+ }
+
+ /**
+ * Execute task only if the lower case product name
+ * of the DB matches this
+ * @param rdbms The rdbms to set
+ */
+ public void setRdbms(String rdbms) {
+ this.rdbms = rdbms;
+ }
+
+ /**
+ * Sets the version string, execute task only if
+ * rdbms version match; optional.
+ * @param version The version to set
+ */
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ /**
+ * whether the task should cause the build to fail if it cannot
+ * connect to the database.
+ * @since Ant 1.8.0
+ */
+ public void setFailOnConnectionError(boolean b) {
+ failOnConnectionError = b;
+ }
+
+ /**
+ * Verify we are connected to the correct RDBMS
+ * @param conn the jdbc connection
+ * @return true if we are connected to the correct RDBMS
+ */
+ protected boolean isValidRdbms(Connection conn) {
+ if (rdbms == null && version == null) {
+ return true;
+ }
+
+ try {
+ DatabaseMetaData dmd = conn.getMetaData();
+
+ if (rdbms != null) {
+ String theVendor = dmd.getDatabaseProductName().toLowerCase();
+
+ log("RDBMS = " + theVendor, Project.MSG_VERBOSE);
+ if (theVendor == null || theVendor.indexOf(rdbms) < 0) {
+ log("Not the required RDBMS: " + rdbms, Project.MSG_VERBOSE);
+ return false;
+ }
+ }
+
+ if (version != null) {
+ String theVersion = dmd.getDatabaseProductVersion().toLowerCase(Locale.ENGLISH);
+
+ log("Version = " + theVersion, Project.MSG_VERBOSE);
+ if (theVersion == null
+ || !(theVersion.startsWith(version)
+ || theVersion.indexOf(" " + version) >= 0)) {
+ log("Not the required version: \"" + version + "\"", Project.MSG_VERBOSE);
+ return false;
+ }
+ }
+ } catch (SQLException e) {
+ // Could not get the required information
+ log("Failed to obtain required RDBMS information", Project.MSG_ERR);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Get the cache of loaders and drivers.
+ * @return a hashtable
+ */
+ protected static Hashtable<String, AntClassLoader> getLoaderMap() {
+ return LOADER_MAP;
+ }
+
+ /**
+ * Get the classloader used to create a driver.
+ * @return the classloader
+ */
+ protected AntClassLoader getLoader() {
+ return loader;
+ }
+
+ /**
+ * Additional properties to put into the JDBC connection string.
+ *
+ * @since Ant 1.8.0
+ */
+ public void addConnectionProperty(Property var) {
+ connectionProperties.add(var);
+ }
+
+ /**
+ * Creates a new Connection as using the driver, url, userid and password
+ * specified.
+ *
+ * The calling method is responsible for closing the connection.
+ *
+ * @return Connection the newly created connection or null if the
+ * connection failed and failOnConnectionError is false.
+ * @throws BuildException if the UserId/Password/Url is not set or there
+ * is no suitable driver or the driver fails to load.
+ */
+ protected Connection getConnection() throws BuildException {
+ if (userId == null) {
+ throw new BuildException("UserId attribute must be set!", getLocation());
+ }
+ if (password == null) {
+ throw new BuildException("Password attribute must be set!", getLocation());
+ }
+ if (url == null) {
+ throw new BuildException("Url attribute must be set!", getLocation());
+ }
+ try {
+
+ log("connecting to " + getUrl(), Project.MSG_VERBOSE);
+ Properties info = new Properties();
+ info.put("user", getUserId());
+ info.put("password", getPassword());
+
+ for (Iterator<Property> props = connectionProperties.iterator();
+ props.hasNext();) {
+ Property p = props.next();
+ String name = p.getName();
+ String value = p.getValue();
+ if (name == null || value == null) {
+ log("Only name/value pairs are supported as connection"
+ + " properties.", Project.MSG_WARN);
+ } else {
+ log("Setting connection property " + name + " to " + value,
+ Project.MSG_VERBOSE);
+ info.put(name, value);
+ }
+ }
+
+ Connection conn = getDriver().connect(getUrl(), info);
+
+ if (conn == null) {
+ // Driver doesn't understand the URL
+ throw new SQLException("No suitable Driver for " + url);
+ }
+
+ conn.setAutoCommit(autocommit);
+ return conn;
+ } catch (SQLException e) {
+ // failed to connect
+ if (!failOnConnectionError) {
+ log("Failed to connect: " + e.getMessage(), Project.MSG_WARN);
+ return null;
+ } else {
+ throw new BuildException(e, getLocation());
+ }
+ }
+
+ }
+
+ /**
+ * Gets an instance of the required driver.
+ * Uses the ant class loader and the optionally the provided classpath.
+ * @return Driver
+ * @throws BuildException
+ */
+ private Driver getDriver() throws BuildException {
+ if (driver == null) {
+ throw new BuildException("Driver attribute must be set!", getLocation());
+ }
+
+ Driver driverInstance = null;
+ try {
+ Class<?> dc;
+ if (classpath != null) {
+ // check first that it is not already loaded otherwise
+ // consecutive runs seems to end into an OutOfMemoryError
+ // or it fails when there is a native library to load
+ // several times.
+ // this is far from being perfect but should work
+ // in most cases.
+ synchronized (LOADER_MAP) {
+ if (caching) {
+ loader = LOADER_MAP.get(driver);
+ }
+ if (loader == null) {
+ log("Loading " + driver
+ + " using AntClassLoader with classpath "
+ + classpath, Project.MSG_VERBOSE);
+ loader = getProject().createClassLoader(classpath);
+ if (caching) {
+ LOADER_MAP.put(driver, loader);
+ }
+ } else {
+ log("Loading " + driver
+ + " using a cached AntClassLoader.",
+ Project.MSG_VERBOSE);
+ }
+ }
+ dc = loader.loadClass(driver);
+ } else {
+ log("Loading " + driver + " using system loader.",
+ Project.MSG_VERBOSE);
+ dc = Class.forName(driver);
+ }
+ driverInstance = (Driver) dc.newInstance();
+ } catch (ClassNotFoundException e) {
+ throw new BuildException(
+ "Class Not Found: JDBC driver " + driver + " could not be loaded",
+ e,
+ getLocation());
+ } catch (IllegalAccessException e) {
+ throw new BuildException(
+ "Illegal Access: JDBC driver " + driver + " could not be loaded",
+ e,
+ getLocation());
+ } catch (InstantiationException e) {
+ throw new BuildException(
+ "Instantiation Exception: JDBC driver " + driver + " could not be loaded",
+ e,
+ getLocation());
+ }
+ return driverInstance;
+ }
+
+
+ /**
+ * Set the caching attribute.
+ * @param value a <code>boolean</code> value
+ */
+ public void isCaching(boolean value) {
+ caching = value;
+ }
+
+ /**
+ * Gets the classpath.
+ * @return Returns a Path
+ */
+ public Path getClasspath() {
+ return classpath;
+ }
+
+ /**
+ * Gets the autocommit.
+ * @return Returns a boolean
+ */
+ public boolean isAutocommit() {
+ return autocommit;
+ }
+
+ /**
+ * Gets the url.
+ * @return Returns a String
+ */
+ public String getUrl() {
+ return url;
+ }
+
+ /**
+ * Gets the userId.
+ * @return Returns a String
+ */
+ public String getUserId() {
+ return userId;
+ }
+
+ /**
+ * Set the user name for the connection; required.
+ * @param userId The userId to set
+ */
+ public void setUserid(String userId) {
+ this.userId = userId;
+ }
+
+ /**
+ * Gets the password.
+ * @return Returns a String
+ */
+ public String getPassword() {
+ return password;
+ }
+
+ /**
+ * Gets the rdbms.
+ * @return Returns a String
+ */
+ public String getRdbms() {
+ return rdbms;
+ }
+
+ /**
+ * Gets the version.
+ * @return Returns a String
+ */
+ public String getVersion() {
+ return version;
+ }
+
+}