/******************************************************************************* | |
* Copyright (c) 2005, 2009 SAP. All rights reserved. | |
* This program and the accompanying materials are made available under the | |
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 | |
* which accompanies this distribution. | |
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html | |
* and the Eclipse Distribution License is available at | |
* http://www.eclipse.org/org/documents/edl-v10.php. | |
* | |
* Contributors: | |
* SAP - initial API and implementation | |
******************************************************************************/ | |
package org.eclipse.persistence.testing.framework.wdf; | |
import java.io.ByteArrayInputStream; | |
import java.io.ByteArrayOutputStream; | |
import java.io.IOException; | |
import java.io.ObjectInputStream; | |
import java.io.ObjectOutputStream; | |
import java.io.Serializable; | |
import java.lang.reflect.InvocationTargetException; | |
import java.lang.reflect.Method; | |
import java.sql.Connection; | |
import java.sql.DatabaseMetaData; | |
import java.sql.ResultSet; | |
import java.sql.SQLException; | |
import java.sql.Statement; | |
import java.util.HashMap; | |
import java.util.HashSet; | |
import java.util.Hashtable; | |
import java.util.Locale; | |
import java.util.Map; | |
import java.util.Properties; | |
import java.util.Set; | |
import javax.naming.Context; | |
import javax.naming.InitialContext; | |
import javax.naming.NamingException; | |
import javax.persistence.EntityManager; | |
import javax.persistence.EntityManagerFactory; | |
import javax.persistence.LockModeType; | |
import javax.persistence.Persistence; | |
import javax.sql.DataSource; | |
import org.eclipse.persistence.config.PersistenceUnitProperties; | |
import org.eclipse.persistence.testing.framework.junit.JUnitTestCaseHelper; | |
import org.eclipse.persistence.testing.framework.server.JEEPlatform; | |
import org.eclipse.persistence.testing.framework.server.ServerPlatform; | |
import org.eclipse.persistence.testing.tests.feature.TestDataSource; | |
import org.junit.Assert; | |
import org.junit.Before; | |
import org.junit.runner.RunWith; | |
import org.junit.runners.Parameterized.Parameters; | |
@SuppressWarnings("unchecked") | |
@RunWith(SkipBugzillaTestRunner.class) | |
public abstract class AbstractBaseTest { | |
// /** System variable to set the tests to run on the server. */ | |
// public static final String RUN_ON_SERVER = "server.run"; | |
// | |
private static Map<String, EntityManagerFactory> emfNamedPersistenceUnits = new Hashtable<String, EntityManagerFactory>(); | |
/** Determine if the test is running on a JEE server, or in JSE. */ | |
private static ServerPlatform serverPlatform; | |
private final JPAEnvironment environment; | |
private final String puName; | |
private final static DataSource dataSource; | |
protected final static Map EMF_PROPERTIES; | |
private static boolean seesJPA2 = (LockModeType.values().length > 2); | |
static { | |
final DataSource aDataSource; | |
if (!ServerInfoHolder.isOnServer()) { | |
Map<String, String> properties = JUnitTestCaseHelper.getDatabaseProperties(); | |
String driver = properties.get(PersistenceUnitProperties.JDBC_DRIVER); | |
String url = properties.get(PersistenceUnitProperties.JDBC_URL); | |
String user = properties.get(PersistenceUnitProperties.JDBC_USER); | |
String password = properties.get(PersistenceUnitProperties.JDBC_PASSWORD); | |
Properties userPasswd = new Properties(); | |
userPasswd.put("user", user); | |
userPasswd.put("password", password); | |
DataSource ds = new TestDataSource(driver, url, userPasswd); | |
aDataSource = new PooledDataSource(ds); | |
} else { | |
Context context; | |
try { | |
context = new InitialContext(); | |
aDataSource = (DataSource) context.lookup(ServerInfoHolder.getDataSourceName()); | |
} catch (NamingException e) { | |
throw new RuntimeException(e); | |
} | |
} | |
dataSource = aDataSource; | |
EMF_PROPERTIES = new HashMap(); | |
EMF_PROPERTIES.put("delimited-identifiers", "true"); | |
EMF_PROPERTIES.put(PersistenceUnitProperties.NON_JTA_DATASOURCE, dataSource); | |
} | |
public AbstractBaseTest(String name) { | |
environment = new ResourceLocalEnvironment(); | |
puName = name; | |
} | |
protected final JPAEnvironment getEnvironment() { | |
return environment; | |
} | |
@Parameters | |
public static void parameters() { | |
} | |
final class ResourceLocalEnvironment implements JPAEnvironment { | |
@Override | |
public void beginTransaction(EntityManager em) { | |
em.getTransaction().begin(); | |
} | |
@Override | |
public void commitTransaction(EntityManager em) { | |
em.getTransaction().commit(); | |
} | |
@Override | |
public void commitTransactionAndClear(EntityManager em) { | |
try { | |
commitTransaction(em); | |
} finally { | |
em.clear(); | |
} | |
} | |
@Override | |
public EntityManagerFactory createNewEntityManagerFactory() throws NamingException { | |
AbstractBaseTest.closeEntityManagerFactory(puName); | |
return Persistence.createEntityManagerFactory(puName, EMF_PROPERTIES); | |
} | |
@Override | |
public EntityManager getEntityManager() { | |
return getEntityManagerFactory().createEntityManager(); | |
// return AbstractBaseTest.createEntityManager(puName, | |
// EMF_PROPERTIES); | |
} | |
@Override | |
public EntityManagerFactory getEntityManagerFactory() { | |
return AbstractBaseTest.getEntityManagerFactory(puName, EMF_PROPERTIES); | |
} | |
@Override | |
public boolean isTransactionActive(EntityManager em) { | |
return em.getTransaction().isActive(); | |
} | |
@Override | |
public boolean isTransactionMarkedForRollback(EntityManager em) { | |
return em.getTransaction().getRollbackOnly(); | |
} | |
@Override | |
public void markTransactionForRollback(EntityManager em) { | |
em.getTransaction().setRollbackOnly(); | |
} | |
@Override | |
public void rollbackTransaction(EntityManager em) { | |
em.getTransaction().rollback(); | |
} | |
@Override | |
public void rollbackTransactionAndClear(EntityManager em) { | |
try { | |
rollbackTransaction(em); | |
} finally { | |
em.clear(); | |
} | |
} | |
@Override | |
public boolean usesExtendedPC() { | |
return true; | |
} | |
@Override | |
public DataSource getDataSource() { | |
return AbstractBaseTest.this.getDataSource(); | |
} | |
@Override | |
public EntityManagerFactory createNewEntityManagerFactory(Map properties) throws NamingException { | |
Map mergedProperties = new HashMap(); | |
mergedProperties.putAll(EMF_PROPERTIES); | |
mergedProperties.putAll(properties); | |
AbstractBaseTest.closeEntityManagerFactory(puName); | |
return Persistence.createEntityManagerFactory(puName, mergedProperties); | |
} | |
@Override | |
public Object getPropertyValue(EntityManager em, String key) { | |
Object delegate = em.getDelegate(); | |
Method getEntityManagerFactoryMethod; | |
try { | |
getEntityManagerFactoryMethod = delegate.getClass().getMethod("getEntityManagerFactory"); | |
Object emf = getEntityManagerFactoryMethod.invoke(delegate); | |
Method getPropertiesMethod = emf.getClass().getMethod("getProperties"); | |
@SuppressWarnings("rawtypes") | |
Map map = (Map) getPropertiesMethod.invoke(emf); | |
return map.get(key); | |
} catch (NoSuchMethodException e) { | |
throw new RuntimeException(e); | |
} catch (IllegalArgumentException e) { | |
throw new RuntimeException(e); | |
} catch (IllegalAccessException e) { | |
throw new RuntimeException(e); | |
} catch (InvocationTargetException e) { | |
throw new RuntimeException(e); | |
} | |
} | |
@Override | |
public void evict(EntityManager em, Class<?> clazz) { | |
Object delegate = em.getDelegate(); | |
Method getEntityManagerFactoryMethod; | |
try { | |
getEntityManagerFactoryMethod = delegate.getClass().getMethod("getEntityManagerFactory"); | |
Object emf = getEntityManagerFactoryMethod.invoke(delegate); | |
Method getCacheMethod = emf.getClass().getMethod("getCache"); | |
Object cache = getCacheMethod.invoke(emf); | |
Method evictClassMethod = cache.getClass().getMethod("evict", Class.class); | |
evictClassMethod.invoke(cache, clazz); | |
} catch (NoSuchMethodException e) { | |
throw new RuntimeException(e); | |
} catch (IllegalArgumentException e) { | |
throw new RuntimeException(e); | |
} catch (IllegalAccessException e) { | |
throw new RuntimeException(e); | |
} catch (InvocationTargetException e) { | |
throw new RuntimeException(e); | |
} | |
} | |
@Override | |
public void evictAll(EntityManager em) { | |
Object delegate = em.getDelegate(); | |
Method getEntityManagerFactoryMethod; | |
try { | |
getEntityManagerFactoryMethod = delegate.getClass().getMethod("getEntityManagerFactory"); | |
Object emf = getEntityManagerFactoryMethod.invoke(delegate); | |
Method getCacheMethod = emf.getClass().getMethod("getCache"); | |
Object cache = getCacheMethod.invoke(emf); | |
Method evictClassMethod = cache.getClass().getMethod("evictAll", new Class[]{}); | |
evictClassMethod.invoke(cache, new Object[]{}); | |
} catch (NoSuchMethodException e) { | |
throw new RuntimeException(e); | |
} catch (IllegalArgumentException e) { | |
throw new RuntimeException(e); | |
} catch (IllegalAccessException e) { | |
throw new RuntimeException(e); | |
} catch (InvocationTargetException e) { | |
throw new RuntimeException(e); | |
} | |
} | |
} | |
final class JTATxScopedEnvironment implements JPAEnvironment { | |
@Override | |
public void beginTransaction(EntityManager em) { | |
AbstractBaseTest.this.beginTransaction(em); | |
} | |
@Override | |
public void commitTransaction(EntityManager em) { | |
AbstractBaseTest.this.commitTransaction(em); | |
} | |
@Override | |
public void commitTransactionAndClear(EntityManager em) { | |
try { | |
commitTransaction(em); | |
} finally { | |
em.clear(); | |
} | |
} | |
@Override | |
public EntityManagerFactory createNewEntityManagerFactory() throws NamingException { | |
AbstractBaseTest.closeEntityManagerFactory(puName); | |
return Persistence.createEntityManagerFactory(puName, EMF_PROPERTIES); | |
} | |
@Override | |
public EntityManager getEntityManager() { | |
return AbstractBaseTest.createEntityManager(puName, EMF_PROPERTIES); | |
} | |
@Override | |
public EntityManagerFactory getEntityManagerFactory() { | |
return AbstractBaseTest.getEntityManagerFactory(puName, EMF_PROPERTIES); | |
} | |
@Override | |
public boolean isTransactionActive(EntityManager em) { | |
return AbstractBaseTest.this.isTransactionActive(em); | |
} | |
@Override | |
public boolean isTransactionMarkedForRollback(EntityManager em) { | |
return AbstractBaseTest.this.getRollbackOnly(em); | |
} | |
@Override | |
public void markTransactionForRollback(EntityManager em) { | |
throw new UnsupportedOperationException(); | |
} | |
@Override | |
public void rollbackTransaction(EntityManager em) { | |
AbstractBaseTest.this.rollbackTransaction(em); | |
} | |
@Override | |
public void rollbackTransactionAndClear(EntityManager em) { | |
try { | |
rollbackTransaction(em); | |
} finally { | |
em.clear(); | |
} | |
} | |
@Override | |
public boolean usesExtendedPC() { | |
return true; | |
} | |
@Override | |
public DataSource getDataSource() { | |
return AbstractBaseTest.this.getDataSource(); | |
} | |
@Override | |
public EntityManagerFactory createNewEntityManagerFactory(Map<String, Object> properties) throws NamingException { | |
throw new UnsupportedOperationException(); | |
} | |
@Override | |
public Object getPropertyValue(EntityManager em, String key) { | |
throw new UnsupportedOperationException(); | |
} | |
@Override | |
public void evict(EntityManager em, Class<?> clazz) { | |
throw new UnsupportedOperationException(); | |
} | |
@Override | |
public void evictAll(EntityManager em) { | |
throw new UnsupportedOperationException(); | |
} | |
} | |
public DataSource getDataSource() { | |
return dataSource; | |
} | |
final public void closeEntityManager(EntityManager em) { | |
if (!em.isOpen()) { | |
return; | |
} | |
if (environment.isTransactionActive(em)/* | |
* ||environment. | |
* isTransactionMarkedForRollback | |
* (em) | |
*/) { // FIXME discuss if tx is | |
// active if marked for | |
// rollback | |
environment.rollbackTransaction(em); | |
} | |
// // close application-managed entity manager | |
// if (!(getEnvironment() instanceof JTASharedPCEnvironment)) { | |
// em.close(); FIXME | |
// } | |
} | |
protected static void verify(boolean condition, String string) { | |
Assert.assertTrue(string, condition); | |
} | |
protected final void flop(final String msg) { | |
Assert.fail(msg); | |
} | |
abstract protected String[] getClearableTableNames(); | |
@Before | |
public void clearAllTablesAndSetup() throws SQLException { | |
clearAllTables(); | |
setup(); | |
} | |
protected void clearAllTables() throws SQLException { | |
Connection conn = getDataSource().getConnection(); | |
try { | |
conn.setAutoCommit(false); | |
Set<String> existingTables = new HashSet<String>(); | |
DatabaseMetaData metaData = conn.getMetaData(); | |
ResultSet rs = metaData.getTables(null, null, "TMP_%", null); | |
try { | |
while (rs.next()) { | |
existingTables.add(rs.getString("TABLE_NAME").toUpperCase(Locale.ENGLISH)); | |
} | |
} finally { | |
rs.close(); | |
} | |
Statement statement = conn.createStatement(); | |
try { | |
if (existingTables.contains("TMP_CASC_NODE")) { | |
statement.executeUpdate("update TMP_CASC_NODE set PARENT = null"); | |
} | |
if (existingTables.contains("TMP_NODE")) { | |
statement.executeUpdate("update TMP_NODE set PARENT = null"); | |
} | |
if (existingTables.contains("TMP_COP")) { | |
statement.executeUpdate("update TMP_COP set PARTNER_ID = null"); | |
} | |
if (existingTables.contains("TMP_UCOFFICE_CUBICLE")) { | |
statement.executeUpdate("delete from TMP_UCOFFICE_CUBICLE"); | |
existingTables.remove("TMP_UCOFFICE_CUBICLE"); | |
} | |
for (String name : getClearableTableNames()) { | |
if (existingTables.contains(name.toUpperCase(Locale.ENGLISH))) { | |
statement.executeUpdate("delete from " + name); | |
} | |
} | |
} catch (SQLException ex) { | |
System.err.println(ex.getMessage()); | |
throw ex; | |
} finally { | |
statement.close(); | |
} | |
conn.commit(); | |
} finally { | |
conn.close(); | |
} | |
// TODO evictAll | |
} | |
/** | |
* intended to be overwritten by subclasses | |
*/ | |
protected void setup() throws SQLException { | |
} | |
public static final <T extends Serializable> T serializeDeserialize(T serializable) throws IOException, ClassNotFoundException { | |
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |
ObjectOutputStream objectOutputStream = new ObjectOutputStream(out); | |
try { | |
objectOutputStream.writeObject(serializable); | |
} finally { | |
objectOutputStream.close(); | |
} | |
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); | |
return (T) new ObjectInputStream(in).readObject(); | |
} | |
public static boolean isInsideEngine() { | |
return false; | |
} | |
/** | |
* Checks whether the given throwable is of type | |
* java.lang.IllegalStateException, or otherwise if the throwable contains a | |
* java.lang.IllegalStateException somewhere in the cause stack. | |
* | |
* @param e | |
* The throwable to check | |
* @return <code>true</code> if the throwable is instance of or caused by | |
* java.lang.IllegalStateException | |
*/ | |
protected final boolean checkForIllegalStateException(Throwable e) { | |
boolean contained = false; | |
while (e != null) { | |
if (e instanceof IllegalStateException) { | |
contained = true; | |
break; | |
} | |
e = e.getCause(); | |
} | |
return contained; | |
} | |
/** | |
* Checks whether the given throwable is of type java.sql.SQLException, or | |
* otherwise if the throwable contains a java.sql.SQLException somewhere in | |
* the cause stack. | |
* | |
* @param e | |
* The throwable to check | |
* @return <code>true</code> if the throwable is instance of or caused by | |
* java.sql.SQLException | |
*/ | |
protected final boolean checkForSQLException(Throwable e) { | |
boolean contained = false; | |
while (e != null) { | |
if (e instanceof SQLException) { | |
contained = true; | |
break; | |
} | |
e = e.getCause(); | |
} | |
return contained; | |
} | |
/** | |
* Return if the transaction is active. This allows the same code to be used | |
* on the server where JTA is used. | |
*/ | |
public boolean isTransactionActive(EntityManager entityManager) { | |
if (ServerInfoHolder.isOnServer()) { | |
return getServerPlatform().isTransactionActive(); | |
} else { | |
return entityManager.getTransaction().isActive(); | |
} | |
} | |
/** | |
* Return if the transaction is roll back only. This allows the same code to | |
* be used on the server where JTA is used. | |
*/ | |
public boolean getRollbackOnly(EntityManager entityManager) { | |
if (ServerInfoHolder.isOnServer()) { | |
return getServerPlatform().getRollbackOnly(); | |
} else { | |
return entityManager.getTransaction().getRollbackOnly(); | |
} | |
} | |
/** | |
* Begin a transaction on the entity manager. This allows the same code to | |
* be used on the server where JTA is used. | |
*/ | |
public void beginTransaction(EntityManager entityManager) { | |
if (ServerInfoHolder.isOnServer()) { | |
getServerPlatform().beginTransaction(); | |
} else { | |
entityManager.getTransaction().begin(); | |
} | |
} | |
/** | |
* Commit a transaction on the entity manager. This allows the same code to | |
* be used on the server where JTA is used. | |
*/ | |
public void commitTransaction(EntityManager entityManager) { | |
if (ServerInfoHolder.isOnServer()) { | |
getServerPlatform().commitTransaction(); | |
} else { | |
entityManager.getTransaction().commit(); | |
} | |
} | |
/** | |
* Rollback a transaction on the entity manager. This allows the same code | |
* to be used on the server where JTA is used. | |
*/ | |
public void rollbackTransaction(EntityManager entityManager) { | |
if (ServerInfoHolder.isOnServer()) { | |
getServerPlatform().rollbackTransaction(); | |
} else { | |
entityManager.getTransaction().rollback(); | |
} | |
} | |
/** | |
* Return the server platform if running in JEE. | |
*/ | |
public static ServerPlatform getServerPlatform() { | |
if (serverPlatform == null) { | |
serverPlatform = new JEEPlatform(); | |
} | |
return serverPlatform; | |
} | |
/** | |
* Create a new entity manager for the "default" persistence unit. If in JEE | |
* this will create or return the active managed entity manager. | |
*/ | |
public static EntityManager createEntityManager() { | |
if (ServerInfoHolder.isOnServer()) { | |
return getServerPlatform().getEntityManager("default"); | |
} else { | |
return getEntityManagerFactory().createEntityManager(); | |
} | |
} | |
/** | |
* Create a new entity manager for the persistence unit using the | |
* properties. The properties will only be used the first time this entity | |
* manager is accessed. If in JEE this will create or return the active | |
* managed entity manager. | |
*/ | |
public static EntityManager createEntityManager(String persistenceUnitName, Map<String, String> properties) { | |
if (ServerInfoHolder.isOnServer()) { | |
return getServerPlatform().getEntityManager(persistenceUnitName); | |
} else { | |
return getEntityManagerFactory(persistenceUnitName, properties).createEntityManager(); | |
} | |
} | |
public static EntityManagerFactory getEntityManagerFactory(String persistenceUnitName) { | |
return getEntityManagerFactory(persistenceUnitName, JUnitTestCaseHelper.getDatabaseProperties()); | |
} | |
public static EntityManagerFactory getEntityManagerFactory(String persistenceUnitName, Map<String, String> properties) { | |
if (ServerInfoHolder.isOnServer()) { | |
return getServerPlatform().getEntityManagerFactory(persistenceUnitName); | |
} else { | |
EntityManagerFactory emfNamedPersistenceUnit = (EntityManagerFactory) emfNamedPersistenceUnits.get(persistenceUnitName); | |
if (emfNamedPersistenceUnit == null) { | |
emfNamedPersistenceUnit = Persistence.createEntityManagerFactory(persistenceUnitName, properties); | |
emfNamedPersistenceUnits.put(persistenceUnitName, emfNamedPersistenceUnit); | |
} | |
return emfNamedPersistenceUnit; | |
} | |
} | |
public static EntityManagerFactory getEntityManagerFactory() { | |
return getEntityManagerFactory("default"); | |
} | |
public static void closeEntityManagerFactory() { | |
closeEntityManagerFactory("default"); | |
} | |
public static void closeEntityManagerFactory(String persistenceUnitName) { | |
EntityManagerFactory emfNamedPersistenceUnit = (EntityManagerFactory) emfNamedPersistenceUnits.get(persistenceUnitName); | |
if (emfNamedPersistenceUnit != null) { | |
if (emfNamedPersistenceUnit.isOpen()) { | |
emfNamedPersistenceUnit.close(); | |
} | |
emfNamedPersistenceUnits.remove(persistenceUnitName); | |
} | |
} | |
public static boolean seesJPA2() { | |
return seesJPA2; | |
} | |
public static Map<String, String> getTestProperties() { | |
if (ServerInfoHolder.isOnServer()) { | |
return ServerInfoHolder.getTestProperties(); | |
} else { | |
return JUnitTestCaseHelper.getDatabaseProperties(); | |
} | |
} | |
} |