KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > easybeans > transaction > interceptors > BMTStatefulTransactionInterceptor


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 1121 2006-09-27 08:51:06Z benoitf $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.easybeans.transaction.interceptors;
27
28 import static javax.transaction.Status.STATUS_COMMITTED JavaDoc;
29 import static javax.transaction.Status.STATUS_ROLLEDBACK JavaDoc;
30
31 import javax.ejb.EJBException JavaDoc;
32 import javax.transaction.InvalidTransactionException JavaDoc;
33 import javax.transaction.SystemException JavaDoc;
34 import javax.transaction.Transaction JavaDoc;
35
36 import org.objectweb.easybeans.api.EasyBeansInvocationContext;
37 import org.objectweb.easybeans.api.bean.EasyBeansSFSB;
38 import org.objectweb.easybeans.api.container.EZBSessionContext;
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     public BMTStatefulTransactionInterceptor() {
58         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     @Override JavaDoc
71     public Object JavaDoc intercept(final EasyBeansInvocationContext invocationContext) throws Exception JavaDoc {
72         logger.debug("Calling BMT TX interceptor");
73
74         // Get current transaction
75
Transaction JavaDoc transaction;
76         try {
77             transaction = getTransactionManager().getTransaction();
78         } catch (SystemException JavaDoc se) {
79             throw new EJBException JavaDoc("Cannot get the current transaction on transaction manager.", se);
80         }
81
82         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         Transaction JavaDoc suspendedTransaction = null;
97         if (transaction != null) {
98             try {
99                 logger.debug("Suspending transaction {0}", transaction);
100                 suspendedTransaction = getTransactionManager().suspend();
101             } catch (SystemException JavaDoc se) {
102                 throw new EJBException JavaDoc("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
EasyBeansSFSB statefulBean = (EasyBeansSFSB) invocationContext.getTarget();
120         EZBSessionContext sessionContext = (EZBSessionContext) statefulBean.getEasyBeansContext();
121         // Get bean transaction (if any)
122
Transaction JavaDoc beanTransaction = sessionContext.getBeanTransaction();
123         // resume transaction for the call
124
if (beanTransaction != null) {
125             try {
126                 getTransactionManager().resume(beanTransaction);
127             } catch (InvalidTransactionException JavaDoc ite) {
128                 throw new EJBException JavaDoc(
129                         "Cannot call resume() on the previous bean transaction. There is an invalid transaction", ite);
130             } catch (IllegalStateException JavaDoc ise) {
131                 throw new EJBException JavaDoc(
132                         "Cannot call resume() on the previous bean transaction. There is another associated transaction",
133                         ise);
134             } catch (SystemException JavaDoc se) {
135                 throw new EJBException JavaDoc(
136                         "Cannot call resume() on the previous bean transaction. Unexpected error condition", se);
137             }
138         }
139
140         try {
141             return invocationContext.proceed();
142         } catch (Exception JavaDoc e) {
143             handleBeanManagedException(invocationContext, e);
144             // Shouldn't come here
145
return null;
146         } finally {
147
148             /*
149              * Saves the current bean transaction if the business method that
150              * started a transaction completes without committing or rolling
151              * back the transaction.
152              */

153             Transaction JavaDoc transactionAfter = null;
154             try {
155                 transactionAfter = getTransactionManager().getTransaction();
156             } catch (SystemException JavaDoc se) {
157                 throw new EJBException JavaDoc("Cannot get the current transaction on transaction manager.", se);
158             }
159             if (transactionAfter != null) {
160                 int transactionStatus = transactionAfter.getStatus();
161                 // not yet committed or rollbacked --> save transaction for the next call.
162
if (transactionStatus != STATUS_COMMITTED && transactionStatus != STATUS_ROLLEDBACK) {
163                     sessionContext.setBeanTransaction(transactionAfter);
164                 } else {
165                     sessionContext.setBeanTransaction(null);
166                 }
167             }
168
169             /*
170              * The container resumes the suspended association when the business
171              * method has completed.
172              */

173             if (suspendedTransaction != null) {
174
175                 logger.debug("Resuming transaction {0}", transaction);
176
177                 try {
178                     getTransactionManager().resume(suspendedTransaction);
179                 } catch (InvalidTransactionException JavaDoc ite) {
180                     throw new EJBException JavaDoc(
181                             "Cannot call resume() on the given transaction. There is an invalid transaction", ite);
182                 } catch (IllegalStateException JavaDoc ise) {
183                     throw new EJBException JavaDoc(
184                             "Cannot call resume() on the given transaction. There is another associated transaction",
185                             ise);
186                 } catch (SystemException JavaDoc se) {
187                     throw new EJBException JavaDoc("Cannot call resume() on the given transaction. Unexpected error condition",
188                             se);
189                 }
190             }
191         }
192     }
193 }
194
Popular Tags