package com.mindprod.example;

import java.io.*;

/**
 * Demonstrate how to spawn a non-Java utility and communicate with it.
 * <p/>
 * composed with IntelliJ IDEA
 *
 * @author Roedy Green, Canadian Mind Products
 * @version 1.0, 2007-11-30
 */
@SuppressWarnings( { "UnusedAssignment" } )
public class Spawner
    {
// --------------------------- main() method ---------------------------

    /**
     * main method
     *
     * @param args not used
     */
    public static void main( String[] args )
        {
        // we spawn blout.exe with parameter E:/temp/temp.txt
        // Modify this to some utility on your own computer.
        ProcessBuilder pb = new ProcessBuilder( "fictitious.exe", "E:/temp/temp.txt" );

        // set up the working directory.
        // Note the method is called "directory" not "setDirectory"
        pb.directory( new File( "E:/sys" ) );

        // Merge child's error and normal output streams.
        // Note the method is called "redirectErrorStream" not "setRedirectErrorStream".
        pb.redirectErrorStream( true );

        try
            {
            // trigger the spawn, creating Process object for controlling child.
            final Process p = pb.start();
            // From here on in, item behaves just like exec, since you have the
            // exact same Process object.

            // Spawn thread to read output of spawned program
            new Thread()
            {
            @SuppressWarnings( { "EmptyCatchBlock" } )
            public void run()
                {
                // hook into output from spawned program
                final InputStream is = p.getInputStream();
                final InputStreamReader isr = new InputStreamReader( is );
                final BufferedReader br = new BufferedReader( isr, 100/* buffsize in chars */ );
                String line;
                try
                    {
                    try
                        {
                        // C/C++ can write this with putc
                        while ( ( line = br.readLine() ) != null )
                            {
                            System.out.println( line );

                            }
                        }
                    catch ( EOFException e )
                        {
                        }
                    br.close();
                    }
                catch ( IOException e )
                    {
                    System.err.println( "problem reading spawn output" + e.getMessage() );
                    System.exit( 1 );
                    }
                // returning from run kills the thread.
                }
            }.start();

            // Spawn thread to write input to the spawned program
            new Thread()
            {
            public void run()
                {
                // hook into input to spawned program
                final OutputStream os = p.getOutputStream();
                final OutputStreamWriter osw = new OutputStreamWriter( os );
                final BufferedWriter bw = new BufferedWriter( osw, 100/* buffsize in chars */ );
                String line;
                try
                    {
                    // C/C++ can read this with getc
                    bw.write( "some text\n" );
                    bw.write( "some more text\n" );
                    bw.close();
                    }
                catch ( IOException e )
                    {
                    System.err.println( "problem writing spawn input" + e.getMessage() );
                    System.exit( 1 );
                    }
                // returning from run kills the thread.
                }
            }.start();

            try
                {
                // wait for spawned program to terminate.
                p.waitFor();
                }

            catch ( InterruptedException e )
                {
                Thread.currentThread().interrupt();
                }
            // child has terminated.

            // You must close these even if you never use them!
            p.getInputStream().close();
            p.getOutputStream().close();
            p.getErrorStream().close();
            }
        catch ( IOException e )
            {
            System.err.println( "spawning problem " + e.getMessage() );
            System.exit( 1 );
            }
        }
    }