Clover coverage report -
Coverage timestamp: Thu Jun 22 2006 14:24:50 CEST
file stats: LOC: 193   Methods: 2
NCLOC: 96   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
CMTRequiresNewTransactionInterceptor.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: CMTRequiresNewTransactionInterceptor.java 9 2006-02-19 18:53:32Z benoitf $
 23    * --------------------------------------------------------------------------
 24    */
 25   
 26    package org.objectweb.easybeans.transaction.interceptors;
 27   
 28    import static javax.transaction.Status.STATUS_ACTIVE;
 29    import static javax.transaction.Status.STATUS_MARKED_ROLLBACK;
 30   
 31    import javax.ejb.EJBException;
 32    import javax.ejb.TransactionRolledbackLocalException;
 33    import javax.transaction.InvalidTransactionException;
 34    import javax.transaction.NotSupportedException;
 35    import javax.transaction.RollbackException;
 36    import javax.transaction.SystemException;
 37    import javax.transaction.Transaction;
 38   
 39    import org.objectweb.easybeans.api.EasyBeansInvocationContext;
 40    import org.objectweb.easybeans.log.JLog;
 41    import org.objectweb.easybeans.log.JLogFactory;
 42   
 43    /**
 44    * Defines an interceptor for method using the REQUIRES_NEW attribute.
 45    * @author Florent Benoit
 46    */
 47    public class CMTRequiresNewTransactionInterceptor extends AbsTransactionInterceptor {
 48   
 49    /**
 50    * Logger.
 51    */
 52    private JLog logger = JLogFactory.getLog(CMTRequiresNewTransactionInterceptor.class);
 53   
 54   
 55    /**
 56    * Constructor.<br>
 57    * Acquire the transaction manager.
 58    */
 59  0 public CMTRequiresNewTransactionInterceptor() {
 60  0 super();
 61    }
 62   
 63    /**
 64    * Execute transaction as specified with the REQUIRES_NEW attribute.
 65    * @param invocationContext context with useful attributes on the current
 66    * invocation
 67    * @return result of the next invocation (to chain interceptors)
 68    * @throws Exception if interceptor fails
 69    * @see <a href="http://www.jcp.org/en/jsr/detail?id=220">EJB 3.0
 70    * specification ?12.6.2.4</a>
 71    */
 72  0 @Override
 73    public Object intercept(final EasyBeansInvocationContext invocationContext) throws Exception {
 74  0 logger.debug("Calling RequiresNew TX interceptor");
 75   
 76    // Get current transaction
 77  0 Transaction transaction;
 78  0 try {
 79  0 transaction = getTransactionManager().getTransaction();
 80    } catch (SystemException se) {
 81  0 throw new EJBException("Cannot get the current transaction on transaction manager.", se);
 82    }
 83   
 84  0 logger.debug("Transaction found = {0}", transaction);
 85   
 86   
 87    /*
 88    * If the client invokes the enterprise bean?s method while the client
 89    * is not associated with a transaction context, the container
 90    * automatically starts a new transaction before delegating a method
 91    * call to the enterprise bean business method. The container
 92    * automatically enlists all the resource managers accessed by the
 93    * business method with the transaction. If the business method invokes
 94    * other enterprise beans, the container passes the transaction context
 95    * with the invocation. The container attempts to commit the transaction
 96    * when the business method has completed. The container performs the
 97    * commit protocol before the method result is sent to the client.
 98    */
 99  0 boolean startedTransaction = false;
 100  0 Transaction suspendedTransaction = null;
 101  0 if (transaction == null) {
 102  0 try {
 103  0 getTransactionManager().begin();
 104  0 startedTransaction = true;
 105    } catch (NotSupportedException nse) {
 106  0 throw new EJBException("Transaction Manager implementation does not support nested transactions.", nse);
 107    } catch (SystemException se) {
 108  0 throw new EJBException("Cannot call begin() on the transaction manager.", se);
 109    }
 110    } else {
 111    /*
 112    * If a client calls with a transaction context, the container
 113    * suspends the association of the transaction context with the
 114    * current thread before starting the new transaction and invoking
 115    * the business method. The container resumes the suspended
 116    * transaction association after the business method and the new
 117    * transaction have been completed.
 118    */
 119  0 try {
 120  0 logger.debug("Suspending transaction {0}", transaction);
 121  0 suspendedTransaction = getTransactionManager().suspend();
 122    } catch (SystemException se) {
 123  0 throw new EJBException("Cannot call suspend() on the transaction manager.", se);
 124    }
 125    }
 126   
 127  0 try {
 128  0 return invocationContext.proceed();
 129    } finally {
 130   
 131    // only do some operations if transaction has been started before
 132    // invoking the method.
 133  0 if (startedTransaction) {
 134   
 135    // sanity check.
 136  0 Transaction transactionAfter = null;
 137  0 try {
 138  0 transactionAfter = getTransactionManager().getTransaction();
 139    } catch (SystemException se) {
 140  0 throw new EJBException("Cannot get the current transaction on transaction manager.", se);
 141    }
 142   
 143  0 if (transactionAfter == null) {
 144  0 throw new RuntimeException("Transaction disappeared.");
 145    }
 146   
 147    /*
 148    * The container attempts to commit the transaction when the
 149    * business method has completed. The container performs the
 150    * commit protocol before the method result is sent to the
 151    * client.
 152    */
 153  0 try {
 154  0 switch (getTransactionManager().getStatus()) {
 155  0 case STATUS_ACTIVE:
 156  0 getTransactionManager().commit();
 157  0 break;
 158  0 case STATUS_MARKED_ROLLBACK:
 159  0 getTransactionManager().rollback();
 160  0 break;
 161  0 default:
 162  0 throw new RuntimeException("Unexpected transaction status" + getTransactionManager().getStatus());
 163    }
 164    } catch (RollbackException e) {
 165  0 throw new TransactionRolledbackLocalException("Could not commit transaction", e);
 166    } catch (Exception e) {
 167  0 throw new EJBException("Container exception", e);
 168    }
 169    }
 170   
 171    // if it was suspended
 172  0 if (suspendedTransaction != null) {
 173   
 174  0 logger.debug("Resuming transaction {0}", transaction);
 175   
 176  0 try {
 177  0 getTransactionManager().resume(suspendedTransaction);
 178    } catch (InvalidTransactionException ite) {
 179  0 throw new EJBException(
 180    "Cannot call resume() on the given transaction. There is an invalid transaction", ite);
 181    } catch (IllegalStateException ise) {
 182  0 throw new EJBException(
 183    "Cannot call resume() on the given transaction. There is another associated transaction",
 184    ise);
 185    } catch (SystemException se) {
 186  0 throw new EJBException("Cannot call resume() on the given transaction. Unexpected error condition",
 187    se);
 188    }
 189    }
 190    }
 191    }
 192   
 193    }