KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas_ejb > container > TxListener


1 /*
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright (C) 1999 Bull S.A.
4  * Contact: jonas-team@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: TxListener.java,v 1.9 2005/04/28 16:52:59 benoitf Exp $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.jonas_ejb.container;
27
28 import java.util.Iterator JavaDoc;
29 import java.util.LinkedList JavaDoc;
30 import javax.naming.Context JavaDoc;
31 import javax.transaction.Synchronization JavaDoc;
32 import javax.transaction.Transaction JavaDoc;
33
34 import org.objectweb.jonas_ejb.container.jorm.JormFactory;
35 import org.objectweb.jorm.api.PMapper;
36 import org.objectweb.medor.eval.prefetch.api.PrefetchCache;
37 import org.objectweb.util.monolog.api.BasicLevel;
38
39 /**
40  * This class is a listener on the transaction. It is registered as
41  * a Synchronization on the current transaction. It holds the list of all
42  * instances that are possibly modified during the transaction.
43  * @author Philippe Durieux
44  * @author Alexei Novakov (fix ConcurrentModification issue)
45  */

46 public class TxListener implements Synchronization JavaDoc {
47
48     private JEntityFactory bf;
49     private Transaction JavaDoc tx;
50
51     /**
52      * list of contexts to be stored on disk.
53      */

54     private LinkedList JavaDoc ctxList = new LinkedList JavaDoc();
55     private LinkedList JavaDoc additionalContexts = new LinkedList JavaDoc();
56     private boolean inStoreInstances = false;
57
58     /**
59      * constructor
60      * @param bf ref on the Bean Factory
61      * @param tx associated Transaction
62      */

63     public TxListener(JEntityFactory bf, Transaction JavaDoc tx) {
64         if (TraceEjb.isDebugTxlistener()) {
65             TraceEjb.txlistener.log(BasicLevel.DEBUG, "");
66         }
67         this.bf = bf;
68         this.tx = tx;
69     }
70
71     /**
72      * Synchronizes all instances on disk.
73      * This must be called before every SQL request (finder) or at beforeCompletion().
74      * We must be in the good transaction context here, and with the correct
75      * component environment (java:comp).
76      */

77     public synchronized void storeInstances() {
78         if (TraceEjb.isDebugTxlistener()) {
79             TraceEjb.txlistener.log(BasicLevel.DEBUG, "");
80         }
81         inStoreInstances = true;
82         storeInstances(ctxList);
83         while (!additionalContexts.isEmpty()) {
84             LinkedList JavaDoc lst = new LinkedList JavaDoc();
85             lst.addAll(additionalContexts);
86             additionalContexts.clear();
87             storeInstances(lst);
88             ctxList.addAll(lst);
89         }
90         inStoreInstances = false;
91     }
92
93     /**
94      * Add a new Context in the list.
95      * @param ec the JEntityContext to synchronize
96      */

97     public synchronized void addInstance(JEntityContext ec) {
98         if (TraceEjb.isDebugTxlistener()) {
99             TraceEjb.txlistener.log(BasicLevel.DEBUG, "");
100         }
101         if (inStoreInstances) {
102             additionalContexts.addLast(ec);
103         } else {
104             ctxList.addLast(ec);
105         }
106     }
107
108     // -------------------------------------------------------------------
109
// Synchronization implementation
110
// -------------------------------------------------------------------
111

112     /**
113      * This beforeCompletion method is called by the transaction
114      * manager prior to the start of the transaction completion process.
115      * This method executes in the transaction context of the calling
116      * thread.
117      * The Bean's state must be stored on the persistent storage before
118      * the completion of the transaction.
119      */

120     public void beforeCompletion() {
121         if (TraceEjb.isDebugTxlistener()) {
122             TraceEjb.txlistener.log(BasicLevel.DEBUG, "");
123         }
124
125         // Set classloader for getting the right component context
126
ClassLoader JavaDoc old = Thread.currentThread().getContextClassLoader();
127         Thread.currentThread().setContextClassLoader(bf.myClassLoader());
128
129         Context JavaDoc bnctx = bf.setComponentContext();
130         storeInstances();
131         bf.resetComponentContext(bnctx);
132         Thread.currentThread().setContextClassLoader(old);
133     }
134
135     /**
136      * The afterCompletion method is called by the transaction
137      * manager after the transaction is committed or rolled back.
138      * This method executes without a transaction context.
139      *
140      * @param status The status of the transaction completion.
141      */

142     public void afterCompletion(int status) {
143         if (TraceEjb.isDebugTxlistener()) {
144             TraceEjb.txlistener.log(BasicLevel.DEBUG, "");
145         }
146
147         // Send afterCompletion on each Context.
148
synchronized (this) {
149             for (Iterator JavaDoc i = ctxList.iterator(); i.hasNext(); ) {
150                 JEntityContext ec = (JEntityContext) i.next();
151                 ec.afterCompletion(status);
152             }
153         }
154
155         // Invalid the prefetch cache
156
if (bf instanceof JormFactory) {
157             PMapper mapper = ((JormFactory) bf).getMapper();
158             PrefetchCache pc = mapper.getPrefetchCache();
159             if (pc != null) {
160                 pc.invalidatePrefetchBuffer(tx);
161             }
162         }
163
164         // remove this in the tx HashMap.
165
bf.removeTxListener(tx);
166     }
167
168     private void storeInstances(LinkedList JavaDoc contexts) {
169         for (Iterator JavaDoc i = contexts.iterator(); i.hasNext(); ) {
170             JEntityContext ec = (JEntityContext) i.next();
171             ec.beforeCompletion();
172         }
173     }
174 }
175
Popular Tags