KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb3 > cache > simple > SimpleStatefulCache


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.ejb3.cache.simple;
23
24 import java.util.Iterator JavaDoc;
25 import java.util.LinkedHashMap JavaDoc;
26 import java.util.Map JavaDoc;
27 import javax.ejb.EJBException JavaDoc;
28 import javax.ejb.NoSuchEJBException JavaDoc;
29 import org.jboss.annotation.ejb.cache.simple.CacheConfig;
30 import org.jboss.annotation.ejb.cache.simple.PersistenceManager;
31 import org.jboss.aop.Advisor;
32 import org.jboss.ejb3.Container;
33 import org.jboss.ejb3.EJBContainer;
34 import org.jboss.ejb3.Pool;
35 import org.jboss.ejb3.cache.StatefulCache;
36 import org.jboss.ejb3.stateful.StatefulBeanContext;
37 import org.jboss.util.id.GUID;
38 import org.jboss.logging.Logger;
39
40 /**
41  * Comment
42  *
43  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
44  * @version $Revision: 58478 $
45  */

46 public class SimpleStatefulCache implements StatefulCache
47 {
48    private static final Logger log = Logger.getLogger(SimpleStatefulCache.class);
49
50    private Pool pool;
51    private CacheMap cacheMap;
52    private int maxSize = 1000;
53    private StatefulSessionPersistenceManager pm;
54    private long sessionTimeout = 300; // 5 minutes
55
private SessionTimeoutTask timeoutTask;
56    private boolean running = true;
57
58    private class CacheMap extends LinkedHashMap JavaDoc
59    {
60       public CacheMap()
61       {
62          super(maxSize, 0.75F, true);
63       }
64
65       public boolean removeEldestEntry(Map.Entry JavaDoc entry)
66       {
67          boolean removeIt = size() > maxSize;
68          if (removeIt)
69          {
70             StatefulBeanContext centry = (StatefulBeanContext) entry.getValue();
71             synchronized (centry)
72             {
73                if (centry.inUse)
74                {
75                   centry.markedForPassivation = true;
76                }
77                else
78                {
79                   passivate(centry);
80                }
81                // its ok to evict because bean will be passivated.
82
}
83          }
84          return removeIt;
85       }
86    }
87
88    private class SessionTimeoutTask extends Thread JavaDoc
89    {
90       public SessionTimeoutTask(String JavaDoc name)
91       {
92          super(name);
93       }
94
95       public void run()
96       {
97          while (running)
98          {
99             try
100             {
101                Thread.sleep(sessionTimeout * 1000);
102             }
103             catch (InterruptedException JavaDoc e)
104             {
105                running = false;
106                return;
107             }
108             try
109             {
110                synchronized (cacheMap)
111                {
112                   if (!running) return;
113                   Iterator JavaDoc it = cacheMap.entrySet().iterator();
114                   long now = System.currentTimeMillis();
115                   while (it.hasNext())
116                   {
117                      Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
118                      StatefulBeanContext centry = (StatefulBeanContext) entry.getValue();
119                      if (now - centry.lastUsed >= sessionTimeout * 1000)
120                      {
121                         synchronized (centry)
122                         {
123                            if (centry.inUse)
124                            {
125                               centry.markedForPassivation = true;
126                            }
127                            else
128                            {
129                               passivate(centry);
130                            }
131                            // its ok to evict because it will be passivated.
132
it.remove();
133                         }
134                      }
135                   }
136                }
137             }
138             catch (Exception JavaDoc ex)
139             {
140                log.error("problem passivation thread", ex);
141             }
142          }
143       }
144    }
145
146    public void initialize(Container container) throws Exception JavaDoc
147    {
148       Advisor advisor = (Advisor) container;
149       this.pool = container.getPool();
150       cacheMap = new CacheMap();
151       PersistenceManager pmConfig = (PersistenceManager) advisor.resolveAnnotation(PersistenceManager.class);
152       this.pm = (StatefulSessionPersistenceManager) pmConfig.value().newInstance();
153       pm.initialize(container);
154       CacheConfig config = (CacheConfig) advisor.resolveAnnotation(CacheConfig.class);
155       maxSize = config.maxSize();
156       sessionTimeout = config.idleTimeoutSeconds();
157       log.debug("Initializing SimpleStatefulCache with maxSize: " +maxSize + " timeout: " +sessionTimeout +
158               " for " +container.getObjectName().getCanonicalName() );
159       timeoutTask = new SessionTimeoutTask("SFSB Passivation Thread - " + container.getObjectName().getCanonicalName());
160    }
161
162    public SimpleStatefulCache()
163    {
164    }
165
166    public void start()
167    {
168       running = true;
169       timeoutTask.start();
170    }
171
172    public void stop()
173    {
174       synchronized (cacheMap)
175       {
176          running = false;
177          timeoutTask.interrupt();
178          cacheMap.clear();
179          try
180          {
181             pm.destroy();
182          }
183          catch (Exception JavaDoc e)
184          {
185             throw new RuntimeException JavaDoc(e);
186          }
187       }
188    }
189
190    protected void passivate(StatefulBeanContext ctx)
191    {
192       ClassLoader JavaDoc oldCl = Thread.currentThread().getContextClassLoader();
193       try
194       {
195          Thread.currentThread().setContextClassLoader(((EJBContainer) ctx.getContainer()).getClassloader());
196          pm.passivateSession(ctx);
197       }
198       finally
199       {
200          Thread.currentThread().setContextClassLoader(oldCl);
201       }
202    }
203
204    public StatefulBeanContext create()
205    {
206       StatefulBeanContext ctx = null;
207       try
208       {
209          ctx = (StatefulBeanContext) pool.get();
210          synchronized (cacheMap)
211          {
212             cacheMap.put(ctx.getId(), ctx);
213          }
214          ctx.inUse = true;
215          ctx.lastUsed = System.currentTimeMillis();
216       }
217       catch (EJBException JavaDoc e)
218       {
219          e.printStackTrace();
220          throw e;
221       }
222       catch (Exception JavaDoc e)
223       {
224          e.printStackTrace();
225          throw new EJBException JavaDoc(e);
226       }
227       return ctx;
228    }
229
230    public StatefulBeanContext create(Class JavaDoc[] initTypes, Object JavaDoc[] initValues)
231    {
232       StatefulBeanContext ctx = null;
233       try
234       {
235          ctx = (StatefulBeanContext) pool.get(initTypes, initValues);
236          synchronized (cacheMap)
237          {
238             cacheMap.put(ctx.getId(), ctx);
239          }
240          ctx.inUse = true;
241          ctx.lastUsed = System.currentTimeMillis();
242       }
243       catch (EJBException JavaDoc e)
244       {
245          e.printStackTrace();
246          throw e;
247       }
248       catch (Exception JavaDoc e)
249       {
250          e.printStackTrace();
251          throw new EJBException JavaDoc(e);
252       }
253       return ctx;
254    }
255
256    public StatefulBeanContext get(Object JavaDoc key) throws EJBException JavaDoc
257    {
258       StatefulBeanContext entry = null;
259       synchronized (cacheMap)
260       {
261          entry = (StatefulBeanContext) cacheMap.get(key);
262       }
263       if (entry == null)
264       {
265          Object JavaDoc bean = pm.activateSession(key);
266          if (bean == null)
267          {
268             throw new NoSuchEJBException JavaDoc("Could not find Stateful bean: " + key);
269          }
270          entry = (StatefulBeanContext) bean;
271          synchronized (cacheMap)
272          {
273             cacheMap.put(key, entry);
274          }
275       }
276       entry.inUse = true;
277       entry.lastUsed = System.currentTimeMillis();
278       return entry;
279    }
280
281    public void finished(StatefulBeanContext ctx)
282    {
283       synchronized (ctx)
284       {
285          ctx.inUse = false;
286          ctx.lastUsed = System.currentTimeMillis();
287          if (ctx.markedForPassivation)
288          {
289             passivate(ctx);
290          }
291       }
292    }
293
294    public void remove(Object JavaDoc key)
295    {
296       StatefulBeanContext ctx = null;
297       synchronized (cacheMap)
298       {
299          ctx = (StatefulBeanContext) cacheMap.remove(key);
300       }
301       if (ctx != null) pool.remove(ctx);
302    }
303
304
305 }
306
Popular Tags