package abbot.util;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import abbot.Log;
/** Provides handling of process output/error streams. */
public class ProcessOutputHandler {
public static class ProcessAbnormalExitException extends IOException {
/**
*
*/
private static final long serialVersionUID = 1L;
private int code;
private ProcessAbnormalExitException(String msg, int code) {
super(msg);
this.code = code;
}
public int getExitValue() { return code; }
}
private InputStreamHandler stderr;
private InputStreamHandler stdout;
private StringBuffer err = new StringBuffer();
public ProcessOutputHandler() { }
public ProcessOutputHandler(Process p) {
setProcess(p);
}
public String getError() {
return err.toString();
}
public synchronized void setProcess(Process p) {
stdout = new InputStreamHandler(p.getInputStream()) {
public void handleBytes(byte[] buf, int count) {
handleOutput(buf, count);
}
};
stdout.start();
stderr = new InputStreamHandler(p.getErrorStream()) {
public void handleBytes(byte[] buf, int count) {
err.append(new String(buf, 0, count));
handleError(buf, count);
}
};
stderr.start();
}
/** Override this method to handle stdout output. The default
implementation does nothing. */
protected void handleOutput(byte[] buf, int count) { }
/** Override this method to handle stderr output. The default
implementation does nothing. */
protected void handleError(byte[] buf, int count) { }
public synchronized void waitFor() throws InterruptedException {
if (stderr != null)
stderr.join();
if (stdout != null)
stdout.join();
}
/** Returns the output of the given command as a String. */
public static String exec(String[] command)
throws IOException {
return exec(command, null);
}
/** Returns the output of the given command as a String. */
public static String exec(String[] command, String[] environment)
throws IOException {
return exec(command, environment, null);
}
/** Returns the output of the given command as a String. */
public static String exec(String[] command, String[] environment, File dir)
throws IOException {
final StringBuffer output = new StringBuffer();
Log.debug("Running " + Arrays.asList(command));
Process p = Runtime.getRuntime().exec(command, environment, dir);
ProcessOutputHandler handler = new ProcessOutputHandler(p) {
public void handleOutput(byte[] buf, int count) {
output.append(new String(buf, 0, count));
}
};
try { p.waitFor(); } catch(InterruptedException e) {Log.debug(e);}
try { handler.waitFor(); } catch(InterruptedException e) { }
int code = p.exitValue();
if (code != 0) {
String msg = "Process " + Arrays.asList(command)
+ " exited with " + code;
String err = handler.getError();
if (!"".equals(err))
msg += ":\n" + err;
Log.debug(msg);
throw new ProcessAbnormalExitException(msg, code);
}
Log.debug("output=" + output.toString());
return output.toString();
}
}