package org.rhq.test;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Hashtable;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.transaction.SystemException;
import javax.transaction.TransactionManager;
public class JPAUtils {
public static InitialContext getInitialContext() {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put("java.naming.factory.initial", "org.jnp.interfaces.LocalOnlyContextFactory");
env.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
try {
return new InitialContext(env);
} catch (NamingException e) {
throw new RuntimeException("Failed to load initial context", e);
}
}
public static EntityManager lookupEntityManager() {
try {
InitialContext initialContext = getInitialContext();
try {
return ((EntityManagerFactory) initialContext.lookup("java:/RHQEntityManagerFactory"))
.createEntityManager();
} finally {
initialContext.close();
}
} catch (NamingException e) {
throw new RuntimeException("Failed to load entity manager", e);
}
}
public static TransactionManager lookupTransactionManager() {
try {
InitialContext initialContext = getInitialContext();
try {
return (TransactionManager) initialContext.lookup("java:/TransactionManager");
} finally {
initialContext.close();
}
} catch (NamingException e) {
throw new RuntimeException("Failed to load transaction manager", e);
}
}
public static void executeInTransaction(TransactionCallback callback) {
TransactionManager tm = null;
try {
tm = lookupTransactionManager();
tm.begin();
callback.execute();
tm.commit();
} catch (Throwable t) {
RuntimeException re = new RuntimeException(getAllThrowableMessages(t), t);
try {
if (tm != null) {
tm.rollback();
}
} catch (SystemException e) {
throw new RuntimeException("Failed to rollback transaction ((" + getAllThrowableMessages(e)
+ ")) but there was a real cause before this - see cause for that", re);
}
re.printStackTrace();
throw re;
}
}
public static <T> T executeInTransaction(TransactionCallbackWithContext<T> callback) {
TransactionManager tm = null;
try {
tm = lookupTransactionManager();
tm.begin();
T results = callback.execute(tm, lookupEntityManager());
tm.commit();
return results;
} catch (Throwable t) {
RuntimeException re = new RuntimeException(getAllThrowableMessages(t), t);
try {
if (tm != null) {
tm.rollback();
}
} catch (SystemException e) {
throw new RuntimeException("Failed to rollback transaction ((" + getAllThrowableMessages(e)
+ ")) but there was a real cause before this - see cause for that", re);
}
re.printStackTrace();
throw re;
}
}
private static String getAllThrowableMessages(Throwable t) {
ArrayList<String> list = new ArrayList<String>();
if (t != null) {
String msg = t.getClass().getName() + ":" + t.getMessage();
if (t instanceof SQLException) {
msg += "[SQLException=" + getAllSqlExceptionMessages((SQLException) t) + "]";
}
list.add(msg);
while ((t.getCause() != null) && (t != t.getCause())) {
t = t.getCause();
msg = t.getClass().getName() + ":" + t.getMessage();
if (t instanceof SQLException) {
msg += "[SQLException=" + getAllSqlExceptionMessages((SQLException) t) + "]";
}
list.add(msg);
}
}
return list.toString();
}
private static String getAllSqlExceptionMessages(SQLException t) {
ArrayList<String> list = new ArrayList<String>();
if (t != null) {
list.add(t.getClass().getName() + ":" + t.getMessage());
while ((t.getNextException() != null) && (t != t.getNextException())) {
t = t.getNextException();
String msg = t.getClass().getName() + ":" + t.getMessage();
list.add(msg + "(error-code=" + t.getErrorCode() + ",sql-state=" + t.getSQLState() + ")");
}
}
return list.toString();
}
}