Clover coverage report -
Coverage timestamp: Thu Jun 22 2006 14:24:50 CEST
file stats: LOC: 189   Methods: 2
NCLOC: 90   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
BMTStatefulTransactionInterceptor.java 0% 0% 0% 0%
coverage
 1    /**
 2    * EasyBeans
 3    * Copyright (C) 2006 Bull S.A.S.
 4    * Contact: easybeans@objectweb.org
 5    *
 6    * This library is free software; you can redistribute it and/or
 7    * modify it under the terms of the GNU Lesser General Public
 8    * License as published by the Free Software Foundation; either
 9    * version 2.1 of the License, or any later version.
 10    *
 11    * This library is distributed in the hope that it will be useful,
 12    * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 14    * Lesser General Public License for more details.
 15    *
 16    * You should have received a copy of the GNU Lesser General Public
 17    * License along with this library; if not, write to the Free Software
 18    * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 19    * USA
 20    *
 21    * --------------------------------------------------------------------------
 22    * $Id: BMTStatefulTransactionInterceptor.java 450 2006-05-12 15:30:25Z benoitf $
 23    * --------------------------------------------------------------------------
 24    */
 25   
 26    package org.objectweb.easybeans.transaction.interceptors;
 27   
 28    import static javax.transaction.Status.STATUS_COMMITTED;
 29    import static javax.transaction.Status.STATUS_ROLLEDBACK;
 30   
 31    import javax.ejb.EJBException;
 32    import javax.transaction.InvalidTransactionException;
 33    import javax.transaction.SystemException;
 34    import javax.transaction.Transaction;
 35   
 36    import org.objectweb.easybeans.api.EasyBeansInvocationContext;
 37    import org.objectweb.easybeans.api.bean.EasyBeansSFSB;
 38    import org.objectweb.easybeans.container.session.EasyBeansSessionContext;
 39    import org.objectweb.easybeans.log.JLog;
 40    import org.objectweb.easybeans.log.JLogFactory;
 41   
 42    /**
 43    * Defines an interceptor for method that are in Bean managed mode and then in
 44    * Bean Managed Transaction : for a stateful bean.
 45    * @author Florent Benoit
 46    */
 47    public class BMTStatefulTransactionInterceptor extends AbsTransactionInterceptor {
 48   
 49    /**
 50    * Logger.
 51    */
 52    private JLog logger = JLogFactory.getLog(BMTStatefulTransactionInterceptor.class);
 53   
 54    /**
 55    * Constructor.<br> Acquire the transaction manager.
 56    */
 57  0 public BMTStatefulTransactionInterceptor() {
 58  0 super();
 59    }
 60   
 61    /**
 62    * Execute transaction as specified for BMT.
 63    * @param invocationContext context with useful attributes on the current
 64    * invocation
 65    * @return result of the next invocation (to chain interceptors)
 66    * @throws Exception if interceptor fails
 67    * @see <a href="http://www.jcp.org/en/jsr/detail?id=220">EJB 3.0
 68    * specification ?12.6.1</a>
 69    */
 70  0 @Override
 71    public Object intercept(final EasyBeansInvocationContext invocationContext) throws Exception {
 72  0 logger.debug("Calling BMT TX interceptor");
 73   
 74    // Get current transaction
 75  0 Transaction transaction;
 76  0 try {
 77  0 transaction = getTransactionManager().getTransaction();
 78    } catch (SystemException se) {
 79  0 throw new EJBException("Cannot get the current transaction on transaction manager.", se);
 80    }
 81   
 82  0 logger.debug("Transaction found = {0}", transaction);
 83   
 84    /*
 85    * When a client invokes a business method via one of the enterprise
 86    * bean's client view interfaces, the container suspends any transaction
 87    * that may be associated with the client request. If there is a
 88    * transaction associated with the instance (this would happen if a
 89    * stateful session bean instance started the transaction in some
 90    * previous business method), the container associates the method
 91    * execution with this transaction. If there are interceptor methods
 92    * associated with the bean instances, these actions are taken before
 93    * the interceptor methods are invoked.
 94    */
 95   
 96  0 Transaction suspendedTransaction = null;
 97  0 if (transaction != null) {
 98  0 try {
 99  0 logger.debug("Suspending transaction {0}", transaction);
 100  0 suspendedTransaction = getTransactionManager().suspend();
 101    } catch (SystemException se) {
 102  0 throw new EJBException("Cannot call suspend() on the transaction manager.", se);
 103    }
 104    }
 105   
 106    /*
 107    * In the case of a stateful session bean, it is possible that the
 108    * business method that started a transaction completes without
 109    * committing or rolling back the transaction. In such a case, the
 110    * container must retain the association between the transaction and the
 111    * instance across multiple client calls until the instance commits or
 112    * rolls back the transaction. When the client invokes the next business
 113    * method, the container must invoke the business method (and any
 114    * applicable interceptor methods for the bean) in this transaction
 115    * context.
 116    */
 117   
 118    // Get Bean and context
 119  0 EasyBeansSFSB statefulBean = (EasyBeansSFSB) invocationContext.getTarget();
 120  0 EasyBeansSessionContext sessionContext = statefulBean.getEasyBeansSessionContext();
 121    // Get bean transaction (if any)
 122  0 Transaction beanTransaction = sessionContext.getBeanTransaction();
 123    // resume transaction for the call
 124  0 if (beanTransaction != null) {
 125  0 try {
 126  0 getTransactionManager().resume(beanTransaction);
 127    } catch (InvalidTransactionException ite) {
 128  0 throw new EJBException(
 129    "Cannot call resume() on the previous bean transaction. There is an invalid transaction", ite);
 130    } catch (IllegalStateException ise) {
 131  0 throw new EJBException(
 132    "Cannot call resume() on the previous bean transaction. There is another associated transaction",
 133    ise);
 134    } catch (SystemException se) {
 135  0 throw new EJBException(
 136    "Cannot call resume() on the previous bean transaction. Unexpected error condition", se);
 137    }
 138    }
 139   
 140  0 try {
 141  0 return invocationContext.proceed();
 142    } finally {
 143   
 144    /*
 145    * Saves the current bean transaction if the business method that
 146    * started a transaction completes without committing or rolling
 147    * back the transaction.
 148    */
 149  0 Transaction transactionAfter = null;
 150  0 try {
 151  0 transactionAfter = getTransactionManager().getTransaction();
 152    } catch (SystemException se) {
 153  0 throw new EJBException("Cannot get the current transaction on transaction manager.", se);
 154    }
 155  0 if (transactionAfter != null) {
 156  0 int transactionStatus = transactionAfter.getStatus();
 157    // not yet committed or rollbacked --> save transaction for the next call.
 158  0 if (transactionStatus != STATUS_COMMITTED && transactionStatus != STATUS_ROLLEDBACK) {
 159  0 sessionContext.setBeanTransaction(transactionAfter);
 160    } else {
 161  0 sessionContext.setBeanTransaction(null);
 162    }
 163    }
 164   
 165    /*
 166    * The container resumes the suspended association when the business
 167    * method has completed.
 168    */
 169  0 if (suspendedTransaction != null) {
 170   
 171  0 logger.debug("Resuming transaction {0}", transaction);
 172   
 173  0 try {
 174  0 getTransactionManager().resume(suspendedTransaction);
 175    } catch (InvalidTransactionException ite) {
 176  0 throw new EJBException(
 177    "Cannot call resume() on the given transaction. There is an invalid transaction", ite);
 178    } catch (IllegalStateException ise) {
 179  0 throw new EJBException(
 180    "Cannot call resume() on the given transaction. There is another associated transaction",
 181    ise);
 182    } catch (SystemException se) {
 183  0 throw new EJBException("Cannot call resume() on the given transaction. Unexpected error condition",
 184    se);
 185    }
 186    }
 187    }
 188    }
 189    }