package com.trendmicro.mist; import java.io.InputStream; import java.io.OutputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.io.InputStreamReader; import java.io.BufferedReader; import java.io.PrintStream; import java.io.IOException; import java.util.ArrayList; abstract public class ThreadInvoker implements Runnable { protected InputStream myIn; protected PrintStream myOut; protected PrintStream myErr; protected int exitCode = 0; protected boolean inputReplaced = false; protected boolean outputReplaced = false; protected boolean errorReplaced = false; private String myArg; private Thread myThread; private String invokerName; private class OutputHooker implements Runnable { private OutputListener outputListener; private BufferedReader streamIn; private String name; public OutputHooker(String id, InputStream in, OutputListener listener) { name = id; streamIn = new BufferedReader(new InputStreamReader(in)); outputListener = listener; } public void run() { try { String line; while((line = streamIn.readLine()) != null) outputListener.receiveOutput(name, line); } catch(IOException e) { } } } private String [] splitIgnoreEmpty(String str, String sep) { ArrayList<String> fields = new ArrayList<String>(); String[] vec = str.split(sep); for(String t : vec) { if(t != null && t.length() > 0) fields.add(t); } String [] ret = new String[fields.size()]; fields.toArray(ret); return ret; } //////////////////////////////////////////////////////////////////////////////// public interface OutputListener { void receiveOutput(String name, String msg); } public ThreadInvoker(String name) { myIn = System.in; myOut = System.out; myErr = System.err; invokerName = name; } public abstract int run(String [] argv); public InputStream getInputStream() { try { PipedOutputStream processOut = new PipedOutputStream(); PipedInputStream externalIn = new PipedInputStream(processOut); myOut = new PrintStream(processOut); outputReplaced = true; return externalIn; } catch(Exception e) { return null; } } public InputStream getErrorStream() { try { PipedOutputStream processErr = new PipedOutputStream(); PipedInputStream externalIn = new PipedInputStream(processErr); myErr = new PrintStream(processErr); errorReplaced = true; return externalIn; } catch(Exception e) { return null; } } public void setErrorListener(OutputListener listener) { try { PipedOutputStream processErr = new PipedOutputStream(); PipedInputStream externalIn = new PipedInputStream(processErr); myErr = new PrintStream(processErr); errorReplaced = true; new Thread(new OutputHooker(invokerName + " stderr", externalIn, listener)).start(); } catch(Exception e) { } } public OutputStream getOutputStream() { try { PipedInputStream processIn = new PipedInputStream(); PipedOutputStream externalOut = new PipedOutputStream(processIn); myIn = processIn; inputReplaced = true; return externalOut; } catch(Exception e) { return null; } } public void setOutputListener(OutputListener listener) { try { PipedOutputStream processOut = new PipedOutputStream(); PipedInputStream externalIn = new PipedInputStream(processOut); myOut = new PrintStream(processOut); outputReplaced = true; new Thread(new OutputHooker(invokerName + " stdout", externalIn, listener)).start(); } catch(Exception e) { } } public void invoke(String arg) { myArg = arg; myThread = new Thread(this); myThread.start(); } public Thread getThread() { return myThread; } public void waitForComplete() { try { myThread.join(); } catch(InterruptedException e) { } } public int exitValue() { return exitCode; } public void run() { exitCode = run(splitIgnoreEmpty(myArg, " ")); if(inputReplaced) { try { myIn.close(); } catch(IOException e) { } } if(outputReplaced) { myOut.close(); } if(errorReplaced) { myErr.close(); } } }