/* JFox, the OpenSource J2EE Application Server
 *
 * Distributable under GNU LGPL license by gun.org
 * more details please visit http://www.huihoo.org/jfox
 */

package org.jfox.ejb.connector.jrmp;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import javax.ejb.EJBException;

import org.jfox.ejb.Invocation;
import org.jfox.ejb.connector.ConnectorHelper;
import org.jfox.ejb.connector.ContainerRemote;
import org.jfox.ejb.connector.ContainerServiceSupport;
import org.jfox.ejb.meta.Protocol;
import org.jfox.framework.extra.Managable;
import org.jfox.framework.extra.ManagementInfo;

/**
 * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
 */

public class JRMPContainerService extends ContainerServiceSupport implements ContainerRemote, Managable {

    // invoker stub
    private Remote stub = null;
    private Protocol protocol = Protocol.JRMP;

    protected void doInit() throws Exception {
        super.doInit();
        try {
            UnicastRemoteObject.unexportObject(this, true);
        }
        catch(Exception e) {
            // ignore
        }
    }

    /**
     * export this invoker and set container's invoker to this stub
     *
     * @throws Exception
     */
    protected void doStart() throws Exception {
        stub = UnicastRemoteObject.exportObject(this);
        INITIAL_CONTEXT.rebind(ConnectorHelper.getJNDIName(protocol), stub);
        // 启动一个线程，用来每隔一段时间 ping 一下，防止 rmi 线程死掉
        Thread pingThread = new Thread(this, getClass().getName());
        pingThread.setPriority(Thread.MIN_PRIORITY);
        pingThread.start();
    }

    protected void doStop() throws Exception {
        INITIAL_CONTEXT.unbind(ConnectorHelper.getJNDIName(protocol));
        UnicastRemoteObject.unexportObject(this, false);
    }

    protected synchronized void doDestroy() throws Exception {
        stub = null;
    }

    /**
     * just forward to container
     * 应该把客户的调用组装成一个 invocation 对象
     */
    public Object invoke(Invocation invocation) throws RemoteException {
        logger.debug("invoke " + invocation.toString());
        try {
            return container.invoke(invocation);
        }
        catch(RemoteException e) {
            logger.error(e.getMessage(), e);
            throw e;
        }
        catch(Exception e) {
            logger.error(e.getMessage(), e);
            throw new EJBException(e);
        }
    }

    public ManagementInfo getManagementInfo() {
        return ManagementInfo.exposePublic(JRMPContainerService.class);
    }

    public static void main(String[] args) throws Exception {

    }
}