package RIDL_Runtime;
public class RIDL_RemoteInst 
  extends java.rmi.server.UnicastRemoteObject 
  implements RIDL_RI {

  /* This is a remote instantiation service that only supports anonymous objects created on remote hosts. */

  public RIDL_RemoteInst() throws java.rmi.RemoteException {}

  private static String lastinst; 
  private static RIDL_RI ri;   

  public static RIDL_Object remotenew(String classname, String host, int port) {
    /* The host:port needs to correspond to a RIDL_RIServer host:port. The object 
       will be instantiated by invoking the no-arg constructor.
       */ 
    System.err.println("remote new: "+classname);
    try {
      String hostport = host+":"+port;
      if ((!hostport.equals(lastinst)) || (ri==null)) {
	lastinst = hostport; 
	ri = (RIDL_RI) java.rmi.Naming.lookup("rmi://"+lastinst+"/RIDL_RemoteInst");
      }
      System.err.println("found server on "+host+":"+port); 
      RIDL_Object h = ri.makeinstance(classname); 
      return h;
    } catch (ClassNotFoundException e) {
      System.err.println("Could not instantiate "+classname+" on "+host+":"+port+".\n"+
			 " Is the class in the CLASSPATH of the instantiation server running on that machine?");
      e.printStackTrace();
      System.exit(1);
    } catch (java.rmi.ServerException e) {
      System.err.println("Could not export "+classname+" from "+host+":"+port+".\n"+
			 " Is the skeleton class in the CLASSPATH of the instantiation server running on that machine?");
      e.printStackTrace();
      System.exit(1);
    } catch (Exception e) {
      System.err.println("Could not instantiate "+classname+" on "+host+":"+port+".\n"+
			 " Is a instantiation server running on that machine?");
      e.printStackTrace();
      System.exit(1);
    }
    return null;

  }

  // as per RIDL_RI interface

  public  RIDL_Object makeinstance(String classname) 
    throws java.rmi.RemoteException,
           ClassNotFoundException, InstantiationException, IllegalAccessException {
    System.err.println("remote new: "+classname); 
    RIDL_Object real  = (RIDL_Object) Class.forName(classname).newInstance();
    System.err.println("made "+classname);
    return real._make_fake(); 
  }


  public static void main(String[] args) {
    /* this does just that: 
       A) startup a new registry, 
       B) bind an instance of RIDL_RemoteInst 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_RemoteInst remote instantiation server\n Usage: java RIDL_RemoteInst <portno>");
      System.exit(1);
    }
    
    int port = Integer.parseInt(args[0]);
    try {
      // not in 1.2 it isn't
//      System.setSecurityManager(new java.rmi.RMISecurityManager());
      java.rmi.registry.Registry r = java.rmi.registry.LocateRegistry.createRegistry(port);
      System.err.println("made the registry- for one whole object. What a waste");
      RIDL_RemoteInst rn = new RIDL_RemoteInst();
      r.rebind("RIDL_RemoteInst", rn);
      System.err.println("bound the RIDL_RemoteInst obj");

    } catch (java.rmi.RemoteException e) {
      e.printStackTrace();
      System.exit(1);
    }
  }

}



