KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > ejb > containers > ContainerSynchronization


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.ejb.containers;
25
26 import java.util.*;
27
28 import javax.ejb.*;
29 import javax.transaction.*;
30
31 import com.sun.enterprise.log.Log;
32
33 import java.util.logging.*;
34 import com.sun.logging.*;
35
36
37 /**
38  * This class intercepts Synchronization notifications from
39  * the TransactionManager and forwards them to the appropriate container.
40  * There is one ContainerSynchronization instance per tx.
41  * All bean instances (of all types) participating in the tx must be
42  * added by the container to the ContainerSynchronization, so that
43  * the beans can be called during before/afterCompletion.
44  *
45  * This class also provides special methods for PersistenceManager Sync and
46  * Timer objects which must be called AFTER the containers during
47  * before/afterCompletion.
48  *
49  */

50 final class ContainerSynchronization implements Synchronization
51 {
52
53     private static Logger _logger=null;
54     static{
55        _logger=LogDomains.getLogger(LogDomains.EJB_LOGGER);
56     }
57
58     private Vector beans = new Vector();
59     private Vector pmSyncs = new Vector();
60
61     private Hashtable timerSyncs = new Hashtable();
62
63     private Transaction tx; // the tx with which this Sync was registered
64
private ContainerFactoryImpl containerFactory;
65     private SFSBTxCheckpointCoordinator sfsbTxCoordinator;
66
67     // Note: this must be called only after a Tx is begun.
68
ContainerSynchronization(Transaction tx,
69                  ContainerFactoryImpl containerFactory)
70     {
71         this.tx = tx;
72         this.containerFactory = containerFactory;
73     }
74     
75     Vector getBeanList(){
76         return beans;
77     }
78     
79     void addBean(EJBContextImpl bean)
80     {
81         if (beans.contains(bean))
82             return;
83         beans.add(bean);
84     }
85     
86     void removeBean(EJBContextImpl bean)
87     {
88         beans.remove(bean);
89     }
90     
91     void addPMSynchronization(Synchronization sync)
92     {
93         pmSyncs.add(sync);
94     }
95
96     // Set synchronization object for a particular timer.
97
void addTimerSynchronization(TimerPrimaryKey timerId, Synchronization sync)
98     {
99         timerSyncs.put(timerId, sync);
100     }
101
102     // Might be null if no timer synch object for this timerId in this tx
103
Synchronization getTimerSynchronization(TimerPrimaryKey timerId) {
104         return (Synchronization) timerSyncs.get(timerId);
105     }
106
107     void removeTimerSynchronization(TimerPrimaryKey timerId) {
108         timerSyncs.remove(timerId);
109     }
110
111     public void beforeCompletion()
112     {
113         // first call beforeCompletion for each bean instance
114
for ( int i=0; i<beans.size(); i++ ) {
115             EJBContextImpl context = (EJBContextImpl)beans.elementAt(i);
116             BaseContainer container = (BaseContainer)context.getContainer();
117             try {
118                 if( container != null ) {
119             if (container.isUndeployed()) {
120             _logger.log(Level.WARNING, "Marking Tx for rollback "
121                 + " because container for " + container
122                 + " is undeployed");
123             try {
124                 tx.setRollbackOnly();
125             } catch (SystemException sysEx) {
126                 _logger.log(Level.FINE, "Error while trying to "
127                 + "mark for rollback", sysEx);
128             }
129             } else {
130             container.beforeCompletion(context);
131             }
132                 } else {
133                     // Might be null if bean was removed. Just skip it.
134
_logger.log(Level.FINE, "context with empty container in " +
135                                 " ContainerSynchronization.beforeCompletion");
136                 }
137             } catch ( Exception JavaDoc ex ) {
138                 // rollback the Tx. The client will get
139
// a EJB/RemoteException or a TransactionRolledbackException.
140
_logger.log(Level.SEVERE,"ejb.remote_or_txnrollback_exception",ex);
141                 try {
142                     tx.setRollbackOnly();
143                 } catch ( SystemException e ) {
144                     _logger.log(Level.FINE, "", ex);
145                 }
146                 return; // no need to call remaining beforeCompletions
147
}
148         }
149
150         // now call beforeCompletion for all pmSyncs
151
for ( int i=0; i<pmSyncs.size(); i++ ) {
152             Synchronization sync = (Synchronization)pmSyncs.elementAt(i);
153             try {
154                 sync.beforeCompletion();
155             } catch ( Exception JavaDoc ex ) {
156                 // rollback the Tx. The client will get
157
// a EJB/RemoteException or a TransactionRolledbackException.
158
_logger.log(Level.SEVERE,"ejb.remote_or_txnrollback_exception",ex);
159                 try {
160                     tx.setRollbackOnly();
161                 } catch ( SystemException e ) {
162                     _logger.log(Level.FINE, "", ex);
163                 }
164                 return; // no need to call remaining beforeCompletions
165
}
166         }
167     }
168
169     public void afterCompletion(int status)
170     {
171         for ( int i=0; i<pmSyncs.size(); i++ ) {
172             Synchronization sync = (Synchronization)pmSyncs.elementAt(i);
173             try {
174                 sync.afterCompletion(status);
175             } catch ( Exception JavaDoc ex ) {
176                 _logger.log(Level.SEVERE, "ejb.after_completion_error", ex);
177             }
178         }
179
180         // call afterCompletion for each bean instance
181
for ( int i=0; i<beans.size();i++ ) {
182             EJBContextImpl context = (EJBContextImpl)beans.elementAt(i);
183             BaseContainer container = (BaseContainer)context.getContainer();
184             try {
185                 if( container != null ) {
186                     container.afterCompletion(context, status);
187                 } else {
188                     // Might be null if bean was removed. Just skip it.
189
_logger.log(Level.FINE, "context with empty container in "
190                                 +
191                                 " ContainerSynchronization.afterCompletion");
192                 }
193             } catch ( Exception JavaDoc ex ) {
194                 _logger.log(Level.SEVERE, "ejb.after_completion_error", ex);
195             }
196         }
197
198     if (sfsbTxCoordinator != null) {
199         sfsbTxCoordinator.doTxCheckpoint();
200     }
201
202         for ( Iterator iter = timerSyncs.values().iterator();
203               iter.hasNext(); ) {
204             Synchronization timerSync = (Synchronization) iter.next();
205             try {
206                 timerSync.afterCompletion(status);
207             } catch ( Exception JavaDoc ex ) {
208                 _logger.log(Level.SEVERE, "ejb.after_completion_error", ex);
209             }
210         }
211
212         // tell ContainerFactory to remove this tx/sync from its table
213
containerFactory.removeContainerSync(tx);
214     }
215
216     void registerForTxCheckpoint(SessionContextImpl sessionCtx) {
217     //No need to synchronize
218
if (sfsbTxCoordinator == null) {
219         sfsbTxCoordinator = new SFSBTxCheckpointCoordinator();
220     }
221
222     sfsbTxCoordinator.registerContext(sessionCtx);
223     }
224 }
225
Popular Tags