KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb > plugins > StatefulSessionInstanceCache


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.ejb.plugins;
23
24 import java.util.HashSet JavaDoc;
25 import java.util.Map JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.rmi.RemoteException JavaDoc;
28 import javax.transaction.Status JavaDoc;
29 import javax.transaction.SystemException JavaDoc;
30
31 import org.jboss.ejb.Container;
32 import org.jboss.ejb.StatefulSessionContainer;
33 import org.jboss.ejb.EnterpriseContext;
34 import org.jboss.ejb.StatefulSessionEnterpriseContext;
35 import org.jboss.ejb.StatefulSessionPersistenceManager;
36 import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
37
38 /**
39  * Cache for stateful session beans.
40  *
41  * @author <a HREF="mailto:simone.bordet@compaq.com">Simone Bordet</a>
42  * @author <a HREF="mailto:sebastien.alborini@m4x.org">Sebastien Alborini</a>
43  * @version $Revision: 42606 $
44  */

45 public class StatefulSessionInstanceCache extends AbstractInstanceCache
46 {
47    // Constants -----------------------------------------------------
48

49    // Attributes ----------------------------------------------------
50

51    /* The container */
52    private StatefulSessionContainer m_container;
53
54    /** The map<id, Long> that holds passivated bean ids that have been removed
55     * from the cache and passivated to the pm along with the time of passivation
56     */

57    private ConcurrentReaderHashMap passivatedIDs = new ConcurrentReaderHashMap();
58
59    /* Ids that are currently being activated */
60    private HashSet JavaDoc activating = new HashSet JavaDoc();
61
62    /* Used for logging */
63    private StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
64
65    // Static --------------------------------------------------------
66

67    // Constructors --------------------------------------------------
68

69    // Public --------------------------------------------------------
70

71    /** Get the passivated count.
72     * @jmx:managed-attribute
73     * @return the number of passivated instances.
74     */

75    public long getPassivatedCount()
76    {
77       return passivatedIDs.size();
78    }
79
80    /* From ContainerPlugin interface */
81    public void setContainer(Container c)
82    {
83       m_container = (StatefulSessionContainer) c;
84    }
85
86    public void destroy()
87    {
88       synchronized (this)
89       {
90          this.m_container = null;
91       }
92       passivatedIDs.clear();
93       super.destroy();
94    }
95
96    // Z implementation ----------------------------------------------
97

98    // Y overrides ---------------------------------------------------
99

100    protected synchronized Container getContainer()
101    {
102       return m_container;
103    }
104
105    protected void passivate(EnterpriseContext ctx) throws RemoteException JavaDoc
106    {
107       m_container.getPersistenceManager().passivateSession((StatefulSessionEnterpriseContext) ctx);
108       passivatedIDs.put(ctx.getId(), new Long JavaDoc(System.currentTimeMillis()));
109    }
110
111    protected void activate(EnterpriseContext ctx) throws RemoteException JavaDoc
112    {
113       m_container.getPersistenceManager().activateSession((StatefulSessionEnterpriseContext) ctx);
114       passivatedIDs.remove(ctx.getId());
115    }
116    
117    protected boolean doActivate(EnterpriseContext ctx) throws RemoteException JavaDoc
118    {
119       Object JavaDoc id = ctx.getId();
120       synchronized (activating)
121       {
122          // This is a recursive invocation
123
if (activating.contains(id))
124             return false;
125          activating.add(id);
126       }
127       try
128       {
129          return super.doActivate(ctx);
130       }
131       finally
132       {
133          synchronized (activating)
134          {
135             activating.remove(id);
136          }
137       }
138    }
139
140    protected EnterpriseContext acquireContext() throws Exception JavaDoc
141    {
142       return m_container.getInstancePool().get();
143    }
144
145    protected void freeContext(EnterpriseContext ctx)
146    {
147       m_container.getInstancePool().free(ctx);
148    }
149
150    protected Object JavaDoc getKey(EnterpriseContext ctx)
151    {
152       return ctx.getId();
153    }
154
155    protected void setKey(Object JavaDoc id, EnterpriseContext ctx)
156    {
157       ctx.setId(id);
158    }
159
160    protected boolean canPassivate(EnterpriseContext ctx)
161    {
162       if (ctx.isLocked())
163       {
164          // The context is in the interceptor chain
165
return false;
166       }
167       else if (m_container.getLockManager().canPassivate(ctx.getId()) == false)
168       {
169          return false;
170       }
171       else
172       {
173          if (ctx.getTransaction() != null)
174          {
175             try
176             {
177                return (ctx.getTransaction().getStatus() == Status.STATUS_NO_TRANSACTION);
178             }
179             catch (SystemException JavaDoc e)
180             {
181                // SA FIXME: not sure what to do here
182
return false;
183             }
184          }
185       }
186       return true;
187    }
188
189    /** Remove all passivated instances that have been inactive too long.
190     * @param maxLifeAfterPassivation the upper bound in milliseconds that an
191     * inactive session will be kept.
192     */

193    protected void removePassivated(long maxLifeAfterPassivation)
194    {
195       StatefulSessionPersistenceManager store = m_container.getPersistenceManager();
196       long now = System.currentTimeMillis();
197       log.debug("removePassivated, now="+now+", maxLifeAfterPassivation="+maxLifeAfterPassivation);
198       boolean trace = log.isTraceEnabled();
199       Iterator JavaDoc entries = passivatedIDs.entrySet().iterator();
200       while (entries.hasNext())
201       {
202          Map.Entry JavaDoc entry = (Map.Entry JavaDoc) entries.next();
203          Object JavaDoc key = entry.getKey();
204          Long JavaDoc value = (Long JavaDoc) entry.getValue();
205          if (value != null)
206          {
207             long passivationTime = value.longValue();
208             if (now - passivationTime > maxLifeAfterPassivation)
209             {
210                preRemovalPreparation(key);
211                store.removePassivated(key);
212                if (trace)
213                   log(key, passivationTime);
214                // Must use iterator to avoid ConcurrentModificationException
215
entries.remove();
216                postRemovalCleanup(key);
217             }
218          }
219       }
220    }
221
222    // Protected -----------------------------------------------------
223

224    protected void preRemovalPreparation(Object JavaDoc key)
225    {
226       // no-op...extending classes may add prep
227
}
228
229    protected void postRemovalCleanup(Object JavaDoc key)
230    {
231       // no-op...extending classes may add cleanup
232
}
233
234    // Private -------------------------------------------------------
235

236    private void log(Object JavaDoc key, long passivationTime)
237    {
238       if (log.isTraceEnabled())
239       {
240          buffer.setLength(0);
241          buffer.append("Removing from storage bean '");
242          buffer.append(m_container.getBeanMetaData().getEjbName());
243          buffer.append("' with id = ");
244          buffer.append(key);
245          buffer.append(", passivationTime=");
246          buffer.append(passivationTime);
247          log.trace(buffer.toString());
248       }
249    }
250
251    // Inner classes -------------------------------------------------
252

253 }
Popular Tags