TimeoutProcessBuilder.java

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

  8. import java.io.File;
  9. import java.io.IOException;
  10. import java.util.List;
  11. import java.util.Map;
  12. import java.util.Timer;
  13. import java.util.TimerTask;

  14. /**
  15.  * The TimeoutProcessBuilder wraps a ProcessBuilder, adding support for a
  16.  * command time out.
  17.  *
  18.  * This class does not support a full command String complete with arguments.
  19.  * You can use the StringUtils.split method to get around this.
  20.  *
  21.  * @see java.lang.ProcessBuilder
  22.  * @see TimeoutProcess
  23.  */
  24. public class TimeoutProcessBuilder {

  25.   /** The wrapped process builder. */
  26.   private ProcessBuilder builder = null;
  27.   /** The timeout for this process. */
  28.   private long timeout = -1;

  29.   /**
  30.    * Create a new TimeoutProcessBuilder with a timeout and an array of strings.
  31.    *
  32.    * @param timeout timeout in milliseconds for process, or <= 0 for no
  33.    *                timeout.
  34.    * @param command array of strings that represent command. The first element
  35.    *                must be the full path to the executable, without arguments.
  36.    */
  37.   public TimeoutProcessBuilder(long timeout, String... command) {
  38.     builder = new ProcessBuilder(command);
  39.     this.timeout = timeout;
  40.   }

  41.   /**
  42.    * Create a new TimeoutProcessBuilder with a timeout and an array of strings.
  43.    *
  44.    * @param timeout timeout in milliseconds for process, or <= 0 for no
  45.    *                timeout.
  46.    * @param command list of strings that represent command.
  47.    */
  48.   public TimeoutProcessBuilder(long timeout, List<String> command) {
  49.     builder = new ProcessBuilder(command);
  50.     this.timeout = timeout;

  51.   }

  52.   /**
  53.    * This signature is preserved, but calls the alternate constructor with
  54.    * argument order swapped.
  55.    *
  56.    * @param command list of strings that represent command.
  57.    * @param timeout timeout in milliseconds for process, or &lt;= 0 for no
  58.    *                timeout.
  59.    */
  60.   @Deprecated
  61.   public TimeoutProcessBuilder(List<String> command, long timeout) {
  62.     this(timeout, command);
  63.   }

  64.   /** @return list of builder commands */
  65.   public List<String> command() {
  66.     return builder.command();
  67.   }

  68.   /**
  69.    * @param command give builder a list of commands
  70.    * @return TimeoutProcessBuilder
  71.    */
  72.   public TimeoutProcessBuilder command(List<String> command) {
  73.     builder.command(command);
  74.     return this;
  75.   }

  76.   /**
  77.    * @param command give builder a single command
  78.    * @return TimeoutProcessBuilder
  79.    */
  80.   public TimeoutProcessBuilder command(String command) {
  81.     builder.command(command);
  82.     return this;
  83.   }

  84.   /** @return builder directory */
  85.   public File directory() {
  86.     return builder.directory();
  87.   }

  88.   /**
  89.    * @param directory to set
  90.    * @return TimeoutProcessBuilder
  91.    */
  92.   public TimeoutProcessBuilder directory(File directory) {
  93.     builder.directory(directory);
  94.     return this;
  95.   }

  96.   /** @return builder environment */
  97.   public Map<String, String> environment() {
  98.     return builder.environment();
  99.   }

  100.   /** @return boolean redirectErrorStream */
  101.   public boolean redirectErrorStream() {
  102.     return builder.redirectErrorStream();
  103.   }

  104.   /**
  105.    * @param redirectErrorStream to set
  106.    * @return TimeoutProcessBuilder
  107.    */
  108.   public TimeoutProcessBuilder redirectErrorStream(boolean redirectErrorStream) {
  109.     builder.redirectErrorStream(redirectErrorStream);
  110.     return this;
  111.   }

  112.   /**
  113.    * @return a TimeoutProcess
  114.    * @throws IOException if IO error occurs
  115.    */
  116.   public TimeoutProcess start() throws IOException {
  117.     final TimeoutProcess process = new TimeoutProcess(builder.start());

  118.     if (timeout > 0) {
  119.       // set up the timeout for this process
  120.       final Timer timer = new Timer();
  121.       timer.schedule(new TimerTask() {
  122.         @Override
  123.         public void run() {
  124.           process.setTimeoutElapsed(true);
  125.           process.destroy();
  126.         }
  127.       }, timeout);
  128.       process.setTimer(timer);
  129.     }

  130.     return process;
  131.   }

  132.   /** @return timeout */
  133.   public long getTimeout() {
  134.     return this.timeout;
  135.   }

  136.   /** @param timeout to set */
  137.   public void setTimeout(final long timeout) {
  138.     this.timeout = timeout;
  139.   }

  140. }