/* 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.soap;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Vector;

import org.apache.xmlrpc.XmlRpcHandler;
import org.jfox.ejb.EJBObjectId;
import org.jfox.ejb.Invocation;
import org.jfox.ejb.connector.ConnectorHelper;
import org.jfox.ejb.connector.ContainerRemote;
import org.jfox.ejb.connector.local.LOCALContainerService;
import org.jfox.ejb.meta.Protocol;
import org.jfox.framework.Registry;

/**
 * 通过 JRMP 转发给 JRMPContainerService 来执行
 *
 * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
 */

public class JRMPXmlRpcHandler implements XmlRpcHandler {
    private ContainerRemote stub = ConnectorHelper.lookupContainerInvoker(Protocol.JRMP);
//  private ContainerRemote local = LOCALContainerService.getInstance();

    public JRMPXmlRpcHandler() {

    }

    public Object execute(String string, Vector vector) throws Exception {
        Invocation invocation = (Invocation) unmarshelledObject((byte[]) vector.get(0));
        EJBObjectId objectId = invocation.getObjectId();

        // if soap servlet web server and the ejb container in same jvm, use LOCAL protocol
//    if(objectId.getIdentity().equals(ObjectId.CONTAINER_IDENTITY)) {
        if(objectId.isCurrentVM()) {
            ContainerRemote local = (ContainerRemote) (Registry.getInstance().getFirstComponentMetabyImplemetation(LOCALContainerService.class).getComponentInstance());
            return marshelledObject((Serializable) local.invoke(invocation));
        }
        // if not int same jvm, use JRMP protocol
        else {
            return marshelledObject((Serializable) stub.invoke(invocation));
        }
    }

    public static Object unmarshelledObject(byte[] bytes) {
        try {
            ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes));
            Object obj = in.readObject();
            in.close();
            return obj;
        }
        catch(Exception e) {
            e.printStackTrace();
            return bytes;
        }
    }

    public static byte[] marshelledObject(Serializable obj) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            ObjectOutputStream oos = new ObjectOutputStream(out);
            oos.writeObject(obj);
            oos.flush();
        }
        catch(IOException e) {
            e.printStackTrace();
        }
        return out.toByteArray();
    }

    public static void main(String[] args) {

    }
}