X-Git-Url: http://wamblee.org/gitweb/?a=blobdiff_plain;f=support%2Fgeneral%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fio%2FSimpleProcess.java;fp=support%2Fgeneral%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fio%2FSimpleProcess.java;h=6b922b93af1e0c43081dde79e79f581d7b683b40;hb=32a62ca2c752e33a7873ac868a7a1f289caedcd4;hp=0000000000000000000000000000000000000000;hpb=d2bdf4e813c6a3964958c87b2ce56eaadf8a1f0a;p=utils diff --git a/support/general/src/main/java/org/wamblee/io/SimpleProcess.java b/support/general/src/main/java/org/wamblee/io/SimpleProcess.java new file mode 100644 index 00000000..6b922b93 --- /dev/null +++ b/support/general/src/main/java/org/wamblee/io/SimpleProcess.java @@ -0,0 +1,153 @@ +package org.wamblee.io; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.StringWriter; +import java.io.Writer; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class SimpleProcess { + + private static final Log LOG = LogFactory.getLog(SimpleProcess.class); + + private File _directory; + + private String[] _cmd; + + private String _stdout; + private String _stderr; + + public SimpleProcess(File aDirectory, String[] aCmd) { + _directory = aDirectory; + _cmd = aCmd; + } + + /** + * @return the stdout + */ + public String getStdout() { + return _stdout; + } + + /** + * @return the stderr + */ + public String getStderr() { + return _stderr; + } + + /** + * Runs the process and blocks until it is done. + * + * @return Exit status of the process. + * @throws IOException + * In case of problems. + */ + public int run() throws IOException { + return runImpl(); + } + + private int runImpl() throws IOException { + try { + String fullcmd = ""; + for (String part: _cmd) { + fullcmd += " " + part; + } + LOG.debug("Executing '" + fullcmd + "' in directory '" + _directory + + "'"); + java.lang.Process proc = Runtime.getRuntime().exec(_cmd, null, _directory); + + // Read standard output and error in separate threads to avoid + // deadlock. + + StringWriter stdout = new StringWriter(); + StringWriter stderr = new StringWriter(); + Thread stdoutReader = readAndLogStream("STDOUT> ", proc + .getInputStream(), stdout); + Thread stderrReader = readAndLogStream("STDERR> ", proc + .getErrorStream(), stderr); + + try { + proc.waitFor(); + } catch (InterruptedException e) { + IOException exception = new IOException( + "Process was terminated: " + this); + exception.initCause(e); + throw exception; + } + waitForReader(stdoutReader); + waitForReader(stderrReader); + + _stdout = stdout.toString(); + _stderr = stderr.toString(); + + if (proc.exitValue() != 0) { + LOG.warn("Exit value was non-zero: " + this); + } else { + LOG.debug("Process finished"); + } + return proc.exitValue(); + } catch (IOException e) { + IOException exception = new IOException("Error executing process: " + + this); + exception.initCause(e); + throw exception; + } + } + + private void waitForReader(Thread aReaderThread) { + try { + aReaderThread.join(); + } catch (InterruptedException e) { + LOG + .warn(this + + ": error waiting for output stream reader of process to finish"); + } + } + + private Thread readAndLogStream(final String aPrefix, + final InputStream aStream, final Writer aOutput) { + Thread inputReader = new Thread() { + @Override + public void run() { + BufferedReader br = null; + try { + br = new BufferedReader(new InputStreamReader(aStream)); + String str; + while ((str = br.readLine()) != null) { + LOG.debug(aPrefix + str); + aOutput.write(str); + } + } catch (IOException e) { + LOG.warn(SimpleProcess.this + ": error reading input stream", e); + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException e) { + LOG.warn("Error closing stream " + aPrefix); + } + } + } + } + }; + inputReader.start(); + return inputReader; + } + + @Override + public String toString() { + String fullcmd = ""; + for (String part: _cmd) { + fullcmd += part + " "; + } + return "process(dir = '" + _directory + "', cmd = '" + fullcmd + "')"; + } +}