My implementation of the Beanfactory
Code:
package test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
public class TestDataSourceFactory implements FactoryBean {
private static Logger logger = Logger.getLogger(TestDataSourceFactory.class);
// Spring properties
private String testDatabaseName;
private Resource schemaLocation;
private Resource testDataLocation;
private DataSource dataSource;
public void setTestDatabaseName(String testDatabaseName) {
this.testDatabaseName = testDatabaseName;
}
public void setSchemaLocation(Resource schemaLocation) {
this.schemaLocation = schemaLocation;
}
public void setTestDataLocation(Resource testDataLocation) {
this.testDataLocation = testDataLocation;
}
// implementing FactoryBean
public Object getObject() throws Exception {
if (dataSource == null) {
initDataSource();
}
return dataSource;
}
@SuppressWarnings("unchecked")
public Class getObjectType() {
return DataSource.class;
}
public boolean isSingleton() {
return true;
}
private void initDataSource() {
// create datasource
this.dataSource = createDataSource();
if (logger.isDebugEnabled()) {
logger.debug("Created in-memory test database '" + testDatabaseName + "'");
}
// now populate the database by loading the schema and test data
populateDataSource();
if (logger.isDebugEnabled()) {
logger.debug("Exported schema in " + schemaLocation);
}
if (logger.isDebugEnabled()) {
logger.debug("Loaded test data in " + testDataLocation);
}
}
private DataSource createDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
// use the HsqlDB JDBC driver
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
// have it create an in-memory database
dataSource.setUrl("jdbc:hsqldb:mem:" + testDatabaseName);
dataSource.setUsername("sa");
dataSource.setPassword("");
dataSource.setConnectionProperties(
(Properties)new Properties().setProperty(
"shutdown", "true"));
return dataSource;
}
private void populateDataSource() {
TestDatabasePopulator populator = new TestDatabasePopulator(dataSource);
populator.populate();
}
private class TestDatabasePopulator {
private DataSource dataSource;
public TestDatabasePopulator(DataSource dataSource) {
this.dataSource = dataSource;
}
public void populate() {
Connection connection = null;
try {
connection = dataSource.getConnection();
if (schemaLocation != null) {
createDatabaseSchema(connection);
}
if (testDataLocation != null) {
insertTestData(connection);
}
} catch (SQLException e) {
throw new RuntimeException("SQL exception occurred acquiring connection", e);
} finally {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
}
}
}
}
// create the application's database schema (tables, indexes, etc.)
private void createDatabaseSchema(Connection connection) {
try {
String sql = parseSqlIn(schemaLocation);
executeSql(sql, connection);
} catch (IOException e) {
throw new RuntimeException("I/O exception occurred accessing the database schema file", e);
} catch (SQLException e) {
throw new RuntimeException("SQL exception occurred exporting database schema", e);
}
}
// populate the tables with test data
private void insertTestData(Connection connection) {
try {
String sql = parseSqlIn(testDataLocation);
executeSql(sql, connection);
} catch (IOException e) {
throw new RuntimeException("I/O exception occurred accessing the test data file", e);
} catch (SQLException e) {
throw new RuntimeException("SQL exception occurred loading test data", e);
}
}
// utility method to read a .sql txt input stream
private String parseSqlIn(Resource resource) throws IOException {
InputStream is = null;
String ret="";
try {
is = resource.getInputStream();
Reader reader = new InputStreamReader(is);
char[] cbuf = new char[4096];
while (reader.read(cbuf)!=-1){;
ret=ret+ new String(cbuf).trim();
cbuf=new char[4096];
}
return ret;
} finally {
if (is != null) {
is.close();
}
}
}
// utility method to run the parsed sql
private void executeSql(String sql, Connection connection) throws SQLException {
Statement statement = connection.createStatement();
statement.execute(sql);
}
}
}