package org.jboss.ejb.txtimer;
import org.jboss.logging.Logger;
import org.jboss.mx.util.MBeanProxy;
import org.jboss.mx.util.MBeanServerLocator;
import org.jboss.tm.TxManager;
import javax.ejb.EJBException;
import javax.ejb.Timer;
import javax.ejb.TimerHandle;
import javax.ejb.TimerService;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.naming.InitialContext;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class TimerServiceImpl implements TimerService
{
private static Logger log = Logger.getLogger(TimerServiceImpl.class);
private TransactionManager transactionManager;
private PersistencePolicy persistencePolicy;
private TimedObjectId timedObjectId;
private TimedObjectInvoker timedObjectInvoker;
private TimerIdGenerator timerIdGenerator;
private Map timers = new HashMap();
public TimerServiceImpl(TimedObjectId timedObjectId, TimedObjectInvoker timedObjectInvoker)
{
this.timedObjectId = timedObjectId;
this.timedObjectInvoker = timedObjectInvoker;
try
{
InitialContext iniCtx = new InitialContext();
transactionManager = (TransactionManager)iniCtx.lookup("java:/TransactionManager");
}
catch (Exception e)
{
log.warn("Cannot obtain TransactionManager from JNDI: " + e.toString());
transactionManager = TxManager.getInstance();
}
try
{
MBeanServer server = MBeanServerLocator.locateJBoss();
ObjectName persistencePolicyName = (ObjectName)server.getAttribute(EJBTimerService.OBJECT_NAME, "PersistencePolicy");
persistencePolicy = (PersistencePolicy)MBeanProxy.get(PersistencePolicy.class, persistencePolicyName, server);
}
catch (Exception e)
{
log.warn("Cannot obtain the implementation of a PersistencePolicy: " + e.toString());
persistencePolicy = new NoopPersistencePolicy();
}
try
{
MBeanServer server = MBeanServerLocator.locateJBoss();
String timerIdGeneratorClassName = (String)server.getAttribute(EJBTimerService.OBJECT_NAME, "TimerIdGeneratorClassName");
Class timerIdGeneratorClass = getClass().getClassLoader().loadClass(timerIdGeneratorClassName);
timerIdGenerator = (TimerIdGenerator)timerIdGeneratorClass.newInstance();
}
catch (Exception e)
{
log.warn("Cannot obtain the implementation of a TimerIdGenerator: " + e.toString());
timerIdGenerator = new BigIntegerTimerIdGenerator();
}
}
public Timer createTimer(long duration, Serializable info) throws IllegalArgumentException, IllegalStateException, EJBException
{
if (duration < 0)
throw new IllegalArgumentException("duration is negative");
return createTimer(new Date(System.currentTimeMillis() + duration), 0, info);
}
public Timer createTimer(long initialDuration, long intervalDuration, Serializable info) throws IllegalArgumentException, IllegalStateException, EJBException
{
if (initialDuration < 0)
throw new IllegalArgumentException("initial duration is negative");
if (intervalDuration < 0)
throw new IllegalArgumentException("interval duration is negative");
return createTimer(new Date(System.currentTimeMillis() + initialDuration), intervalDuration, info);
}
public Timer createTimer(Date expiration, Serializable info) throws IllegalArgumentException, IllegalStateException, EJBException
{
if (expiration == null)
throw new IllegalArgumentException("expiration is null");
return createTimer(expiration, 0, info);
}
public Timer createTimer(Date initialExpiration, long intervalDuration, Serializable info) throws IllegalArgumentException, IllegalStateException, EJBException
{
if (initialExpiration == null)
throw new IllegalArgumentException("initial expiration is null");
if (intervalDuration < 0)
throw new IllegalArgumentException("interval duration is negative");
try
{
String timerId = timerIdGenerator.nextTimerId();
TimerImpl timer = new TimerImpl(timerId, timedObjectId, timedObjectInvoker, info);
persistencePolicy.insertTimer(timerId, timedObjectId, initialExpiration, intervalDuration, info);
timer.startTimer(initialExpiration, intervalDuration);
return timer;
}
catch (Exception e)
{
log.error("Cannot create txtimer", e);
return null;
}
}
public Collection getTimers() throws IllegalStateException, EJBException
{
ArrayList activeTimers = new ArrayList();
synchronized (timers)
{
Iterator it = timers.values().iterator();
while (it.hasNext())
{
TimerImpl timer = (TimerImpl)it.next();
if (timer.isActive())
activeTimers.add(timer);
}
}
return activeTimers;
}
public Collection getAllTimers()
{
synchronized (timers)
{
return new ArrayList(timers.values());
}
}
public Timer getTimer(TimerHandle handle)
{
TimerImpl timer = (TimerImpl)timers.get(handle);
if (timer != null && timer.isActive())
return timer;
else
return null;
}
public void killTimer(TimerHandle handle)
{
TimerImpl timer = (TimerImpl)timers.get(handle);
if (timer != null)
{
removeTimer(timer);
timer.killTimer();
}
}
public void killAllTimers()
{
synchronized (timers)
{
Iterator it = timers.values().iterator();
while (it.hasNext())
{
TimerImpl timer = (TimerImpl)it.next();
it.remove();
timer.killTimer();
}
}
}
public TimedObjectInvoker getTimedObjectInvoker()
{
return timedObjectInvoker;
}
public Transaction getTransaction()
{
try
{
return transactionManager.getTransaction();
}
catch (SystemException e)
{
return null;
}
}
void addTimer(TimerImpl txtimer)
{
synchronized (timers)
{
TimerHandle handle = new TimerHandleImpl(txtimer);
timers.put(handle, txtimer);
}
}
void removeTimer(TimerImpl txtimer)
{
synchronized (timers)
{
persistencePolicy.deleteTimer(txtimer.getTimerId(), txtimer.getTimedObjectId());
timers.remove(new TimerHandleImpl(txtimer));
}
}
}