All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.dbunit.ant.DbUnitTask Maven / Gradle / Ivy

/*
 *
 * The DbUnit Database Testing Framework
 * Copyright (C)2002-2004, DbUnit.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */
package org.dbunit.ant;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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;
import org.dbunit.DatabaseUnitException;
import org.dbunit.database.DatabaseConfig;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.datatype.IDataTypeFactory;

import java.sql.Connection;
import java.sql.Driver;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

/**
 * DbUnitTask is the task definition for an Ant interface to
 * DbUnit. DbUnit is a JUnit extension which sets your database to
 * a known state before executing your tasks.
 *
 * @author Timothy Ruppert
 * @author Ben Cox
 * @version $Revision$
 * @since Jun 10, 2002
 * @see org.apache.tools.ant.Task
 */
public class DbUnitTask extends Task {

    /**
     * Logger for this class
     */
    private static final Logger logger = LoggerFactory.getLogger(DbUnitTask.class);

    /**
     * Database connection
     */
    private Connection conn = null;

    /**
     * DB driver.
     */
    private String driver = null;

    /**
     * DB url.
     */
    private String url = null;

    /**
     * User name.
     */
    private String userId = null;

    /**
     * Password
     */
    private String password = null;

    /**
     * DB schema.
     */
    private String schema = null;

    /**
     * Steps
     */
    private List steps = new ArrayList();

    private Path classpath;

    private AntClassLoader loader;

    /**
     * DB configuration child element to configure {@link DatabaseConfig} properties
     * in a generic way.
     */
    private DbConfig dbConfig;

    /**
     * Flag for using the qualified table names.
     * 
     * @deprecated since 2.4. Use {@link #dbConfig} instead. Only here because of
     *             backwards compatibility should be removed in the next major
     *             release.
     */
    private Boolean useQualifiedTableNames = null;

    /**
     * Flag for using batched statements.
     * 
     * @deprecated since 2.4. Use {@link #dbConfig} instead. Only here because of
     *             backwards compatibility should be removed in the next major
     *             release.
     */
    private Boolean supportBatchStatement = null;

    /**
     * Flag for datatype warning.
     * 
     * @deprecated since 2.4. Use {@link #dbConfig} instead. Only here because of
     *             backwards compatibility should be removed in the next major
     *             release.
     */
    private Boolean datatypeWarning = null;

    /**
     * @deprecated since 2.4. Use {@link #dbConfig} instead. Only here because of
     *             backwards compatibility should be removed in the next major
     *             release.
     */
    private String escapePattern = null;

    /**
     * @deprecated since 2.4. Use {@link #dbConfig} instead. Only here because of
     *             backwards compatibility should be removed in the next major
     *             release.
     */
    private String dataTypeFactory = null;

    /**
     * @deprecated since 2.4. Use {@link #dbConfig} instead. Only here because of
     *             backwards compatibility should be removed in the next major
     *             release.
     */
    private String batchSize = null;

    /**
     * @deprecated since 2.4. Use {@link #dbConfig} instead. Only here because of
     *             backwards compatibility should be removed in the next major
     *             release.
     */
    private String fetchSize = null;

    /**
     * @deprecated since 2.4. Use {@link #dbConfig} instead. Only here because of
     *             backwards compatibility should be removed in the next major
     *             release.
     */
    private Boolean skipOracleRecycleBinTables = null;

    /**
     * @deprecated since 2.5.1. Use {@link #dbConfig} instead. Only here because of
     *             backwards compatibility should be removed in the next major
     *             release.
     */
    private Boolean allowEmptyFields = null;

    /**
     * Set the JDBC driver to be used.
     */
    public void setDriver(String driver) {
        logger.trace("setDriver(driver={}) - start", driver);
        this.driver = driver;
    }

    /**
     * Set the DB connection url.
     */
    public void setUrl(String url) {
        logger.trace("setUrl(url={}) - start", url);
        this.url = url;
    }

    /**
     * Set the user name for the DB connection.
     */
    public void setUserid(String userId) {
        logger.trace("setUserid(userId={}) - start", userId);
        this.userId = userId;
    }

    /**
     * Set the password for the DB connection.
     */
    public void setPassword(String password) {
        logger.trace("setPassword(password=*****) - start");
        this.password = password;
    }

    /**
     * Set the schema for the DB connection.
     */
    public void setSchema(String schema) {
        logger.trace("setSchema(schema={}) - start", schema);
        this.schema = schema;
    }

