package com.adeptechllc.unitils.dbunit;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.unitils.core.TestListener;
import org.unitils.dbunit.DbUnitModule;
import org.unitils.dbunit.util.DbUnitDatabaseConnection;
/**
* This class extends the stock Unitils DbUnitModule to support schema creation
* before tests are run.
*
* It is intended to support in-memory databases, in particular hsqldb. This
* class should be registered in the unitils.properties file as follows:
*
* unitils.module.dbunit.className=com.adeptechllc.unitils.dbunit.InMemoryDbUnitModule
*
* The class allows you to provide the schema file name via the
* com.adeptechllc.dbunit.schemaFileName
property in the
* unitils.properties file, or assumes a default file name of
* "create_database.sql"
*
* This class is limited to support for a single schema at this time, and is
* sensitive to the "database.schemaNames" property in the unitils.properties
* file.
*
* @author Keith McMillan
*
*/
public class InMemoryDbUnitModule extends DbUnitModule {
private static final String DATABASE_SCHEMA_NAME = "database.schemaNames";
private static final String DEFAULT_SCHEMA_NAME = "PUBLIC";
private static final String SCHEMA_DEFAULT_FILENAME = "create_database.sql";
private static final String SCHEMA_FILENAME = "com.adeptechllc.dbunit.schemaFileName";
private boolean isInitialized = false;
/**
* @return The TestListener object that implements Unitils' DbUnit support
*/
@Override
public TestListener getTestListener() {
return new DbUnitListener();
}
public void initializeSchema() {
try {
String schemaName = configuration.getProperty(DATABASE_SCHEMA_NAME,
DEFAULT_SCHEMA_NAME);
DbUnitDatabaseConnection connection = getDbUnitDatabaseConnection(schemaName);
Statement statement = connection.getConnection().createStatement();
for (String tableString : getTableStatements())
{
statement.executeUpdate(tableString);
}
connection.close();
isInitialized = true;
} catch (SQLException sqle) {
System.err.println(sqle);
}
}
private List getTableStatements() {
List results = new ArrayList();
try {
String allTables = readFileAsString();
StringTokenizer st = new StringTokenizer(allTables, ";", false);
while (st.hasMoreTokens()) {
results.add(st.nextToken());
}
} catch (IOException ioe) {
ioe.printStackTrace(System.err);
}
return results;
}
private String readFileAsString() throws IOException {
InputStream input;
String filename = configuration.getProperty(SCHEMA_FILENAME, SCHEMA_DEFAULT_FILENAME);
input = getClass().getClassLoader().getResourceAsStream(filename);
if (input == null) {
System.err.println("schema filename " + filename + " not found: using default");
input = getClass().getClassLoader().getResourceAsStream(SCHEMA_DEFAULT_FILENAME);
}
BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(input));
StringBuilder stringBuilder = new StringBuilder();
String nextLine = bufferedReader.readLine();
while (nextLine != null) {
stringBuilder.append(nextLine.replaceAll("\t", ""));
nextLine = bufferedReader.readLine();
}
return stringBuilder.toString();
}
/**
*
* Test listener that is called while the test framework is running tests
*/
protected class DbUnitListener extends
org.unitils.dbunit.DbUnitModule.DbUnitListener {
@Override
public void beforeTestSetUp(Object testObject, Method testMethod) {
if (!isInitialized) {
initializeSchema();
}
super.beforeTestSetUp(testObject, testMethod);
}
}
}