// eg3_impl.java -- a server using the name service.

package UK.co.orl.omniorb;

import org.omg.CORBA.*;
import org.omg.CORBA.ORBPackage.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;

class eg3_impl {
  public static void main(String[] args) {
    ORB orb = ORB.init(args, null);

    echo_i myobj = new echo_i();
    orb.connect(myobj);

    try {
      bindObjectToName(orb, myobj);
    } catch (Throwable x) {
      System.exit(1);
    }

    Thread.currentThread().suspend();
  }

  static void bindObjectToName(ORB orb, org.omg.CORBA.Object obj)
  throws Exception {
        NamingContext rootContext;
    try {
      org.omg.CORBA.Object initServ;
      try {
	initServ = orb.resolve_initial_references("NameService");
      } catch (COMM_FAILURE x) {
	if (x.minor == 6)
	  // We probably haven't got a bootstrap server running.  Try
	  // doing what omniORB would do...
	  initServ =
	    OmniOrbConfig.resolve_omniorb_initial_references("NameService",
							     orb);
	else throw x;
      }
      rootContext = NamingContextHelper.narrow(initServ);
    } catch (org.omg.CORBA.ORBPackage.InvalidName x) {
      System.err.println("Service required is invalid [does not exist].");
      throw x;
    } catch (Exception x) {
      System.err.println("Caught a system exception finding the name " +
			 "service:");
      System.err.println(x);
      throw x;
    }

    try {
      // Bind a context called "test" to the root context:
      NameComponent[] contextName = {new NameComponent("test", "my_context")};
      NamingContext testContext;
      try {
	// Bind the context to root, and assign testContext to it:
	testContext = rootContext.bind_new_context(contextName);
      } catch (AlreadyBound x) {
	// If the context already exists, this exception will be raised.
	// In this case, just resolve the name and assign testContext
	// to the object returned:
	org.omg.CORBA.Object tmpobj;
	tmpobj = rootContext.resolve(contextName);
	testContext = NamingContextHelper.narrow(tmpobj);
	if (testContext == null) {
	  System.out.println("Failed to narrow naming context.");
	  throw new Exception();
	}
      }
      // Bind the object (obj) to testContext, naming it Echo:
      NameComponent[] objectName = {new NameComponent("Echo", "Object")};

      // Bind obj with name Echo to the testContext:
      try {
	testContext.bind(objectName, obj);
      } catch (AlreadyBound x) {
	testContext.rebind(objectName, obj);
      }
      // Note: Using rebind() will overwrite any Object previously bound 
      //       to /test/Echo with obj.
      //       Alternatively, bind() can be used, which will raise a
      //       CosNaming::NamingContext::AlreadyBound exception if the name
      //       supplied is already bound to an object.

      // Amendment: When using OrbixNames, it is necessary to first
      // try bind and then rebind, as rebind on it's own will throw a
      // NotFoundexception if the Name has not already been
      // bound. [This is incorrect behaviour - it should just bind].
    }
    catch (COMM_FAILURE x) {
    System.err.println("Caught system exception COMM_FAILURE, unable to " +
		       "contact the naming service.");
    throw new Exception();
    }
    catch (Throwable x) {
      System.err.println("Caught a system exception while using the naming " +
			 "service:");
      System.err.println(x);
      throw new Exception();
    }
  }
}
