001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: JEntitySwitchDB.java 9860 2006-11-23 16:40:22Z durieuxp $
023: * --------------------------------------------------------------------------
024: */package org.objectweb.jonas_ejb.container;
025:
026: import java.util.HashMap;
027: import java.util.Iterator;
028:
029: import javax.ejb.EJBException;
030: import javax.transaction.SystemException;
031: import javax.transaction.Transaction;
032:
033: import org.objectweb.jonas_ejb.deployment.api.EntityDesc;
034:
035: import org.objectweb.util.monolog.api.BasicLevel;
036:
037: /**
038: * DataBase lock policy : 1 instance per transactions.
039: * Transaction Isolation is managed by the database.
040: * @author Philippe Durieux
041: */
042: public class JEntitySwitchDB extends JEntitySwitch {
043:
044: /**
045: * EntityContext for non-transacted requests
046: */
047: protected JEntityContext ihContext = null;
048:
049: /**
050: * Map of EntityContext's for transactions Key is the Transaction.
051: */
052: protected HashMap itsContext;
053:
054: /**
055: * empty constructor. Object is initialized via init() because it is
056: * implemented differently according to jorm mappers.
057: */
058: public JEntitySwitchDB() {
059: lockpolicy = EntityDesc.LOCK_DATABASE;
060: itsContext = new HashMap();
061: }
062:
063: protected void initpolicy(JEntityFactory bf) {
064: // TODO should be false, but the test is not correct.
065: lazyregister = !bf.isPrefetch() && !shared;
066: }
067:
068: /**
069: * @param tx The Transaction
070: * @return the JEntityContext used for this tx
071: */
072: protected JEntityContext getContext4Tx(Transaction tx) {
073: if (tx == null) {
074: return ihContext;
075: } else {
076: return (JEntityContext) itsContext.get(tx);
077: }
078: }
079:
080: /**
081: * @param tx The Transaction
082: * @param the JEntityContext used for this tx
083: */
084: protected void setContext4Tx(Transaction tx, JEntityContext ctx) {
085: if (tx == null) {
086: ihContext = ctx;
087: } else {
088: itsContext.put(tx, ctx);
089: }
090: }
091:
092: /**
093: *
094: */
095: protected void removeContext4Tx(Transaction tx) {
096: // free this Context
097: if (tx == null) {
098: ihContext = null;
099: } else {
100: itsContext.remove(tx);
101: }
102: }
103:
104: public void waitmyturn(Transaction tx) {
105: // synchro done by database.
106: }
107:
108: /**
109: * try to passivate instances
110: * @param store not used for this policy
111: * @param passivate always true for this policy
112: * @return result of operation: (not really used here)
113: * ALL_DONE = instances passivated
114: * NOT_DONE = not all passivated
115: */
116: public synchronized int passivateIH(boolean store, boolean passivate) {
117:
118: // Don't passivate too recent instances to avoid problems at create
119: if (System.currentTimeMillis() < estimestamp) {
120: TraceEjb.context.log(BasicLevel.DEBUG, "too recent ");
121: return NOT_DONE;
122: }
123:
124: // Instance used when no transaction.
125: JEntityContext jec = ihContext;
126: if (jec != null && countIH == 0) {
127: if (TraceEjb.isDebugContext()) {
128: TraceEjb.context.log(BasicLevel.DEBUG, "passivate: "
129: + jec);
130: }
131: if (jec.passivate()) {
132: // Will be pooled only if min-pool-size not reached in free list.
133: bf.releaseJContext(jec, 1);
134: ihContext = null;
135: // notify waiters for new instances
136: if (waiters > 0) {
137: notify();
138: }
139: }
140: }
141:
142: // Instances used for transactions are passivated automatically
143: // because usually shared=false with this policy.
144:
145: // all instances passivated
146: if (ihContext == null && itsContext.size() == 0) {
147: // look if we can destroy the objects
148: if (inactivityTimeout > 0
149: && System.currentTimeMillis() - estimestamp > inactivityTimeout) {
150: detachPk();
151: estimestamp = System.currentTimeMillis();
152: }
153:
154: return ALL_DONE;
155: }
156: return NOT_DONE;
157: }
158:
159: public void endIH() {
160: TraceEjb.synchro.log(BasicLevel.ERROR, ident);
161: return;
162: }
163:
164: /**
165: * Get a context/instance associated with this transaction Called at each
166: * request on the bean (including remove)
167: * @param tx - the Transaction object
168: * @return the BeanContext
169: */
170: public JEntityContext getICtx(Transaction tx, boolean checkr) {
171: // Don't check reentrance in case of database for now
172: // because it doesn't work in multithreading (countIT!)
173: return mapICtx(tx, null, false, true, false);
174: }
175:
176: /**
177: * @return State of this instance. State values are 0=in-tx, 1=out-tx, 2=idle,
178: * 3=passive, 4=removed. we don't synchronize this method to avoid
179: * jadmin blocks
180: */
181: public int getState() {
182: if (ihContext != null) {
183: if (ihContext.isMarkedRemoved()) {
184: return 4;
185: } else {
186: return 2;
187: }
188: }
189: if (itsContext.size() > 0) {
190: return 0;
191: }
192: return 3;
193: }
194:
195: }
|