package com.evasion.plugin.junit.persistence;
import java.net.URL;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import javax.sql.DataSource;
import javax.naming.Context;
import javax.naming.InitialContext;
import org.dbunit.database.DatabaseConfig;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.DatabaseDataSet;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.filter.ExcludeTableFilter;
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
import org.dbunit.ext.hsqldb.HsqldbDataTypeFactory;
import org.dbunit.operation.DatabaseOperation;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/*
* To change this template, choose Tools | Templates and open the template in
* the editor.
*/
/**
*
* @author sebastien.glon
*/
public abstract class AbstractPersistentTest {
private static boolean dataSourceFound;
private enum Database {
derby("Apache Derby"), hsql("HSQL Database Engine"), mysql("");
private String productName;
Database(String productName) {
this.productName = productName;
}
public String getProductName() {
return productName;
}
}
private static final Logger LOGGER =
LoggerFactory.getLogger(AbstractPersistentTest.class);
private static Database database;
private static DataSource datasource;
private IDatabaseConnection connection=null;
@BeforeClass
public static void initEntityManager() throws Exception {
Context ctx = new InitialContext();
datasource = ((DataSource) ctx.lookup("jdbc/__default"));
dataSourceFound = checkDatabase(datasource.getConnection().getMetaData());
}
@AfterClass
public static void afterClass() throws Exception {
datasource=null;
dataSourceFound=false;
System.gc();
}
private void openConnection() throws Exception {
connection = new DatabaseConnection(datasource.getConnection());
if (database == Database.hsql) {
DatabaseConfig config = connection.getConfig();
config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY,
new HsqldbDataTypeFactory());
}
}
private static boolean checkDatabase(DatabaseMetaData metaData) {
Database[] supportedDataBases = Database.values();
try {
LOGGER.debug("database product name: {}", metaData.getDatabaseProductName());
for (int i = 0; i < supportedDataBases.length; i++) {
Database database1 = supportedDataBases[i];
if (database1.getProductName().equalsIgnoreCase(
metaData.getDatabaseProductName())) {
database = database1;
return true;
}
}
} catch (SQLException ex) {
LOGGER.warn("Datasource non compatible ou non trouve.", ex);
}
database = null;
return false;
}
@Before
public void setUp() throws Exception {
openConnection();
// Initializes DBUnit
String dateFile = this.getClass().getSimpleName() + "-dataset.xml";
URL file = ClassLoader.getSystemResource(dateFile);
if (file != null) {
IDataSet dataset = new FlatXmlDataSetBuilder().build(file);
LOGGER.info("Dataset File: {}", dateFile);
DatabaseOperation.CLEAN_INSERT.execute(connection, dataset);
LOGGER.info("Dataset inserted.");
connection.getConnection().commit();
}
}
private void clearDataBase() throws Exception {
LOGGER.info("Clean Database except SEQUENCE table");
IDataSet dataset = new DatabaseDataSet(connection, false, new ExcludeTableFilter(new String[]{"SEQUENCE"}));
disableReferentialIntegrity(connection);
DatabaseOperation.DELETE_ALL.execute(connection, dataset);
enableReferentialIntegrity(connection);
connection.getConnection().commit();
}
@After
public void tearDown() throws Exception {
if (dataSourceFound) {
clearDataBase();
connection.close();
connection=null;
System.gc();
}
}
/**
* Override this method if you aren't using HSQL DB.
* <p/>
* Execute whatever statement is necessary to either defer or disable foreign
* key constraint checking on the given database connection, which is used by
* DBUnit to import datasets.
*
* @param con A DBUnit connection wrapper, which is used afterwards for dataset operations
*/
protected void disableReferentialIntegrity(IDatabaseConnection con) {
try {
if (database.equals(Database.hsql)) {
con.getConnection().prepareStatement(
"SET DATABASE REFERENTIAL INTEGRITY FALSE").execute(); // HSQL DB
} else if (database.equals(Database.mysql)) {
con.getConnection().prepareStatement(
"set foreign_key_checks=0").execute(); // MySQL > 4.1.1
}
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
/**
* Override this method if you aren't using HSQL DB.
* <p/>
* Execute whatever statement is necessary to enable integrity constraint checks after
* dataset operations.
*
* @param con A DBUnit connection wrapper, before it is used by the application again
*/
protected void enableReferentialIntegrity(IDatabaseConnection con) {
try {
if (database.equals(Database.hsql)) {
con.getConnection().prepareStatement(
"SET DATABASE REFERENTIAL INTEGRITY TRUE").execute(); // HSQL DB
} else if (database.equals(Database.mysql)) {
con.getConnection().prepareStatement(
"set foreign_key_checks=1").execute(); // MySQL > 4.1.1
}
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}