package com.wiley.compbooks.brose.chapter10.office;

import java.io.*;
import org.omg.CORBA.*;
import org.omg.PortableServer.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;

public class BuildingServer 
{
    static ORB orb;
    static String filename;
    static BuildingImpl building = null;

    /**
     * serialize building and 
     * shutdown the server application 
     */
    
    public static void shutdown()
    {
        /* serialization must be performed before shutting down
           the ORB as the ORB is needed for object_to_string
           operations. */
        try
        {
            File f = new File(filename);
            FileOutputStream fout = new FileOutputStream(f);
            ObjectOutputStream out = 
                new ObjectOutputStream(fout);
		
            /* save state */
            out.writeObject((BuildingImpl)building);
        }
        catch( IOException io )
        {
            io.printStackTrace();
            System.err.println("Error opening output file "  + filename );
        }
        /* ok, we're done. */
        orb.shutdown(false);
    }

    public static void main(String[] args) 
    {
        String str_name;
	String buildingName;


        if( args.length != 1 ) 
	{
            System.out.println("Usage: java ...RoomServer building_name");
            System.exit( 1 );
	}

	buildingName = args[0];
	filename = "." + buildingName + "_rooms";

        try 
	{
	    //init
	    orb = ORB.init( args, null );
	    POA rootPOA = POAHelper.narrow( orb.resolve_initial_references( "RootPOA"));

	    /* create a user defined poa for the building */

	    org.omg.CORBA.Policy [] policies = new org.omg.CORBA.Policy[3];
	    policies[0] = rootPOA.create_id_assignment_policy(IdAssignmentPolicyValue.USER_ID);
	    policies[1] = rootPOA.create_lifespan_policy(LifespanPolicyValue.PERSISTENT);
	    policies[2] = rootPOA.create_servant_retention_policy(
                                                                  ServantRetentionPolicyValue.RETAIN);

	    POA buildingPOA = rootPOA.create_POA("BuildingPOA", rootPOA.the_POAManager(), policies);

	    for (int i=0; i<policies.length; i++) 
		policies[i].destroy();			

	    /* create another poa for the room objects */

	    policies = new org.omg.CORBA.Policy[4];

	    policies[0] = buildingPOA.create_id_assignment_policy(IdAssignmentPolicyValue.USER_ID);
	    policies[1] = buildingPOA.create_lifespan_policy(LifespanPolicyValue.PERSISTENT);
	    policies[2] = buildingPOA.create_request_processing_policy(
                                                                       RequestProcessingPolicyValue.USE_SERVANT_MANAGER);
	    policies[3] = buildingPOA.create_servant_retention_policy(
                                                                      ServantRetentionPolicyValue.NON_RETAIN);

	    POA roomPOA = buildingPOA.create_POA("RoomPOA", rootPOA.the_POAManager(), policies);

	    RoomLocator roomLocator = new RoomLocator();
	    roomPOA.set_servant_manager(roomLocator._this(orb));


	    for (int i=0; i<policies.length; i++) 
		policies[i].destroy();			

	    /* read persistent state from a fle */
	    try
	    {
		File f = new File( filename );
		if( f.exists() )
		{
		    FileInputStream f_in = new FileInputStream(f);
		    
		    if( f_in.available() > 0 )
		    {
			ObjectInputStream in = new ObjectInputStream(f_in);
			building = (BuildingImpl)in.readObject();
			in.close();
		    }
		    f_in.close();
		}
	    }
	    catch( Exception e )
	    {
		e.printStackTrace();
	    }	

	    if( building == null )
	    {
		building = new BuildingImpl( roomPOA, orb, buildingName );	
	    }
	    else
		building.init( roomPOA, orb );

	    buildingPOA.activate_object_with_id( "Building".getBytes(), building );
	    org.omg.CORBA.Object obj = buildingPOA.servant_to_reference( building );

	    rootPOA.the_POAManager().activate();

            // register with naming service
            str_name =  "RoomService/" + buildingName;

	    NamingContextExt root = 
		NamingContextExtHelper.narrow( orb.resolve_initial_references("NameService"));

	    try
	    {
		// make sure the context is  bound
		root.bind_new_context( root.to_name("RoomService" ));
	    }
	    catch( AlreadyBound ab )
	    { 
		// does not matter .
	    }
	    
            root.rebind( root.to_name( str_name), obj );

	
	    RoomGUI gui = new RoomGUI( building );

	    // wait for requests
	    System.out.println("Server up");

	    orb.run();


	    System.exit(0);
        }
	catch(UserException ue) 
	{
	    ue.printStackTrace();
	    System.err.println(ue);
        }
	catch(SystemException se) 
	{
	    se.printStackTrace();
	    System.err.println(se);
        }
    }
}
