package org.jfox.ejb.plugin;
import java.util.Iterator;
import javax.transaction.NotSupportedException;
import javax.transaction.Status;
import javax.transaction.TransactionRequiredException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import javax.ejb.SessionSynchronization;
import javax.ejb.EnterpriseBean;
import javax.ejb.EJBException;
import org.jfox.ejb.Bulk;
import org.jfox.ejb.Invocation;
import org.jfox.ejb.ContainerImpl;
import org.jfox.ejb.meta.SessionBeanDescriptor;
import org.jfox.ejb.meta.TransactionAttribute;
import org.jfox.ejb.EJBSynchronization;
public class T5_TransactionInvoker extends AbstractInvoker {
private static TransactionManager tm = ContainerImpl.getInstance().getTransactionManager();
public Object invokeBean(Bulk bulk, Invocation invocation, Iterator iter) throws Exception {
logger.debug("invokeBean " + bulk + ", " + invocation);
Transaction suspendedTrans = null;
SessionBeanDescriptor meta = (SessionBeanDescriptor)bulk.getEJBDescriptor();
EnterpriseBean bean = invocation.getBean();
boolean isSync = bean instanceof SessionSynchronization ? true : false;
if(isSync & meta.isStateless()) {
throw new EJBException("only stateful session bean can implement javax.ejb.SessionSynchronization.");
}
byte type = meta.getMethodTransactionAttribute(invocation.getMethod());
int status = tm.getStatus();
boolean created = false;
boolean toCommit = true;
try {
switch(type) {
case TransactionAttribute.TX_NOT_SUPPORTED: {
if(status != Status.STATUS_NO_TRANSACTION) {
suspendedTrans = tm.suspend();
}
break;
}
case TransactionAttribute.TX_SUPPORTS: {
break;
}
case TransactionAttribute.TX_REQUIRED: {
if(status == Status.STATUS_NO_TRANSACTION) {
tm.begin();
if(isSync){
EJBSynchronization ejbSync = new EJBSynchronization((SessionSynchronization)bean,tm.getTransaction());
ejbSync.afterBegin();
}
created = true;
}
break;
}
case TransactionAttribute.TX_REQUIRES_NEW: {
if(status != Status.STATUS_NO_TRANSACTION) {
suspendedTrans = tm.suspend();
}
tm.begin();
if(isSync){
EJBSynchronization ejbSync = new EJBSynchronization((SessionSynchronization)bean,tm.getTransaction());
tm.getTransaction().registerSynchronization(ejbSync);
ejbSync.afterBegin();
}
created = true;
break;
}
case TransactionAttribute.TX_MANDATORY: {
if(status == Status.STATUS_NO_TRANSACTION) {
throw new TransactionRequiredException("Transaction Required");
}
break;
}
case TransactionAttribute.TX_NEVER: {
if(status != Status.STATUS_NO_TRANSACTION) {
throw new NotSupportedException("Transaction Not Supported");
}
break;
}
}
return super.invokeBean(bulk, invocation, iter);
}
catch(Exception e){
toCommit = false;
throw e;
}
finally {
if(created == true) {
if(toCommit) {
tm.commit();
}
else {
tm.rollback();
}
}
else { if(toCommit == false && tm.getStatus() != Status.STATUS_NO_TRANSACTION) {
tm.getTransaction().setRollbackOnly();
}
}
if(suspendedTrans != null) {
tm.resume(suspendedTrans);
}
}
}
public static void main(String[] args) {
}
}