/*
* Copyright 2010 Ralf Joachim
*
* Licensed 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.castor.cpa.test.framework;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.castor.cpa.test.framework.xml.types.DatabaseEngineType;
/**
* Execute create and drop DDL scripts of CPA test framework.
*
* @author <a href="mailto:ralf DOT joachim AT syscon DOT eu">Ralf Joachim</a>
* @version $Revision$ $Date: 2006-04-25 15:08:23 -0600 (Tue, 25 Apr 2006) $
*/
public final class CPAScriptExecutor {
//--------------------------------------------------------------------------
private static final String MODULE_PREFIX = "cpactf/";
private static final String MODULE_PATH = "src/test/ddl/";
private static final String DOT = ".";
private static final String SEPARATOR = "/";
private static final String DROP_FILE = "-drop";
private static final String CREATE_FILE = "-create";
private static final String FILE_EXTENSION = ".sql";
private static final String COMMENT = "--";
private static final String DELIMITER_DEFAULT = ";";
private static final String DELIMITER_ORACLE = "/";
private static final String DELIMITER_SAPDB = "//";
private static final String DELIMITER_MSSQL = "GO";
/** The <a href="http://jakarta.apache.org/commons/logging/">Jakarta
* Commons Logging</a> instance used for all logging. */
private static final Log LOG = LogFactory.getLog(CPAScriptExecutor.class);
//--------------------------------------------------------------------------
public static void execute(final DatabaseEngineType engine, final Connection connection,
final String test) {
String path = MODULE_PATH + test.replace(DOT, SEPARATOR) + SEPARATOR;
if (!new File(path).exists()) {
path = MODULE_PREFIX + path;
}
String dropFileName = path + engine.toString() + DROP_FILE + FILE_EXTENSION;
File dropFile = new File(dropFileName);
try {
List<String> dropScripts = parse(new FileReader(dropFile), engine);
executeDrop(dropScripts, connection);
LOG.info("Drop script for '" + test + "' executed.");
} catch (SQLException ex) {
if (LOG.isDebugEnabled()) {
LOG.debug("Drop script for '" + test + "' failed.", ex);
} else {
LOG.info("Drop script for '" + test + "' failed.");
}
} catch (FileNotFoundException ex) {
String msg = "Drop script for '" + test + "' not found.";
throw new IllegalStateException(msg);
} catch (IOException ex) {
String msg = "Drop script for '" + test + "' could not be read.";
throw new IllegalStateException(msg);
}
String createFileName = path + engine.toString() + CREATE_FILE + FILE_EXTENSION;
File createFile = new File(createFileName);
try {
List<String> createScripts = parse(new FileReader(createFile), engine);
executeCreate(createScripts, connection);
LOG.info("Create script for '" + test + "' executed.");
} catch (SQLException ex) {
String msg = "Create script for '" + test + "' failed.";
throw new IllegalStateException(msg, ex);
} catch (FileNotFoundException ex) {
String msg = "Create script for '" + test + "' not found.";
throw new IllegalStateException(msg);
} catch (IOException ex) {
String msg = "Create script for '" + test + "' could not be read.";
throw new IllegalStateException(msg);
}
}
private static void executeDrop(final List<String> statements, final Connection connection)
throws SQLException {
SQLException firstException = null;
for (Iterator<String> iter = statements.iterator(); iter.hasNext(); ) {
String statement = iter.next();
Statement sql = null;
try {
sql = connection.createStatement();
sql.executeUpdate(statement);
} catch (SQLException ex) {
// just remember first exceptions on failing statements of drop script
if (firstException == null) {
firstException = ex;
}
} finally {
if (sql != null) {
sql.close();
}
}
}
if (firstException != null) { throw firstException; }
}
private static void executeCreate(final List<String> statements, final Connection connection)
throws SQLException {
Statement sql = null;
try {
for (Iterator<String> iter = statements.iterator(); iter.hasNext(); ) {
String statement = iter.next();
sql = connection.createStatement();
sql.executeUpdate(statement);
sql.close();
sql = null;
}
} finally {
if (sql != null) {
sql.close();
}
}
}
public static List<String> parse(final Reader reader, final DatabaseEngineType engine)
throws IOException {
List<String> list = new ArrayList<String>();
String delimiter = getStatementDelimiter(engine);
StringBuilder builder = new StringBuilder();
BufferedReader buffer = new BufferedReader(reader);
String line = buffer.readLine();
while (line != null) {
String trim = line.trim();
if ((trim.length() != 0) && !line.startsWith(COMMENT)) {
if (trim.toUpperCase().endsWith(delimiter)) {
builder.append(trim.substring(0, trim.length() - delimiter.length()));
list.add(builder.toString());
builder = new StringBuilder();
} else {
builder.append(trim);
builder.append(' ');
}
}
line = buffer.readLine();
}
return list;
}
private static String getStatementDelimiter(final DatabaseEngineType engine) {
if (engine == DatabaseEngineType.ORACLE) {
return DELIMITER_ORACLE;
} else if (engine == DatabaseEngineType.SAPDB) {
return DELIMITER_SAPDB;
} else if (engine == DatabaseEngineType.SQL_SERVER) {
return DELIMITER_MSSQL;
} else if (engine == DatabaseEngineType.SYBASE) {
return DELIMITER_MSSQL;
} else {
return DELIMITER_DEFAULT;
}
}
//--------------------------------------------------------------------------
/**
* Hide default constructor of utility class.
*/
private CPAScriptExecutor() { }
//--------------------------------------------------------------------------
}