/* * 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() { } //-------------------------------------------------------------------------- }