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

import java.io.BufferedInputStream;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import javax.naming.CommunicationException;
import javax.rmi.PortableRemoteObject;

//import javax.rmi.PortableRemoteObject;
//import javax.rmi.CORBA.Stub;

/**
 * cache and get remote NamingService stub
 *
 * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
 */

class ServiceLocator {
    private static Map services = new HashMap();
//  private static ORB orb = ORB.init(new String[0],null);

    /**
     * get NamingService Remote Reference from the host:port
     */
    public static NamingService getNamingService(String host, int port)
            throws CommunicationException {
        if(services.containsKey(genKey(host, port))) { // return from cache
            try {
//        return (NamingService)PortableRemoteObject.narrow(((MarshalledObject)services.get(genKey(host,port))).get(),NamingService.class);
//        return (NamingService)(((MarshalledObject)services.get(genKey(host,port))).get());
                return (NamingService) services.get(genKey(host, port));
            }
            catch(Exception e) {
                services.remove(genKey(host, port));
                e.printStackTrace();
                throw new CommunicationException(e.getMessage());
            }
        }
        else {
            try {
                Socket csocket = new Socket(host, port);
                ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(csocket.getInputStream()));
                Object obj = in.readObject();
                csocket.close();
//        MarshalledObject mobj = (MarshalledObject)obj;
//        NamingService stub = (NamingService)mobj.get();
//        NamingService stub = (NamingService)PortableRemoteObject.narrow(mobj.get(),NamingService.class);
//        ((Stub)stub).connect(orb);
                NamingService stub = (NamingService) PortableRemoteObject.narrow(obj, NamingService.class);
                services.put(genKey(host, port), obj);
                return stub;
            }
            catch(Exception e) {
                e.printStackTrace();
                services.remove(genKey(host, port));
                throw new CommunicationException(e.getMessage());
            }
        }

    }

    public static NamingService getNamingService(String privoderURL) throws CommunicationException {
        int index = privoderURL.indexOf("://");
        if(index > 0) {
            privoderURL = privoderURL.substring(index + 3);
        }
        index = privoderURL.indexOf(':');

        String host = privoderURL.substring(0, index);
        String port = privoderURL.substring(index + 1);

        int p = Integer.parseInt(port);
        return getNamingService(host, p);
    }

    private static String genKey(String host, int port) {
        return host + ":" + port;
    }

    public static void main(String[] args) throws Exception {
        getNamingService("java://localhost:1099");
    }

}
