KickJava   Java API By Example, From Geeks To Geeks.

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


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: JEntitySwitchDB.java,v 1.20 2005/05/16 14:52:47 durieuxp Exp $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.jonas_ejb.container;
27
28 import java.util.HashMap JavaDoc;
29 import java.util.Iterator JavaDoc;
30
31 import javax.ejb.EJBException JavaDoc;
32 import javax.transaction.SystemException JavaDoc;
33 import javax.transaction.Transaction JavaDoc;
34
35 import org.objectweb.jonas_ejb.deployment.api.EntityDesc;
36
37 import org.objectweb.util.monolog.api.BasicLevel;
38
39 /**
40  * DataBase lock policy : 1 instance per transactions.
41  * Transaction Isolation is managed by the database.
42  * @author Philippe Durieux
43  */

44 public class JEntitySwitchDB extends JEntitySwitch {
45
46     /**
47      * EntityContext for non-transacted requests
48      */

49     protected JEntityContext ihContext = null;
50
51     /**
52      * Map of EntityContext's for transactions Key is the Transaction.
53      */

54     protected HashMap JavaDoc itsContext;
55
56     /**
57      * empty constructor. Object is initialized via init() because it is
58      * implemented differently according to jorm mappers.
59      */

60     public JEntitySwitchDB() {
61         lockpolicy = EntityDesc.LOCK_DATABASE;
62         txUpdates = true;
63         itsContext = new HashMap JavaDoc();
64     }
65
66     protected void initpolicy(JEntityFactory bf) {
67         // should be false, because usually this policy implies shared=true.
68
lazyregister = !bf.isPrefetch() && !shared;
69     }
70
71     /**
72      * @param tx The Transaction
73      * @return the JEntityContext used for this tx
74      */

75     protected JEntityContext getContext4Tx(Transaction JavaDoc tx) {
76         if (tx == null) {
77             return ihContext;
78         } else {
79             return (JEntityContext) itsContext.get(tx);
80         }
81     }
82
83     /**
84      * @param tx The Transaction
85      * @param the JEntityContext used for this tx
86      */

87     protected void setContext4Tx(Transaction JavaDoc tx, JEntityContext ctx) {
88         if (tx == null) {
89             ihContext = ctx;
90         } else {
91             if (TraceEjb.isDebugSwapper()) TraceEjb.swapper.log(BasicLevel.DEBUG, ident + " add new Context");
92             itsContext.put(tx, ctx);
93         }
94     }
95
96     /**
97      *
98      */

99     protected void removeContext4Tx(Transaction JavaDoc tx) {
100         // free this Context
101
if (tx == null) {
102             ihContext = null;
103         } else {
104             if (TraceEjb.isDebugSwapper()) TraceEjb.swapper.log(BasicLevel.DEBUG, ident + " get rid of this Context");
105             itsContext.remove(tx);
106         }
107     }
108
109     public void waitmyturn(Transaction JavaDoc tx) {
110         // synchro done by database.
111
}
112
113     public boolean passivateIH(boolean passivation) {
114         // If already passivated, look if we can destroy the objects
115
if (ihContext == null && itsContext.size() == 0) {
116             if (inactivityTimeout > 0 &&
117                 System.currentTimeMillis() - timestamp > inactivityTimeout) {
118                 if (TraceEjb.isDebugContext()) {
119                     TraceEjb.context.log(BasicLevel.DEBUG, "discard object on timeout");
120                 }
121                 discardContext(null, true, false);
122             }
123             return true;
124         }
125
126         // passivate this instance if required.
127
if (passivation) {
128             if (TraceEjb.isDebugSwapper()) TraceEjb.swapper.log(BasicLevel.DEBUG, ident);
129             // Instance used when no transaction.
130
JEntityContext jec = ihContext;
131             if (jec != null) {
132                 if (TraceEjb.isDebugContext()) TraceEjb.context.log(BasicLevel.DEBUG, "passivated: " + jec);
133                 jec.passivate();
134                 bf.releaseJContext(jec);
135                 ihContext = null;
136             }
137
138             // If passivation done, set the timestamp
139
if (itsContext.size() == 0) {
140                 timestamp = System.currentTimeMillis();
141             }
142
143             // Instances used in transaction are already passivated
144
// when the transaction is over. (See JEntitySwitch.java)
145
if (waiters > 0) {
146                 if (TraceEjb.isDebugSynchro()) {
147                     TraceEjb.synchro.log(BasicLevel.DEBUG, ident + " notify");
148                 }
149                 notifyAll();
150             }
151         }
152         return true;
153     }
154
155     public void endIH() {
156         return;
157     }
158
159     /**
160      * Get a context/instance associated with this transaction Called at each
161      * request on the bean (including remove)
162      * @param tx - the Transaction object
163      * @return the BeanContext
164      */

165     public JEntityContext getICtx(Transaction JavaDoc tx, boolean checkr) {
166         // Don't check reentrance in case of database for now
167
// because it doesn't work in multithreading (countIT!)
168
return mapICtx(tx, null, false, true, false);
169     }
170
171     /**
172      * This transaction has just modified this instance. (CMP2 only)
173      * @param tx transaction
174      */

175     public synchronized void notifyWriting(Transaction JavaDoc tx, JEntityContext bctx) {
176         if (TraceEjb.isDebugSynchro()) {
177             TraceEjb.synchro.log(BasicLevel.DEBUG, ident);
178         }
179         if (writingtx != null) {
180             if (!tx.equals(writingtx)) {
181                 TraceEjb.logger.log(BasicLevel.WARN, bf.getEJBName() + " Conflict: 2 transactions attempt to write the same instance");
182                 try {
183                     tx.setRollbackOnly();
184                 } catch (SystemException JavaDoc e) {
185                     TraceEjb.logger.log(BasicLevel.ERROR, "cannot setRollbackOnly");
186                 }
187             }
188         } else {
189             if (lazyregister) {
190                 // Instance must be written later.
191
// In case of prefetch, this has already be done (=
192
// !lazyregister)
193
registerCtx(tx, bctx);
194             }
195             writingtx = tx;
196         }
197     }
198
199     /**
200      * @return State of this instance. State values are 0=in-tx, 1=out-tx, 2=idle,
201      * 3=passive, 4=removed. we don't synchronize this method to avoid
202      * jadmin blocks
203      */

204     public int getState() {
205         if (ihContext != null) {
206             if (ihContext.isMarkedRemoved()) {
207                 return 4;
208             } else {
209                 if (inDirtyList) {
210                     return 1;
211                 } else {
212                     return 2;
213                 }
214             }
215         }
216         if (itsContext.size() > 0) {
217             return 0;
218         }
219         return 3;
220     }
221
222 }
223
Popular Tags