/* * The Apache Software License, Version 1.1 * * Copyright (c) 2001-2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Ant", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ package org.apache.tools.ant.taskdefs.condition; import java.io.IOException; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.ProjectComponent; import org.apache.tools.ant.types.Reference; import org.apache.tools.ant.types.EnumeratedAttribute; import org.apache.tools.ant.types.JDBCConnection; /** * Condition to check database metadata for objects. Its attribute(s) are: * schema - * connectionRef - * * @author Thierry Lach * @since Ant 1.6 */ public class JDBCCondition extends ProjectComponent implements Condition { private Connection connection = null; private JDBCConnection jdbc = null; private String catalog = null; private String schema = null; private String table = null; private String name = null; private String type = null; // private boolean unique = false; public static String SCHEMA = "schema"; public static String CATALOG = "catalog"; public static String TABLE = "table"; public static String VIEW = "view"; public static String COLUMN = "column"; public static String INDEX = "index"; public boolean eval() throws BuildException { boolean result = false; validateArguments(); this.connection = this.jdbc.getConnectionInstance(); if (this.connection == null) { throw new BuildException("Unable to connect to database"); } try { result = checkMetaData(); } catch (SQLException e) { result = false; } return result; } // public void setUnique(boolean unique) { // this.unique = unique; // } // public boolean getUnique() { // return this.unique; // } public void setTable(String table) { this.table = table; } public String getTable() { return this.table; } public void setCatalog(String catalog) { this.catalog = catalog; } public String getCatalog() { return this.catalog; } public void setSchema(String schema) { this.schema = schema; } public String getSchema() { return this.schema; } public void setType(ObjectType type) { this.type = type.getValue(); } public String getType() { return this.type; } public void setName(String name) { this.name = name; } public String getName() { return this.name; } public void setConnectionRef(Reference r) { // this.connectionRef = r; this.jdbc = new JDBCConnection(getProject()); this.jdbc.setConnectionRef(r); } // public Reference getConnectionRef() { // return this.connection.getConnectionRef(); // } private boolean checkResultSet(ResultSet rs, int col) throws BuildException { boolean result = false; try { String val; while( (!result) && rs.next()) { val = rs.getString(col); if (val.equalsIgnoreCase(name)) { result = true; } } } catch (SQLException e) { throw new BuildException("Unable to fetch metadata resultset", e); } try { rs.close(); } catch (SQLException e) { throw new BuildException("Unable to close metadata resultset", e); } return result; } private boolean checkCatalog(DatabaseMetaData dbmd) throws BuildException { ResultSet rs = null; try { rs = dbmd.getCatalogs(); } catch (SQLException e) { throw new BuildException("Unable to get metadata resultset", e); } return checkResultSet(rs, 1); } private boolean checkSchema(DatabaseMetaData dbmd) throws BuildException { ResultSet rs = null; try { rs = dbmd.getSchemas(); } catch (SQLException e) { throw new BuildException("Unable to get metadata resultset", e); } return checkResultSet(rs, 1); } private boolean checkColumn(DatabaseMetaData dbmd) throws BuildException { ResultSet rs = null; boolean result = false; try { rs = dbmd.getColumns(this.catalog, this.schema, this.table, this.name); } catch (SQLException e) { throw new BuildException("Unable to get metadata resultset", e); } return checkResultSet(rs, 4); } private boolean checkIndex(DatabaseMetaData dbmd) throws BuildException { ResultSet rs = null; try { rs = dbmd.getIndexInfo(this.catalog, this.schema, this.table, false, false); } catch (SQLException e) { throw new BuildException("Unable to get metadata resultset", e); } return checkResultSet(rs, 6); } private boolean checkTableOrView(DatabaseMetaData dbmd, String passedType) throws BuildException { ResultSet rs = null; boolean result = false; String[] typelist = new String[] { passedType }; try { rs = dbmd.getTables(this.catalog, this.schema, this.name, typelist); } catch (SQLException e) { throw new BuildException("Unable to get metadata resultset", e); } return checkResultSet(rs, 3); } private boolean checkMetaData() throws SQLException { boolean result = false; DatabaseMetaData dbmd = null; try { dbmd = connection.getMetaData(); } catch (SQLException e) { throw new BuildException("Unable to get database metadata", e); } log(" Looking for " + type + " '" + this.name + "'", Project.MSG_DEBUG); if (SCHEMA.equals(type)) { result = checkSchema(dbmd); } if (TABLE.equals(type)) { result = checkTableOrView(dbmd, TABLE.toUpperCase()); } if (VIEW.equals(type)) { result = checkTableOrView(dbmd, VIEW.toUpperCase()); } if (INDEX.equals(type)) { result = checkIndex(dbmd); } if (COLUMN.equals(type)) { result = checkColumn(dbmd); } if (result) { log(" Found " + type + " '" + this.name + "'", Project.MSG_DEBUG); } else { log(" Did not find " + type + " '" + this.name + "'", Project.MSG_DEBUG); } return result; } private void requireType() throws BuildException { if (this.type == null) { throw new BuildException("Type not supplied"); } } private void requireConnection() throws BuildException { if (this.jdbc == null) { throw new BuildException("Connection not supplied"); } } private void requireName() throws BuildException { if (this.name == null) { throw new BuildException("Name not supplied"); } } private void requireTable() throws BuildException { if (this.table == null) { throw new BuildException("Table not supplied"); } } private void validateArguments() throws BuildException { requireType(); requireConnection(); requireName(); if (SCHEMA.equals(type)) { } else if (TABLE.equals(type)) { } else if (VIEW.equals(type)) { } else if (INDEX.equals(type)) { requireTable(); } else if (COLUMN.equals(type)) { requireTable(); } } /** * The type of object to check for, one of the list * "schema", "catalog", "table", "view", "column", "index". */ public static class ObjectType extends EnumeratedAttribute { public String[] getValues() { return new String[] {SCHEMA, CATALOG, TABLE, VIEW, COLUMN, INDEX}; } } }