package com.wiley.compbooks.brose.chapter9.dii;

import java.io.*;
import org.omg.CORBA.*;
import org.omg.CORBA.InterfaceDefPackage.*;
import org.omg.CosNaming.*;

public class DiiClient 
{

    public static void main(String args[]) 
    {	
        String line, ior = null;
	
        if( args.length > 0 )
        {
            if( args[0].equals("-f"))
            {
                try
                {
                    BufferedReader br = 
                        new BufferedReader ( new FileReader( args[1] ), 2048 );
				
                    line = br.readLine();
                    if ( line != null ) 
                    { 
                        ior = line;
                        while ( line != null ) 
                        { 
                            line = br.readLine();
                            if ( line != null ) ior= ior + line;
                        }
                    }
                } 
                catch ( IOException ioe )
                {
                    ioe.printStackTrace();
                    System.exit(1);
                }
            }
            else
            {
				// get stringified IOR from command line
                ior = new String( args[0] );
            }
        }

        try 
        {
            // initialize the ORB
            ORB orb = ORB.init( args, null );

            // get object reference
            org.omg.CORBA.Object obj = null;
            if( ior != null )
            {
                obj = orb.string_to_object( ior );
            }
            else 
            {
                NamingContextExt nc = NamingContextExtHelper.narrow( 
                                                                    orb.resolve_initial_references("NameService"));		
		
                if( nc == null )
                    throw new RuntimeException("narrow failed");
                obj = nc.resolve( nc.to_name("any.example"));
            }

            // browsing the Interface Repository

            // get interface definition from Interface Repository
            org.omg.CORBA.Object interfaceDefObj = obj._get_interface_def();
            if( interfaceDefObj == null )
            {
                System.out.println("No result from Interface Repository, cannot create DII call.");
                System.exit(1);
            }

            InterfaceDef if_def = InterfaceDefHelper.narrow( interfaceDefObj );

            if( if_def == null )
            {
                System.out.println("Narrow failed, exiting ...." ); 
                System.exit(1);
            }

            // get full interface dscription
            FullInterfaceDescription full_if_desc =
                if_def.describe_interface();

            int no_of_parameters;

            // print various information
            System.out.println("Querying the Interface Repository\n");

            System.out.println("interface " + full_if_desc.name + " has " + full_if_desc.operations.length + " operations and " + full_if_desc.attributes.length + " attributes." );


            System.out.println("interface " + full_if_desc.name + " {" );

            for( int i = 0; i < full_if_desc.attributes.length; i++ ) 
            {
                System.out.println("    attribute " + full_if_desc.attributes[i].name );
            }

            for( int i = 0; i < full_if_desc.operations.length; i++ ) 
            {
                no_of_parameters = full_if_desc.operations[i].parameters.length;

                System.out.println("    " +								   
                                   // print the type code of the operation's result
                                   full_if_desc.operations[i].result + " " +

                                   // print the name of the operation
                                   full_if_desc.operations[i].name + " ("
                                   );

                // define and initialise text representations
                // for parameter modes
                String mode, in, inout, out;
                in = new String("in");
                inout = new String("inout");
                out = new String("out");

                char last_char = ',';

                // print parameters of the operations
                for( int j = 0; j < no_of_parameters; j++ ) 
                {
                    // set the right text for the parameter mode
                    switch (full_if_desc.operations[i].parameters[j].mode.value() ) {
                    case ParameterMode._PARAM_IN:
                        mode = in; break;
                    case ParameterMode._PARAM_INOUT:
                        mode = inout; break;
                    case ParameterMode._PARAM_OUT:
                        mode = out; break;
                    default:
                        mode = new String("unknown mode");
                    }

                    // deal with separating commas
                    if( j == no_of_parameters - 1 )
                        last_char = ' ';

                    // print mode, type and name of the parameter
                    System.out.println("        " +
                                       mode + " " +
                                       full_if_desc.operations[i].parameters[j].type + " " +
                                       full_if_desc.operations[i].parameters[j].name + last_char
                                       );
                }
                System.out.println("    );");
            }
            System.out.println("\n};\n");
            /* use the DII to make an invocation */

            // create a very simple request first to check that the target still exists
            Request r = obj._request("_non_existent");
            r.set_return_type( orb.get_primitive_tc( org.omg.CORBA.TCKind.tk_boolean ));
            r.invoke();
            System.out.println("result of _non_existent():    " + r.result().value() );

            // Now call a type-specific operation
            System.out.println("Make a DII call for operation: " + 
                               full_if_desc.operations[0].name );

            // create request
            Request request = 
                obj._request(full_if_desc.operations[0].name );

            // create and initialise arg_list
            NVList arg_list = request.arguments();
            no_of_parameters = full_if_desc.operations[0].parameters.length;

            for( int i = 0; i < no_of_parameters; i++ ) 
            {
                Any argumentAny = orb.create_any();
                argumentAny.type( full_if_desc.operations[0].parameters[i].type );

                // add empty value
                arg_list.add_value(
                                   full_if_desc.operations[0].parameters[i].name,
                                   argumentAny, 
                                   full_if_desc.operations[0].parameters[i].mode.value() + 1 );
            }
			
            // set the request's return type
            request.set_return_type( full_if_desc.operations[0].result );

            // invoke request 
            request.invoke();

            // get result

            Any res_any = request.result().value();
            System.out.println("result:\n    " + res_any ); // VB-specific

            // get out parameters
            NVList nv_list = request.arguments();
            for( int i = 0; i < no_of_parameters; i++ )
            {
                System.out.println( nv_list.item( i ).name() +
                                    ":\n    " + nv_list.item( i ).value() );
            }
        }
        // catch exceptions
        catch(Bounds bex) {
            bex.printStackTrace();
        }
        catch(SystemException ex) {
            ex.printStackTrace();
        }
        catch(Exception ex) {
            ex.printStackTrace();
        }   
    }
}
