KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb > txtimer > EJBTimerServiceImpl


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.txtimer;
23
24 // $Id: EJBTimerServiceImpl.java 58307 2006-11-13 21:38:35Z wolfc $
25

26 import java.lang.reflect.Constructor JavaDoc;
27 import java.util.Collection JavaDoc;
28 import java.util.Collections JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.List JavaDoc;
32 import java.util.Map JavaDoc;
33
34 import javax.ejb.TimerService JavaDoc;
35 import javax.management.ObjectName JavaDoc;
36 import javax.transaction.TransactionManager JavaDoc;
37
38 import org.jboss.ejb.Container;
39 import org.jboss.ejb.ContainerMBean;
40 import org.jboss.logging.Logger;
41 import org.jboss.mx.util.MBeanProxyExt;
42 import org.jboss.system.ServiceMBeanSupport;
43 import org.jboss.tm.TransactionManagerFactory;
44 import org.jboss.tm.TransactionManagerLocator;
45
46 /**
47  * A service that implements this interface provides an Tx aware EJBTimerService.
48  *
49  * @author Thomas.Diesler@jboss.org
50  * @author Dimitris.Andreadis@jboss.org
51  * @version $Revision: 58307 $
52  * @since 07-Apr-2004
53  */

54 public class EJBTimerServiceImpl extends ServiceMBeanSupport
55    implements EJBTimerServiceImplMBean
56 {
57    // Logging support
58
private static Logger log = Logger.getLogger(EJBTimerServiceImpl.class);
59
60    // Attributes
61

62    // The object name of the retry policy
63
private ObjectName JavaDoc retryPolicyName;
64    // The object name of the persistence policy
65
private ObjectName JavaDoc persistencePolicyName;
66    // The TimerIdGenerator class name
67
private String JavaDoc timerIdGeneratorClassName;
68    // The TimedObjectInvoker class name
69
private String JavaDoc timedObjectInvokerClassName;
70    // The TransactionManagerFactory
71
private TransactionManagerFactory transactionManagerFactory;
72    
73    // Plug-ins
74

75    // The tx manager plug-in
76
private TransactionManager JavaDoc transactionManager;
77    // The retry policy plug-in
78
private RetryPolicy retryPolicy;
79    // The persistence policy plug-in
80
private PersistencePolicy persistencePolicy;
81    // The timerId generator plug-in
82
private TimerIdGenerator timerIdGenerator;
83    
84    // Maps the timedObjectId to TimerServiceImpl objects
85
private Map JavaDoc timerServiceMap = Collections.synchronizedMap(new HashMap JavaDoc());
86
87    // Attributes ----------------------------------------------------
88

89    /**
90     * Get the object name of the retry policy.
91     *
92     * @jmx.managed-attribute
93     */

94    public ObjectName JavaDoc getRetryPolicy()
95    {
96       return retryPolicyName;
97    }
98
99    /**
100     * Set the object name of the retry policy.
101     *
102     * @jmx.managed-attribute
103     */

104    public void setRetryPolicy(ObjectName JavaDoc retryPolicyName)
105    {
106       this.retryPolicyName = retryPolicyName;
107    }
108
109    /**
110     * Get the object name of the persistence policy.
111     *
112     * @jmx.managed-attribute
113     */

114    public ObjectName JavaDoc getPersistencePolicy()
115    {
116       return persistencePolicyName;
117    }
118
119    /**
120     * Set the object name of the persistence policy.
121     *
122     * @jmx.managed-attribute
123     */

124    public void setPersistencePolicy(ObjectName JavaDoc persistencePolicyName)
125    {
126       this.persistencePolicyName = persistencePolicyName;
127    }
128
129    /**
130     * Get the TimerIdGenerator class name
131     *
132     * @jmx.managed-attribute
133     */

134    public String JavaDoc getTimerIdGeneratorClassName()
135    {
136       return timerIdGeneratorClassName;
137    }
138
139    /**
140     * Get the TimerIdGenerator class name
141     *
142     * @jmx.managed-attribute
143     */

144    public void setTimerIdGeneratorClassName(String JavaDoc timerIdGeneratorClassName)
145    {
146       this.timerIdGeneratorClassName = timerIdGeneratorClassName;
147    }
148
149    /**
150     * Get the TimedObjectInvoker class name
151     *
152     * @jmx.managed-attribute
153     */

154    public String JavaDoc getTimedObjectInvokerClassName()
155    {
156       return timedObjectInvokerClassName;
157    }
158
159    /**
160     * Set the TimedObjectInvoker class name
161     *
162     * @jmx.managed-attribute
163     */

164    public void setTimedObjectInvokerClassName(String JavaDoc timedObjectInvokerClassName)
165    {
166       this.timedObjectInvokerClassName = timedObjectInvokerClassName;
167    }
168
169    /**
170     * Set the TransactionManagerFactory
171     */

172    public void setTransactionManagerFactory(TransactionManagerFactory factory)
173    {
174       this.transactionManagerFactory = factory;
175    }
176    
177    // ServiceMBeanSupport Lifecycle ---------------------------------
178

179    protected void startService() throws Exception JavaDoc
180    {
181       // Setup plugins, fall back to safe defaults
182

183       // Get the TransactionManager from the factory, fall-back to the locator
184
if (transactionManagerFactory != null)
185          transactionManager = transactionManagerFactory.getTransactionManager();
186       else
187          transactionManager = TransactionManagerLocator.getInstance().locate();
188       
189       // Get a proxy to the retry policy
190
try
191       {
192          retryPolicy = (RetryPolicy)MBeanProxyExt.create(RetryPolicy.class, getRetryPolicy(), server);
193       }
194       catch (Exception JavaDoc e)
195       {
196          log.error("Cannot obtain the implementation of a RetryPolicy", e);
197       }
198       
199       // Get a proxy to the persistence policy
200
try
201       {
202          persistencePolicy = (PersistencePolicy)MBeanProxyExt.create(PersistencePolicy.class, persistencePolicyName, server);
203       }
204       catch (Exception JavaDoc e)
205       {
206          log.warn("Cannot obtain the implementation of a PersistencePolicy, using NoopPersistencePolicy: " + e.toString());
207          persistencePolicy = new NoopPersistencePolicy();
208       }
209
210       // Get the timerId generator
211
try
212       {
213          Class JavaDoc timerIdGeneratorClass = getClass().getClassLoader().loadClass(timerIdGeneratorClassName);
214          timerIdGenerator = (TimerIdGenerator)timerIdGeneratorClass.newInstance();
215       }
216       catch (Exception JavaDoc e)
217       {
218          log.warn("Cannot obtain the implementation of a TimerIdGenerator, using BigIntegerTimerIdGenerator: " + e.toString());
219          timerIdGenerator = new BigIntegerTimerIdGenerator();
220       }
221    }
222    
223    protected void stopService()
224    {
225       // Cleanup plugins
226
transactionManager = null;
227       retryPolicy = null;
228       persistencePolicy = null;
229       timerIdGenerator = null;
230    }
231    
232    // EJBTimerService Operations ------------------------------------
233

234    /**
235     * Create a TimerService for a given TimedObjectId that lives in a JBoss Container.
236     * The TimedObjectInvoker is constructed from the invokerClassName.
237     *
238     * @param containerId The string identifier for a class of TimedObjects
239     * @param instancePk The rimary key for an instance of a TimedObject, may be null
240     * @param container The Container that is associated with the TimerService
241     * @return the TimerService
242     */

243    public TimerService JavaDoc createTimerService(ObjectName JavaDoc containerId, Object JavaDoc instancePk, Container container)
244    {
245       TimedObjectInvoker invoker = null;
246       try
247       {
248          TimedObjectId timedObjectId = new TimedObjectId(containerId, instancePk);
249          Class JavaDoc invokerClass = getClass().getClassLoader().loadClass(timedObjectInvokerClassName);
250          Constructor JavaDoc constr = invokerClass.getConstructor(new Class JavaDoc[]{TimedObjectId.class, Container.class});
251          invoker = (TimedObjectInvoker)constr.newInstance(new Object JavaDoc[]{timedObjectId, container});
252       }
253       catch (Exception JavaDoc e)
254       {
255          log.error("Cannot create TimedObjectInvoker: " + timedObjectInvokerClassName, e);
256          return null;
257       }
258
259       return createTimerService(containerId, instancePk, invoker);
260    }
261
262    /**
263     * Create a TimerService for a given TimedObjectId that is invoked through the given invoker
264     *
265     * @param containerId The string identifier for a class of TimedObjects
266     * @param instancePk The rimary key for an instance of a TimedObject, may be null
267     * @param invoker The TimedObjectInvoker
268     * @return the TimerService
269     */

270    public TimerService JavaDoc createTimerService(ObjectName JavaDoc containerId, Object JavaDoc instancePk, TimedObjectInvoker invoker)
271    {
272       TimedObjectId timedObjectId = new TimedObjectId(containerId, instancePk);
273       TimerServiceImpl timerService = (TimerServiceImpl)timerServiceMap.get(timedObjectId);
274       if (timerService == null)
275       {
276          timerService = new TimerServiceImpl(timedObjectId, invoker,
277                transactionManager, persistencePolicy, retryPolicy, timerIdGenerator);
278          log.debug("createTimerService: " + timerService);
279          timerServiceMap.put(timedObjectId, timerService);
280       }
281       return timerService;
282    }
283
284    /**
285     * Get the TimerService for a given TimedObjectId
286     *
287     * @param containerId The string identifier for a class of TimedObjects
288     * @param instancePk The rimary key for an instance of a TimedObject, may be null
289     * @return The TimerService, or null if it does not exist
290     */

291    public TimerService JavaDoc getTimerService(ObjectName JavaDoc containerId, Object JavaDoc instancePk)
292    {
293       TimedObjectId timedObjectId = new TimedObjectId(containerId, instancePk);
294       return (TimerServiceImpl)timerServiceMap.get(timedObjectId);
295    }
296
297    /**
298     * Remove the TimerService for a given containerId/pKey (TimedObjectId),
299     * along with any persisted timer information.
300     *
301     * This should be used for removing the TimerService and Timers
302     * associated with a particular entity bean, when it gets removed.
303     *
304     * @param containerId The string identifier for a class of TimedObjects
305     * @param pKey The primary key for an instance of a TimedObject, may be null
306     */

307    public void removeTimerService(ObjectName JavaDoc containerId, Object JavaDoc instancePk)
308    {
309       TimedObjectId timedObjectId = new TimedObjectId(containerId, instancePk);
310       // remove a single timer service
311
if (timedObjectId.getInstancePk() != null)
312       {
313          TimerServiceImpl timerService = (TimerServiceImpl)getTimerService(containerId, instancePk);
314          if (timerService != null)
315          {
316             log.debug("removeTimerService: " + timerService);
317             // don't keep persistent state about the timer
318
// this is really an entity->remove()
319
timerService.shutdown(false);
320             timerServiceMap.remove(timedObjectId);
321          }
322       }
323       else
324       {
325          // assume we don't want to keep timer state when the container
326
// gets undeployed, this is the legacy behaviour
327
removeTimerService(containerId, false);
328       }
329    }
330
331    /**
332     * Remove the TimerService for a given containerId.
333     *
334     * This should be used to remove the timer service and timers for
335     * any type of container (session, entity, message) at the time of
336     * undeployment.
337     *
338     * @param containerId The string identifier for a class of TimedObjects
339     * @param keepState Flag indicating whether timer persistent state should be kept or removed
340     */

341    public void removeTimerService(ObjectName JavaDoc containerId, boolean keepState) throws IllegalStateException JavaDoc
342    {
343       // remove all timers with the given containerId
344
Iterator JavaDoc it = timerServiceMap.entrySet().iterator();
345       while (it.hasNext())
346       {
347          Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
348          TimedObjectId key = (TimedObjectId)entry.getKey();
349          TimerServiceImpl timerService = (TimerServiceImpl)entry.getValue();
350          if (containerId.equals(key.getContainerId()))
351          {
352             log.debug("removeTimerService: " + timerService);
353             timerService.shutdown(keepState);
354             it.remove();
355          }
356       }
357    }
358    
359    /**
360     * Remove the TimerService for a given containerId/pKey (TimedObjectId).
361     *
362     * @param containerId The string identifier for a class of TimedObjects
363     * @param pKey The primary key for an instance of a TimedObject, may be null
364     * @param keepState Flag indicating whether timer persistent state should be kept or removed
365     */

366    public void removeTimerService(ObjectName JavaDoc containerId, Object JavaDoc instancePk, boolean keepState) throws IllegalStateException JavaDoc
367    {
368       // remove a single timer service
369
TimedObjectId timedObjectId = new TimedObjectId(containerId, instancePk);
370       if (timedObjectId.getInstancePk() != null)
371       {
372          TimerServiceImpl timerService = (TimerServiceImpl)getTimerService(containerId, instancePk);
373          if (timerService != null)
374          {
375             log.debug("removeTimerService: " + timerService);
376             timerService.shutdown(false);
377             timerServiceMap.remove(timedObjectId);
378          }
379       }
380       // remove all timers with the given containerId
381
else
382       {
383          Iterator JavaDoc it = timerServiceMap.entrySet().iterator();
384          while (it.hasNext())
385          {
386             Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
387             TimedObjectId key = (TimedObjectId)entry.getKey();
388             TimerServiceImpl timerService = (TimerServiceImpl)entry.getValue();
389             if (containerId.equals(key.getContainerId()))
390             {
391                log.debug("removeTimerService: " + timerService);
392                timerService.shutdown(keepState);
393                it.remove();
394             }
395          }
396       }
397    }
398    
399    /**
400     * Restore the persisted timers for a given ejb container
401     *
402     * @param containerId The ejb container id
403     * @param loader The classloader to use for loading the timers
404     */

405    public void restoreTimers(ObjectName JavaDoc containerId, ClassLoader JavaDoc loader) throws IllegalStateException JavaDoc
406    {
407       // find out all the persisted handles, for the specified container
408
List JavaDoc handles = persistencePolicy.listTimerHandles(containerId, loader);
409       
410       if (handles.isEmpty() == false)
411       {
412          // first remove the persisted handles from the db
413
for (Iterator JavaDoc i = handles.iterator(); i.hasNext(); )
414          {
415             TimerHandleImpl handle = (TimerHandleImpl)i.next();
416             persistencePolicy.deleteTimer(handle.getTimerId(), handle.getTimedObjectId());
417          }
418
419          // make a second pass to re-create the timers; use the container
420
// itself to retrieve the correct TimerService/ for each handle,
421
// then use the standard ejb timer API to recreate the timer
422
for (Iterator JavaDoc i = handles.iterator(); i.hasNext(); )
423          {
424             TimerHandleImpl handle = (TimerHandleImpl)i.next();
425             try
426             {
427                TimedObjectId targetId = handle.getTimedObjectId();
428                ContainerMBean container = (ContainerMBean)MBeanProxyExt.create(ContainerMBean.class, containerId, server);
429                TimerService JavaDoc timerService = container.getTimerService(targetId.getInstancePk());
430                timerService.createTimer(handle.getFirstTime(), handle.getPeriode(), handle.getInfo());
431             }
432             catch (Exception JavaDoc e)
433             {
434                log.warn("Unable to restore timer record: " + handle, e);
435             }
436          }
437       }
438    }
439    
440    // EJBTimerServiceImplMbean operations ---------------------------
441

442    /**
443     * List the timers registered with all TimerService objects
444     *
445     * @jmx.managed-operation
446     */

447    public String JavaDoc listTimers()
448    {
449       StringBuffer JavaDoc retBuffer = new StringBuffer JavaDoc();
450       Iterator JavaDoc it = timerServiceMap.entrySet().iterator();
451       while (it.hasNext())
452       {
453          Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
454          TimedObjectId timedObjectId = (TimedObjectId)entry.getKey();
455          retBuffer.append(timedObjectId + "\n");
456
457          TimerServiceImpl timerService = (TimerServiceImpl)entry.getValue();
458          Collection JavaDoc col = timerService.getAllTimers();
459          for (Iterator JavaDoc iterator = col.iterator(); iterator.hasNext();)
460          {
461             TimerImpl timer = (TimerImpl)iterator.next();
462             TimerHandleImpl handle = new TimerHandleImpl(timer);
463             retBuffer.append(" handle: " + handle + "\n");
464             retBuffer.append(" " + timer + "\n");
465          }
466       }
467       return retBuffer.toString();
468    }
469  
470 }
471
Popular Tags