    /**
     * Set the flag for using the qualified table names.
     */
    public void setUseQualifiedTableNames(Boolean useQualifiedTableNames) {
        logger.trace("setUseQualifiedTableNames(useQualifiedTableNames={}) - start",
                String.valueOf(useQualifiedTableNames));
        this.useQualifiedTableNames = useQualifiedTableNames;
    }

    /**
     * Set the flag for supporting batch statements. NOTE: This property cannot be
     * used to force the usage of batch statement if your database does not support
     * it.
     */
    public void setSupportBatchStatement(Boolean supportBatchStatement) {
        logger.trace("setSupportBatchStatement(supportBatchStatement={}) - start",
                String.valueOf(supportBatchStatement));
        this.supportBatchStatement = supportBatchStatement;
    }

    public void setDatatypeWarning(Boolean datatypeWarning) {
        logger.trace("setDatatypeWarning(datatypeWarning={}) - start", String.valueOf(datatypeWarning));
        this.datatypeWarning = datatypeWarning;
    }

    public void setDatatypeFactory(String datatypeFactory) {
        logger.trace("setDatatypeFactory(datatypeFactory={}) - start", datatypeFactory);
        this.dataTypeFactory = datatypeFactory;
    }

    public void setEscapePattern(String escapePattern) {
        logger.trace("setEscapePattern(escapePattern={}) - start", escapePattern);
        this.escapePattern = escapePattern;
    }

    public DbConfig getDbConfig() {
        return dbConfig;
    }

//    public void setDbConfig(DbConfig dbConfig) 
//    {
//        logger.debug("setDbConfig(dbConfig={}) - start", dbConfig);
//        this.dbConfig = dbConfig;
//    }

    public void addDbConfig(DbConfig dbConfig) {
        logger.trace("addDbConfig(dbConfig={}) - start", dbConfig);
        this.dbConfig = dbConfig;
    }

    /**
     * Set the classpath for loading the driver.
     */
    public void setClasspath(Path classpath) {
        logger.trace("setClasspath(classpath={}) - start", classpath);
        if (this.classpath == null) {
            this.classpath = classpath;
        } else {
            this.classpath.append(classpath);
        }
    }

    /**
     * Create the classpath for loading the driver.
     */
    public Path createClasspath() {
        logger.trace("createClasspath() - start");

        if (this.classpath == null) {
            this.classpath = new Path(getProject());
        }
        return this.classpath.createPath();
    }

    /**
     * Set the classpath for loading the driver using the classpath reference.
     */
    public void setClasspathRef(Reference r) {
        logger.trace("setClasspathRef(r={}) - start", r);

        createClasspath().setRefid(r);
    }

    /**
     * Gets the Steps.
     */
    public List getSteps() {
        return steps;
    }

    /**
     * Adds an Operation.
     */
    public void addOperation(Operation operation) {
        logger.trace("addOperation({}) - start", operation);

        steps.add(operation);
    }

    /**
     * Adds a Compare to the steps List.
     */
    public void addCompare(Compare compare) {
        logger.trace("addCompare({}) - start", compare);

        steps.add(compare);
    }

    /**
     * Adds an Export to the steps List.
     */
    public void addExport(Export export) {
        logger.trace("addExport(export={}) - start", export);

        steps.add(export);
    }

    public String getBatchSize() {
        return batchSize;
    }

    /**
     * sets the size of batch inserts.
     * 
     * @param batchSize
     */
    public void setBatchSize(String batchSize) {
        this.batchSize = batchSize;
    }

    public String getFetchSize() {
        return fetchSize;
    }

    public void setFetchSize(String fetchSize) {
        this.fetchSize = fetchSize;
    }

    public void setSkipOracleRecycleBinTables(Boolean skipOracleRecycleBinTables) {
        this.skipOracleRecycleBinTables = skipOracleRecycleBinTables;
    }

