KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openejb > alt > containers > castor_cmp11 > CastorCmpEntityTxPolicy


1 package org.openejb.alt.containers.castor_cmp11;
2
3 import java.rmi.RemoteException JavaDoc;
4
5 import javax.ejb.EnterpriseBean JavaDoc;
6
7 import org.exolab.castor.jdo.Database;
8 import org.exolab.castor.jdo.JDO;
9 import org.openejb.ApplicationException;
10 import org.openejb.core.transaction.TransactionContext;
11 import org.openejb.core.transaction.TransactionPolicy;
12 import org.openejb.core.transaction.TransactionContainer;
13 import org.openejb.core.DeploymentInfo;
14 import org.openejb.core.RpcContainerWrapper;
15
16 /**
17  * Wraps the TxPolicies for EntityBeans beans with container-managed
18  * persistence using Castor for persistence.
19  *
20  * When the wrapped TransactionPolicy doesn't start a transaction for the
21  * invocation of called method, a Castor local transaciton is required. The
22  * castor local transaction executes on a Database object aquired from a JDO
23  * object that was not initated with a transaction manager name.
24  *
25  * The local transaction will be committed by the afterInoke() method of this
26  * class or rolled back by the handleSystemException() or
27  * handleApplicationException() methods.
28  *
29  * @author <a HREF="mailto:Richard@Monson-Haefel.com">Richard Monson-Haefel</a>
30  * @author <a HREF="mailto:david.blevins@visi.com">David Blevins</a>
31  * @version $Revision: 2112 $ $Date: 2005-08-26 14:28:34 -0700 (Fri, 26 Aug 2005) $
32  */

