KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openejb > core > stateful > StatefulBeanManagedTxPolicy


1 package org.openejb.core.stateful;
2
3 import java.rmi.RemoteException JavaDoc;
4
5 import javax.ejb.EnterpriseBean JavaDoc;
6 import javax.transaction.Status JavaDoc;
7 import javax.transaction.Transaction JavaDoc;
8
9 import org.openejb.ApplicationException;
10 import org.openejb.InvalidateReferenceException;
11 import org.openejb.core.transaction.TransactionContainer;
12 import org.openejb.core.transaction.TransactionContext;
13 import org.openejb.core.transaction.TransactionPolicy;
14
15 /**
16  * @author <a HREF="mailto:david.blevins@visi.com">David Blevins</a>
17  * @version $Revision: 2495 $ $Date: 2006-02-22 23:30:53 -0800 (Wed, 22 Feb 2006) $
18  */

19 public class StatefulBeanManagedTxPolicy extends TransactionPolicy {
20     
21     public StatefulBeanManagedTxPolicy(TransactionContainer container){
22         this();
23         if(container instanceof org.openejb.Container &&
24            ((org.openejb.Container)container).getContainerType()!=org.openejb.Container.STATEFUL) {
25             throw new IllegalArgumentException JavaDoc();
26         }
27         this.container = container;
28     }
29
30     public StatefulBeanManagedTxPolicy(){
31         policyType = BeanManaged;
32     }
33     
34     public String JavaDoc policyToString() {
35         return "TX_BeanManaged: ";
36     }
37     /**
38      * When a client invokes a business method via the enterprise bean's home or
39      * component interface, the Container suspends any transaction that may be
40      * associated with the client request. If there is a transaction associated
41      * with the instance (this would happen if the instance started the
42      * transaction in some previous business method), the Container associates the
43      * method execution with this transaction.
44      *
45      * The Container must make the javax.transaction.UserTransaction interface
46      * available to the enterprise bean's business method or onMessage method via
47      * the javax.ejb.EJBContext interface and under the environment entry
48      * java:comp/UserTransaction.
49      *
50      * When an instance uses the javax.transaction.UserTransaction interface to
51      * demarcate a transaction, the Container must enlist all the resource managers
52      * used by the instance between the begin() and commit() or rollback() methods
53      * with the transaction.
54      *
55      * When the instance attempts to commit the transaction, the Container is
56      * responsible for the global coordination of the transaction commit.
57      *
58      * @param instance
59      * @param context
60      * @exception org.openejb.SystemException
61      * @exception org.openejb.ApplicationException
62      */

63     public void beforeInvoke(EnterpriseBean JavaDoc instance, TransactionContext context) throws org.openejb.SystemException, org.openejb.ApplicationException{
64         try {
65
66             StatefulInstanceManager instanceManager = (StatefulInstanceManager) context.context.get(StatefulInstanceManager.class);
67             // if no transaction ---> suspend returns null
68
context.clientTx = suspendTransaction();
69
70             // Get any previously started transaction
71
Object JavaDoc primaryKey = context.callContext.getPrimaryKey();
72             Object JavaDoc possibleBeanTx = instanceManager.getAncillaryState( primaryKey );
73             if ( possibleBeanTx instanceof Transaction JavaDoc ) {
74                 context.currentTx = (Transaction JavaDoc)possibleBeanTx;
75                 resumeTransaction( context.currentTx );
76             }
77         } catch ( org.openejb.OpenEJBException e ) {
78             handleSystemException( e.getRootCause(), instance, context );
79         }
80     }
81
82     /**
83      * In the case of a stateful session bean, it is possible that the business
84      * method that started a transaction completes without committing or rolling
85      * back the transaction. In such a case, the Container must retain the
86      * association between the transaction and the instance across multiple client
87      * calls until the instance commits or rolls back the transaction.
88      *
89      * When the client invokes the next business method, the Container must invoke
90      * the business method in this transaction context.
91      *
92      * @param instance
93      * @param context
94      * @exception org.openejb.ApplicationException
95      * @exception org.openejb.SystemException
96      */

97     public void afterInvoke(EnterpriseBean JavaDoc instance, TransactionContext context) throws org.openejb.ApplicationException, org.openejb.SystemException{
98         try {
99             // Get the instance's transaction
100
context.currentTx = getTxMngr().getTransaction();
101
102             /*
103             // Remeber the instance's transaction if it is not committed or rolledback
104             */

105             if ( context.currentTx != null &&
106                  context.currentTx.getStatus() != Status.STATUS_COMMITTED &&
107                  context.currentTx.getStatus() != Status.STATUS_ROLLEDBACK ) {
108                 // There is a transaction in progress
109
// if we have a valid transaction it must be suspended
110
suspendTransaction();
111             }
112                             
113             // Remeber the instance's transaction
114

115             Object JavaDoc primaryKey = context.callContext.getPrimaryKey();
116             StatefulInstanceManager instanceManager = (StatefulInstanceManager) context.context.get(StatefulInstanceManager.class);
117             instanceManager.setAncillaryState( primaryKey, context.currentTx );
118
119         } catch ( org.openejb.OpenEJBException e ) {
120             handleSystemException( e.getRootCause(), instance, context );
121         } catch ( javax.transaction.SystemException JavaDoc e ) {
122             handleSystemException( e, instance, context );
123         } catch ( Throwable JavaDoc e ){
124             handleSystemException( e, instance, context );
125         } finally {
126             resumeTransaction( context.clientTx );
127         }
128     }
129
130     /**
131      * <B>Container's action</B>
132      *
133      * <P>
134      * Re-throw AppException
135      * </P>
136      *
137      * <B>Client's view</B>
138      *
139      * <P>
140      * Client receives AppException.
141      * </P>
142      */

143     public void handleApplicationException( Throwable JavaDoc appException, TransactionContext context) throws ApplicationException{
144         //re-throw AppException
145
throw new ApplicationException( appException );
146     }
147     
148     /**
149      * A system exception is any exception that is not an Application Exception.
150      *
151      * <B>Container's action</B>
152      *
153      * <P>
154      * <OL>
155      * <LI>
156      * Log the exception or error so that the System Administrator is alerted of
157      * the problem.
158      * </LI>
159      * <LI>
160      * Mark for rollback a transaction that has been started, but not yet
161      * completed, by the instance.
162      * </LI>
163      * <LI>
164      * Discard instance. The Container must not invoke any business methods or
165      * container callbacks on the instance.
166      * </LI>
167      * <LI>
168      * Throw RemoteException to remote client; throw EJBException to local client.
169      * </LI>
170      * </OL>
171      * </P>
172      *
173      * <B>Client's view</B>
174      *
175      * <P>
176      * Receives RemoteException or EJBException.
177      * </P>
178      */

179     public void handleSystemException( Throwable JavaDoc sysException, EnterpriseBean JavaDoc instance, TransactionContext context) throws org.openejb.ApplicationException, org.openejb.SystemException{
180         
181         // Log the system exception or error
182
logSystemException( sysException );
183         
184         // Mark for rollback the instance's transaction if it is not completed.
185
if ( context.currentTx != null ) markTxRollbackOnly( context.currentTx );
186
187         // Discard instance.
188
discardBeanInstance( instance, context.callContext);
189
190         // Throw RemoteException to remote client; throw EJBException to local client.
191
throwExceptionToServer( sysException );
192         
193     }
194
195     protected void throwExceptionToServer(Throwable JavaDoc sysException) throws ApplicationException{
196         // Throw RemoteException to remote client.
197
RemoteException JavaDoc re = new RemoteException JavaDoc("The bean encountered a non-application exception.", sysException);
198         
199         throw new InvalidateReferenceException( re );
200
201         // TODO:3: throw EJBException to local client.
202

203     }
204
205     protected void throwTxExceptionToServer( Throwable JavaDoc sysException ) throws ApplicationException{
206         /* Throw javax.transaction.TransactionRolledbackException to remote client */
207         // TODO:3: Internationalize the log message
208
String JavaDoc message = "The transaction was rolled back because the bean encountered a non-application exception :" + sysException.getClass().getName() + " : "+sysException.getMessage();
209         javax.transaction.TransactionRolledbackException JavaDoc txException = new javax.transaction.TransactionRolledbackException JavaDoc(message);
210
211         throw new InvalidateReferenceException( txException );
212
213         // TODO:3: throw javax.ejb.TransactionRolledbackLocalException to local client.
214
}
215 }
216
217
Popular Tags