/* Philosophy: RIDL_Naming does one thing- 
   We store the Remote holder version of an Object -- the two are indistinguishable

*/
package RIDL_Runtime;

import java.rmi.*; 

public class RIDL_Naming 
  extends java.rmi.server.UnicastRemoteObject 
  implements  RIDL_RN {

  /* These are called locally */

  public static RIDL_Object lookup(String host, int port, String name) 
    throws RemoteException {
//      System.err.println("looking up "+name); 
      get_reg(host,port); 
      RIDL_Object h = rn.lookup(name);
//      System.err.println("looked up "+h); 
      return h;
  }

  public static void bind(String host, int port, String name, RIDL_Object obj)
    throws RemoteException {
      get_reg(host,port); 
      rn.bind(name,obj._make_fake()); 
  }  

  public static void unbind(String host, int port, String name) 
    throws RemoteException {
      get_reg(host,port); 
      rn.unbind(name); 
  }
  /*    
  public static void rebind(String host, int port, String name, RIDL_Object obj) 
    throws RemoteException {
      get_reg(host,port);
      rn.rebind(name,obj._make_fake()); 
  }
  */
  public static String[] list(String host, int port) 
    throws RemoteException {
      get_reg(host,port); 
      return rn.list(); 
  }


  private static String lastinst; 
  private static RIDL_RN rn;   

  private static void get_reg(String host, int port)  {
    try {
      String hostport = host+":"+port;
      if ((!hostport.equals(lastinst)) || (rn==null)) {
	lastinst = hostport; 
	rn = (RIDL_RN) Naming.lookup("rmi://"+lastinst+"/RIDL_Naming");
      }
    } catch (RemoteException e) {
      System.err.println("Remote error occurred when accessing naming server on "+host+":"+port);
      e.printStackTrace();
      System.exit(1);
    } catch (Exception e) {
      System.err.println("Could not find remote naming server on "+host+":"+port+".\n"+
			 " Is a instantiation server running on that machine?");
      e.printStackTrace();
      System.exit(1);
    }
  }
  /* INIT */

  public RIDL_Naming() throws java.rmi.RemoteException {}; 

  java.util.Hashtable hashtable  = new java.util.Hashtable(); 

  public static void main(String[] args) {
    /* this does just that: 
       A) startup a new registry, 
       B) bind an instance of RIDL_Naming to it
       C) hang around for ever
       */

    /* The args MUST be just an Int: the port number for the registry */
    if (args.length != 1) {
      System.err.println("RIDL_Naming remote naming server\n Usage: java RIDL_Naming <portno>");
      System.exit(1);
    }
    
    int port = Integer.parseInt(args[0]);
    try {
      /* Not in 1.2! 
	 http://archives.java.sun.com/cgi-bin/wa?A2=ind9807&L=rmi-users&D=0&P=30490
	 */
//      System.setSecurityManager(new RMISecurityManager());

      java.rmi.registry.Registry r = java.rmi.registry.LocateRegistry.createRegistry(port);
      System.err.println("made the registry");
      RIDL_Naming rn = new RIDL_Naming();
      RIDL_RemoteInst ri = new RIDL_RemoteInst();
      r.rebind("RIDL_RemoteInst", ri);
      r.rebind("RIDL_Naming", rn); 
      System.err.println("bound the RIDL_Naming obj");

    } catch (RemoteException e) {
      e.printStackTrace();
      System.exit(1);
    } 
  }
  /* REMOTE Functions */

      /* these are on the remote host, where the registry lives */
  public RIDL_Object lookup(String name) 
    throws RemoteException {
//      System.err.println("looking up "+name); 
      Object o = hashtable.get(name);
//      System.err.println("found "+o); 
      return (RIDL_Object) o;
  }

  public void bind(String name,RIDL_Object r) 
    throws RemoteException {
//      System.err.println("binding "+name+": "+r.toString()); 
      hashtable.put(name,r);
  }

  public void unbind(String name) 
    throws RemoteException {
      hashtable.remove(name); 
  }
  /*
  public void rebind(String name, RIDL_Object obj) 
    throws RemoteException {
//      System.err.println("binding "+obj+" as "+name); 
      hashtable.put(name,obj); 
  }
  */
  public String[] list() 
    throws RemoteException {
      String[] strs = new String[hashtable.size()];
      int i = 0; 
      java.util.Enumeration e = hashtable.keys();
      while (e.hasMoreElements())
	strs[i++]=(String) e.nextElement(); 
      return strs; 
  }
    
    
}



