TimeoutProcess.java

  1. /*
  2.  * TimeoutProcess
  3.  *
  4.  * $Id$
  5.  * $URL$
  6.  */
  7. package gov.usgs.util;

  8. import java.io.IOException;
  9. import java.io.InputStream;
  10. import java.io.OutputStream;
  11. import java.util.Timer;

  12. /**
  13.  * TimeoutProcess wraps a Process object.
  14.  *
  15.  * It is most commonly used with TimeoutProcessBuilder, which configures the
  16.  * process timeout (and sets the timed out state once the timeout is reached).
  17.  *
  18.  * @see java.lang.Process
  19.  * @see TimeoutProcessBuilder
  20.  * @see ProcessTimeoutException
  21.  */
  22. public class TimeoutProcess {

  23.     /** The wrapped process */
  24.     private Process process;

  25.     /** Whether this process timed out. */
  26.     private boolean timeoutElapsed = false;

  27.     /** Timer object that will destroy this process. */
  28.     private Timer timer = null;

  29.     /** Standard error output. */
  30.     private byte[] errorOutput;

  31.     /**
  32.      * Construct a new TimeoutProcess.
  33.      *
  34.      * @param process
  35.      *            the wrapped process.
  36.      */
  37.     protected TimeoutProcess(Process process) {
  38.         this.process = process;
  39.     }

  40.     /** Destroys a process */
  41.     public void destroy() {
  42.         process.destroy();
  43.     }

  44.     /** @return errorOutput byte array */
  45.     public byte[] errorOutput() {
  46.         return errorOutput;
  47.     }

  48.     /** @return exit value */
  49.     public int exitValue() {
  50.         return process.exitValue();
  51.     }

  52.     /** @return InputStream of error stream */
  53.     public InputStream getErrorStream() {
  54.         return process.getErrorStream();
  55.     }

  56.     /** @return InputStream */
  57.     public InputStream getInputStream() {
  58.         return process.getInputStream();
  59.     }

  60.     /** @return OutputStream */
  61.     public OutputStream getOutputStream() {
  62.         return process.getOutputStream();
  63.     }

  64.     /**
  65.      * Wait for the process to complete, either normally or because its timeout
  66.      * was reached.
  67.      *
  68.      * @return exitStatus.
  69.      * @throws InterruptedException
  70.      *             if thread interruption occurs
  71.      * @throws IOException
  72.      *             if IO error occurs
  73.      * @throws ProcessTimeoutException
  74.      *             if the process timed out before exiting.
  75.      */
  76.     public int waitFor() throws InterruptedException, IOException, ProcessTimeoutException {
  77.         int status = -1;
  78.         try {
  79.             status = process.waitFor();

  80.             if (timeoutElapsed()) {
  81.                 throw new ProcessTimeoutException("The process has timed out.");
  82.             }
  83.         } finally {
  84.             if (timer != null) {
  85.                 // the timer hasn't destroyed this process already, cancel it.
  86.                 timer.cancel();
  87.             }
  88.         }

  89.         try {
  90.             errorOutput = StreamUtils.readStream(getErrorStream());
  91.         } finally {
  92.             // close streams
  93.             StreamUtils.closeStream(getErrorStream());
  94.             StreamUtils.closeStream(getInputStream());
  95.             StreamUtils.closeStream(getOutputStream());
  96.         }

  97.         return status;
  98.     }

  99.     /** @param timeoutElapsed to set */
  100.     protected void setTimeoutElapsed(boolean timeoutElapsed) {
  101.         this.timeoutElapsed = timeoutElapsed;
  102.     }

  103.     /** @return timeoutElapsed boolean */
  104.     protected boolean timeoutElapsed() {
  105.         return timeoutElapsed;
  106.     }

  107.     /** @param timer to set */
  108.     protected void setTimer(final Timer timer) {
  109.         this.timer = timer;
  110.     }

  111. }