33 public class CastorCmpEntityTxPolicy extends org.openejb.core.transaction.TransactionPolicy {
34     
35     protected TransactionPolicy policy;
36     protected CastorCMP11_EntityContainer cmpContainer;
37     
38     protected JDO jdo_ForLocalTransaction = null;
39     
40
41     public CastorCmpEntityTxPolicy(TransactionPolicy policy){
42         this.policy = policy;
43         this.container = policy.getContainer();
44         this.policyType = policy.policyType;
45
46         this.cmpContainer = getCastorContainer(container);
47         
48         this.jdo_ForLocalTransaction = cmpContainer.jdo_ForLocalTransaction;
49     }
50
51     private CastorCMP11_EntityContainer getCastorContainer(TransactionContainer container) {
52         if (container instanceof RpcContainerWrapper) {
53             RpcContainerWrapper wrapper = (RpcContainerWrapper)container;
54             return getCastorContainer((TransactionContainer) wrapper.getContainer());
55         } else {
56             return (CastorCMP11_EntityContainer)container;
57         }
58     }
59
60     public void beforeInvoke(EnterpriseBean JavaDoc instance, TransactionContext context) throws org.openejb.SystemException, org.openejb.ApplicationException{
61         policy.beforeInvoke( instance, context );
62
63         DeploymentInfo deploymentInfo = context.callContext.getDeploymentInfo();
64         ClassLoader JavaDoc classLoader = deploymentInfo.getBeanClass().getClassLoader();
65         cmpContainer.jdo_ForLocalTransaction.setClassLoader(classLoader);
66         cmpContainer.jdo_ForGlobalTransaction.setClassLoader(classLoader);
67
68         Database db = null;
69         try{
70             if( context.currentTx == null ) {
71                 /*
72                 * No current transaciton means that a local transaciton is required which
73                 * must be executed on Database object aquired from a JDO object that was not
74                 * initated with a transaction manager name.
75                 */

76                 db = jdo_ForLocalTransaction.getDatabase();
77                 
78                 /*
79                 * The fact that there is no transaction following the processing of the wrapped
80                 * TransactionPolicy's beforeInvoke( ) method indicates that the request must
81                 * execute in a Castor local transaction. To get that local transacion started
82                 * the begin() method is invoked. The local transaction will be committed by the
83                 * afterInoke() method of this class or rolled back by the handleSystemException()
84                 * or handleApplicationException() methods.
85                 */

86                 db.begin();
87                 
88                 /*
89                 * Places a non-transaction managed database object into the unspecified field
90                 * of the current transaction context. This will be used later by the
91                 * getDatabase( ) method of this class to provide the correct database object.
92                 * Its also used by the afterInovoke() method to commit the local transaction
93                 * and the handleSystemException() and handleApplicationException method to
94                 * rollback the Castor's local transaction.
95                 */

96                 context.callContext.setUnspecified(db);
97             }else{
98                 /*
99                 * If there is a transaction, that means that context is transaction-managed so
100                 * we make the unspecified field of the current ThreadContext null, which will
101                 * be used by the getDatabase() method of this class to determine that a
102                 * transaction-managed database object is needed.
103                 */

104                 context.callContext.setUnspecified( null );
105             }
106         }catch(org.exolab.castor.jdo.DatabaseNotFoundException e){
107             RemoteException JavaDoc re = new RemoteException JavaDoc("Castor JDO DatabaseNotFoundException thrown when attempting to begin a local transaciton", e);
108             handleSystemException( re, instance, context);
109         
110         }catch(org.exolab.castor.jdo.PersistenceException e){
111             RemoteException JavaDoc re = new RemoteException JavaDoc("Castor JDO PersistenceException thrown when attempting to begin local transaciton", e);
112             handleSystemException( re, instance, context);
113         
114         }catch (Throwable JavaDoc e){
115             RemoteException JavaDoc re = new RemoteException JavaDoc("Encountered and unkown error in Castor JDO when attempting to begin local transaciton", e);
116             handleSystemException( re, instance, context);
117         }
118     }
119
120     public void afterInvoke(EnterpriseBean JavaDoc instance, TransactionContext context) throws org.openejb.ApplicationException, org.openejb.SystemException{
121         try {
122             if ( context.currentTx == null ) {
123                 Database db = (Database)context.callContext.getUnspecified();
124                 if ( db != null && db.isActive() ) {
125                     db.commit();
126                 }
127             }
128         } catch ( org.exolab.castor.jdo.TransactionAbortedException e ) {
129             RemoteException JavaDoc ex = new RemoteException JavaDoc("Castor JDO threw a JDO TransactionAbortedException while attempting to commit a local transaciton", e);
130             policy.handleApplicationException( ex, context );
131         } catch ( org.exolab.castor.jdo.TransactionNotInProgressException e ) {
132             RemoteException JavaDoc ex = new RemoteException JavaDoc("Transaction managment problem with Castor JDO, a transaction should be in progress, but this is not the case.", e);
133             policy.handleSystemException( ex, instance, context );
134         } catch ( Throwable JavaDoc e ) {
135             RemoteException JavaDoc ex = new RemoteException JavaDoc("Encountered and unknown exception while attempting to commit the local castor database transaction", e);
136             policy.handleSystemException( ex, instance, context );
137         } finally {
138             policy.afterInvoke( instance, context );
139         }
140     }
141
142     public void handleApplicationException( Throwable JavaDoc appException, TransactionContext context) throws ApplicationException{
143         try{
144             if( context.currentTx == null ){
145                 Database db = (Database)context.callContext.getUnspecified();
146                 db.rollback();
147             }
148         }catch(org.exolab.castor.jdo.TransactionNotInProgressException tnipe){
149             // do nothing. At this point JDO's tx state is not important to handling the exception.
150
} finally {
151             policy.handleApplicationException( appException, context );
152         }
153     }
154     
155     public void handleSystemException( Throwable JavaDoc sysException, EnterpriseBean JavaDoc instance, TransactionContext context) throws org.openejb.ApplicationException, org.openejb.SystemException{
156         try{
157             if( context.currentTx == null ){
158                 Database db = (Database)context.callContext.getUnspecified();
159                 db.rollback();
160             }
161         }catch(org.exolab.castor.jdo.TransactionNotInProgressException tnipe){
162             // do nothing. At this point JDO's tx state is not important to handling the exception.
163
} finally {
164             policy.handleSystemException( sysException, instance, context );
165         }
166     }
167
168 }
169
170
171
Popular Tags