package org.jboss.ejb.txtimer;
import org.jboss.ejb.Container;
import org.jboss.logging.Logger;
import org.jboss.mx.util.MBeanProxy;
import org.jboss.mx.util.MBeanServerLocator;
import org.jboss.system.ServiceMBeanSupport;
import javax.ejb.Timer;
import javax.ejb.TimerService;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.reflect.Constructor;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class EJBTimerServiceImpl
extends ServiceMBeanSupport
implements EJBTimerServiceImplMBean
{
private static Logger log = Logger.getLogger(EJBTimerServiceImpl.class);
private Map timerServiceMap = Collections.synchronizedMap(new HashMap());
private ObjectName retryPolicyName;
private ObjectName persistencePolicyName;
private String timerIdGeneratorClassName;
private String timedObjectInvokerClassName;
public ObjectName getRetryPolicy()
{
return retryPolicyName;
}
public void setRetryPolicy(ObjectName retryPolicyName)
{
this.retryPolicyName = retryPolicyName;
}
public ObjectName getPersistencePolicy()
{
return persistencePolicyName;
}
public void setPersistencePolicy(ObjectName persistencePolicyName)
{
this.persistencePolicyName = persistencePolicyName;
}
public String getTimerIdGeneratorClassName()
{
return timerIdGeneratorClassName;
}
public void setTimerIdGeneratorClassName(String timerIdGeneratorClassName)
{
this.timerIdGeneratorClassName = timerIdGeneratorClassName;
}
public String getTimedObjectInvokerClassName()
{
return timedObjectInvokerClassName;
}
public void setTimedObjectInvokerClassName(String timedObjectInvokerClassName)
{
this.timedObjectInvokerClassName = timedObjectInvokerClassName;
}
public TimerService createTimerService(ObjectName containerId, Object instancePk, Container container)
{
TimedObjectInvoker invoker = null;
try
{
TimedObjectId timedObjectId = new TimedObjectId(containerId, instancePk);
Class invokerClass = getClass().getClassLoader().loadClass(timedObjectInvokerClassName);
Constructor constr = invokerClass.getConstructor(new Class[]{TimedObjectId.class, Container.class});
invoker = (TimedObjectInvoker)constr.newInstance(new Object[]{timedObjectId, container});
}
catch (Exception e)
{
log.error("Cannot create TimedObjectInvoker: " + timedObjectInvokerClassName, e);
return null;
}
return createTimerService(containerId, instancePk, invoker);
}
public TimerService createTimerService(ObjectName containerId, Object instancePk, TimedObjectInvoker invoker)
{
TimedObjectId timedObjectId = new TimedObjectId(containerId, instancePk);
TimerServiceImpl timerService = (TimerServiceImpl)timerServiceMap.get(timedObjectId);
if (timerService == null)
{
timerService = new TimerServiceImpl(timedObjectId, invoker);
log.debug("createTimerService: " + timerService);
timerServiceMap.put(timedObjectId, timerService);
}
return timerService;
}
public TimerService getTimerService(ObjectName containerId, Object instancePk)
{
TimedObjectId timedObjectId = new TimedObjectId(containerId, instancePk);
return (TimerServiceImpl)timerServiceMap.get(timedObjectId);
}
public void retryTimeout(ObjectName containerId, Object instancePk, Timer timer)
{
TimedObjectId timedObjectId = new TimedObjectId(containerId, instancePk);
TimerServiceImpl timerService = (TimerServiceImpl)timerServiceMap.get(timedObjectId);
if (timerService != null)
{
try
{
TimedObjectInvoker invoker = timerService.getTimedObjectInvoker();
MBeanServer server = MBeanServerLocator.locateJBoss();
RetryPolicy retryPolicy = (RetryPolicy)MBeanProxy.get(RetryPolicy.class, getRetryPolicy(), server);
retryPolicy.retryTimeout(invoker, timer);
}
catch (Exception e)
{
log.error("Retry timeout failed: " + e);
}
}
}
public void removeTimerService(ObjectName containerId, Object instancePk)
{
TimedObjectId timedObjectId = new TimedObjectId(containerId, instancePk);
if (timedObjectId.getInstancePk() != null)
{
TimerServiceImpl timerService = (TimerServiceImpl)getTimerService(containerId, instancePk);
if (timerService != null)
{
log.debug("removeTimerService: " + timerService);
timerService.killAllTimers();
timerServiceMap.remove(timedObjectId);
}
}
else
{
Iterator it = timerServiceMap.entrySet().iterator();
while (it.hasNext())
{
Map.Entry entry = (Map.Entry)it.next();
TimedObjectId key = (TimedObjectId)entry.getKey();
TimerServiceImpl timerService = (TimerServiceImpl)entry.getValue();
if (containerId.equals(key.getContainerId()))
{
log.debug("removeTimerService: " + timerService);
timerService.killAllTimers();
it.remove();
}
}
}
}
public String listTimers()
{
StringBuffer retBuffer = new StringBuffer();
Iterator it = timerServiceMap.entrySet().iterator();
while (it.hasNext())
{
Map.Entry entry = (Map.Entry)it.next();
TimedObjectId timedObjectId = (TimedObjectId)entry.getKey();
retBuffer.append(timedObjectId + "\n");
TimerServiceImpl timerService = (TimerServiceImpl)entry.getValue();
Collection col = timerService.getAllTimers();
for (Iterator iterator = col.iterator(); iterator.hasNext();)
{
TimerImpl timer = (TimerImpl)iterator.next();
TimerHandleImpl handle = new TimerHandleImpl(timer);
retBuffer.append(" handle: " + handle + "\n");
retBuffer.append(" " + timer + "\n");
}
}
return retBuffer.toString();
}
}