/* 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.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.HttpURLConnection;
import java.net.URL;
import java.rmi.RemoteException;
import java.util.Vector;

import org.apache.xmlrpc.XmlRpcClientLite;
import org.apache.xmlrpc.XmlRpcHandler;
import org.jfox.ejb.Invocation;
import org.jfox.ejb.connector.ContainerRemote;

/**
 * SOAPContainerServiceBinder use to bound in jndi, so client can lookup it to client side,
 * after look down, can use it to invoke soap protocol
 * <p/>
 * it's a Serializable class, readObject method is be overwrote
 *
 * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
 */

public class SOAPContainerServiceBinder implements ContainerRemote, Serializable {
    private transient XmlRpcHandler client;
    private String soapURL;

    public SOAPContainerServiceBinder(String soapUrl) {
        this.soapURL = soapUrl;
        try {
            client = new XmlRpcClientLite(soapUrl);
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }

    public Object invoke(Invocation invocation) throws RemoteException {
        Vector params = new Vector(1);
        params.add(marshelledObject(invocation));
        try {
            // handler can be any String, because has use $default handle in server side
            return client.execute("xmlrpc", params);
        }
        catch(Exception e) {
            throw new RemoteException(e.getMessage(), e);
        }

    }

    /**
     * after lookup, re initialize XmlRpcClient according as the soap servlet url
     *
     * @param in
     * @throws IOException
     * @throws ClassNotFoundException
     */
    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        client = new XmlRpcClientLite(soapURL);
    }

    public void ping() throws RemoteException {
        HttpURLConnection conn = null;
        try {
            conn = (HttpURLConnection) new URL(soapURL).openConnection();
        }
        catch(Exception e) {
            throw new RemoteException("can't get connection with the soap url: " + soapURL, e);
        }
        finally {
            if(conn != null) {
                try {
                    conn.disconnect();
                }
                catch(Exception e) {
                }
            }
        }
//    System.out.println("SOAPContainerServiceBinder: I'm alive :)   " + new Date());
    }

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

    public static void main(String[] args) {

    }
}