    /**
     * Load the step and then execute it
     */
    public void execute() throws BuildException {
        logger.trace("execute() - start");

        try {
            IDatabaseConnection connection = createConnection();

            Iterator stepIter = steps.listIterator();
            while (stepIter.hasNext()) {
                DbUnitTaskStep step = (DbUnitTaskStep) stepIter.next();
                log(step.getLogMessage(), Project.MSG_INFO);
                step.execute(connection);
            }
        } catch (DatabaseUnitException e) {
            throw new BuildException(e, getLocation());
        } catch (SQLException e) {
            throw new BuildException(e, getLocation());
        } finally {
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                logger.error("execute()", e);
            }
        }
    }

    protected IDatabaseConnection createConnection() throws SQLException {
        logger.trace("createConnection() - start");

        if (driver == null) {
            throw new BuildException("Driver attribute must be set!", getLocation());
        }
        if (userId == null) {
            throw new BuildException("User Id 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());
        }
        if (steps.size() == 0) {
            throw new BuildException("Must declare at least one step in a  task!", getLocation());
        }

        // Instantiate JDBC driver
        Driver driverInstance = null;
        try {
            Class dc;
            if (classpath != null) {
                log("Loading " + driver + " using AntClassLoader with classpath " + classpath, Project.MSG_VERBOSE);

                loader = new AntClassLoader(getProject(), classpath);
                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());
        }

        log("connecting to " + url, Project.MSG_VERBOSE);
        Properties info = new Properties();
        info.put("user", userId);
        info.put("password", password);
        conn = driverInstance.connect(url, info);

        if (conn == null) {
            // Driver doesn't understand the URL
            throw new SQLException("No suitable Driver for " + url);
        }
        conn.setAutoCommit(true);

        IDatabaseConnection connection = createDatabaseConnection(conn, schema);
        return connection;
    }

    /**
     * Creates the dbunit connection using the two given arguments. The
     * configuration properties of the dbunit connection are initialized using the
     * fields of this class.
     * 
     * @param jdbcConnection
     * @param dbSchema
     * @return The dbunit connection
     */
    protected IDatabaseConnection createDatabaseConnection(Connection jdbcConnection, String dbSchema) {
        logger.trace("createDatabaseConnection(jdbcConnection={}, dbSchema={}) - start", jdbcConnection, dbSchema);

        IDatabaseConnection connection = null;
        try {
            connection = new DatabaseConnection(jdbcConnection, dbSchema);
        } catch (DatabaseUnitException e) {
            throw new BuildException("Could not create dbunit connection object", e);
        }
        DatabaseConfig config = connection.getConfig();

        if (this.dbConfig != null) {
            try {
                this.dbConfig.copyTo(config);
            } catch (DatabaseUnitException e) {
                throw new BuildException("Could not populate dbunit config object", e, getLocation());
            }
        }

        // For backwards compatibility (old mode overrides the new one) copy the other
        // attributes to the config
        copyAttributes(config);

        log("Created connection for schema '" + schema + "' with config: " + config, Project.MSG_VERBOSE);

        return connection;
    }

    /**
     * @param config
     * @deprecated since 2.4. Only here because of backwards compatibility should be
     *             removed in the next major release.
     */
    private void copyAttributes(DatabaseConfig config) {
        if (supportBatchStatement != null)
            config.setFeature(DatabaseConfig.FEATURE_BATCHED_STATEMENTS, supportBatchStatement.booleanValue());
        if (useQualifiedTableNames != null)
            config.setFeature(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, useQualifiedTableNames.booleanValue());
        if (datatypeWarning != null)
            config.setFeature(DatabaseConfig.FEATURE_DATATYPE_WARNING, datatypeWarning.booleanValue());
        if (skipOracleRecycleBinTables != null)
            config.setFeature(DatabaseConfig.FEATURE_SKIP_ORACLE_RECYCLEBIN_TABLES,
                    skipOracleRecycleBinTables.booleanValue());
        if (allowEmptyFields != null)
            config.setFeature(DatabaseConfig.FEATURE_ALLOW_EMPTY_FIELDS, allowEmptyFields.booleanValue());

        if (escapePattern != null) {
            config.setProperty(DatabaseConfig.PROPERTY_ESCAPE_PATTERN, escapePattern);
        }
        if (batchSize != null) {
            Integer batchSizeInteger = new Integer(batchSize);
            config.setProperty(DatabaseConfig.PROPERTY_BATCH_SIZE, batchSizeInteger);
        }
        if (fetchSize != null) {
            config.setProperty(DatabaseConfig.PROPERTY_FETCH_SIZE, new Integer(fetchSize));
        }

        // Setup data type factory
        if (this.dataTypeFactory != null) {
            try {
                IDataTypeFactory dataTypeFactory = (IDataTypeFactory) Class.forName(this.dataTypeFactory).newInstance();
                config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, dataTypeFactory);
            } catch (ClassNotFoundException e) {
                throw new BuildException("Class Not Found: DataType factory " + driver + " could not be loaded", e,
                        getLocation());
            } catch (IllegalAccessException e) {
                throw new BuildException("Illegal Access: DataType factory " + driver + " could not be loaded", e,
                        getLocation());
            } catch (InstantiationException e) {
                throw new BuildException("Instantiation Exception: DataType factory " + driver + " could not be loaded",
                        e, getLocation());
            }
        }

    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy