package org.jfox.ejb.timer;

import java.io.Serializable;
import java.util.TimerTask;
import javax.ejb.EJBException;
import javax.ejb.TimedObject;
import javax.ejb.Timer;

import org.jfox.ejb.Bucket;
import org.jfox.ejb.ContainerImpl;
import org.jfox.ejb.EJBObjectId;
import org.jfox.ejb.Invocation;
import org.jfox.ejb.InvocationImpl;
import org.jfox.ejb.MethodHasher;
import org.jfox.ejb.connector.ContainerRemote;
import org.jfox.ejb.connector.local.LOCALContainerService;
import org.jfox.framework.Registry;

/**
 * @author <a href="mailto:yangyong@ufsoft.com.cn">Young Yang</a>
 */

public class EJBTimerTask extends TimerTask {

    private EJBTimerService timerService;
    private EJBTimer timer;


    public EJBTimerTask(EJBTimerService timerService, Serializable info) {
        this.timerService = timerService;
        timer = new EJBTimer(this, info);
    }

    public Timer getTimer() {
        return timer;
    }

    public void run() {
        String ejbName = timerService.getEjbName();
        Bucket bucket = ContainerImpl.getInstance().getBucket(ejbName);

        if(!TimedObject.class.isAssignableFrom(bucket.getBeanClass())) {
            throw new EJBException("ejb " + ejbName + " not implements " + TimedObject.class.getName());
        }
        // bucause Timer used by StatelessBean, so objectId can be random
        EJBObjectId objectId = bucket.nextObjectId();
        Invocation invocation = new InvocationImpl(objectId, "" + MethodHasher.getMethodHash(TimedObjectMethod.TimeOut), new Object[]{timer});

        try {
            // use LOCALContainerService invoke the timout
            ContainerRemote local = (ContainerRemote) (Registry.getInstance().getFirstComponentMetabyImplemetation(LOCALContainerService.class).getComponentInstance());
            local.invoke(invocation);
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }

    public boolean cancel() {
        timerService.cancel(this);
        return super.cancel();
    }

    EJBTimerService getTimerService() {
        return timerService;
    }

    public static void main(String[] args) {

    }
}

