/*******************************************************************************
* Copyright (C) 2009-2011 Amir Hassan <amir@viel-zu.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
******************************************************************************/
package org.wooden.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import org.wooden.io.ByteStreamPipe;
public class ProcessHandler {
private static final Runtime runtime = Runtime.getRuntime();
public static String[] determineCommandInterpreter() {
String osName = System.getProperty("os.name");
String cmd[] = new String[2];
if (osName.equals("Windows NT") || osName.equals("Windows XP")
|| osName.equals("Windows 2000")) {
cmd[0] = "cmd.exe";
cmd[1] = "/C";
} else if (osName.equals("Windows 95") || osName.equals("Windows 98")
|| osName.equals("Windows ME")) {
cmd[0] = "command.com";
cmd[1] = "/C";
} else {
cmd[0] = "bash";
cmd[1] = "-c";
}
return cmd;
}
public static void main(String args[]) {
try {
ProcessHandler ph = new ProcessHandler();
ph.execShellCommand(new String[] { "dir" });
ph.pipeStreams(System.out, System.err, null, 4096, true, true, 100L);
} catch (Throwable t) {
t.printStackTrace();
}
}
private String commandInterpreterInvocation[];
private Process process;
private InputStream in;
private InputStream err;
private OutputStream out;
public ProcessHandler() {
this(determineCommandInterpreter());
}
public ProcessHandler(String customCommandInterpreterInvocation[]) {
this.commandInterpreterInvocation = customCommandInterpreterInvocation;
}
private void ensureOpen() {
if (!this.isStarted())
throw new IllegalStateException("Job was not started");
else
return;
}
public void exec(String arrCommand[]) throws IOException {
StringBuffer sb = new StringBuffer();
for (String element : arrCommand)
sb.append(element).append(' ');
System.out.println(sb);
this.process = runtime.exec(arrCommand);
}
public void execShellCommand(String arrCommand[]) throws IOException {
String arrShellCommand[] = new String[arrCommand.length
+ this.commandInterpreterInvocation.length];
System.arraycopy(this.commandInterpreterInvocation, 0, arrShellCommand, 0,
this.commandInterpreterInvocation.length);
System.arraycopy(arrCommand, 0, arrShellCommand,
this.commandInterpreterInvocation.length, arrCommand.length);
StringBuffer sb = new StringBuffer();
for (String element : arrShellCommand)
sb.append(element).append(' ');
System.out.println(sb);
this.process = runtime.exec(arrShellCommand);
}
public InputStream getInputStream(boolean errorStream) throws IOException {
this.ensureOpen();
if (errorStream && this.err == null)
this.err = this.process.getErrorStream();
else if (this.in == null)
this.in = this.process.getInputStream();
return errorStream ? this.err : this.in;
}
public OutputStream getOutputStream() throws IOException {
this.ensureOpen();
if (this.out == null)
this.out = this.process.getOutputStream();
return this.out;
}
public boolean isRunning() {
if (this.isStarted())
try {
this.process.exitValue();
} catch (IllegalThreadStateException e) {
return true;
}
return false;
}
public boolean isStarted() {
return this.process != null;
}
public void join() {
try {
this.process.waitFor();
} catch (InterruptedException ex) {
throw new RuntimeException(ex.getMessage());
}
}
public void kill() {
this.ensureOpen();
try {
if (this.out != null)
this.out.close();
} catch (IOException ioexception) {}
try {
if (this.in != null)
this.in.close();
} catch (IOException ioexception1) {}
this.process.destroy();
}
public void pipeStreams(OutputStream oppositeIn, OutputStream oppositeErr,
InputStream oppositeOut, int bufferSize, boolean waitFor,
boolean autoCloseStreams, long autoFlushInterval) throws IOException,
InterruptedException, InvocationTargetException {
ByteStreamPipe pOut = null;
ByteStreamPipe pIn = null;
ByteStreamPipe pErr = null;
if (oppositeIn != null)
pIn = new ByteStreamPipe(this.getInputStream(false), oppositeIn,
bufferSize, autoFlushInterval, autoCloseStreams);
if (oppositeErr != null)
pErr = new ByteStreamPipe(this.getInputStream(true), oppositeErr,
bufferSize, autoFlushInterval, autoCloseStreams);
if (oppositeOut != null)
pOut = new ByteStreamPipe(oppositeOut, this.getOutputStream(),
bufferSize, autoFlushInterval, autoCloseStreams);
if (pIn != null) {
if (waitFor)
pIn.join();
if (pIn.isAborted())
throw pIn.abortionCause();
}
if (pErr != null) {
if (waitFor)
pErr.join();
if (pErr.isAborted())
throw pErr.abortionCause();
}
if (pOut != null) {
if (waitFor)
pOut.join();
if (pOut.isAborted())
throw pOut.abortionCause();
}
}
}