1   package com.atlassian.sdk.accept;
2   
3   import org.apache.commons.logging.Log;
4   import org.apache.commons.logging.LogFactory;
5   
6   import java.io.BufferedReader;
7   import java.io.File;
8   import java.io.IOException;
9   import java.io.InputStream;
10  import java.io.InputStreamReader;
11  import java.util.List;
12  import java.util.Map;
13  import java.util.logging.Level;
14  
15  public class ExecRunner
16  {
17      private static final Log log = LogFactory.getLog(ExecRunner.class);
18  
19      public int run(File baseDir, List<String> command, Map<String, String> env)
20      {
21          int err = 0;
22  
23          try
24          {
25              // show the command
26              log.info("Running '" + command + "'");
27  
28              // exec command on system runtime
29              ProcessBuilder procBuilder = new ProcessBuilder(command).directory(baseDir);
30              procBuilder.environment().putAll(env);
31              Process proc = procBuilder.start();
32  
33              // copy input and error to the output stream
34              StreamPumper inputPumper =
35                      new StreamPumper(proc.getInputStream(), Level.INFO);
36              StreamPumper errorPumper =
37                      new StreamPumper(proc.getErrorStream(), Level.WARNING);
38  
39              // starts pumping away the generated output/error
40              inputPumper.start();
41              errorPumper.start();
42  
43              // Wait for everything to finish
44              proc.waitFor();
45              inputPumper.join();
46              errorPumper.join();
47              proc.destroy();
48  
49              // check its exit value
50              err = proc.exitValue();
51              if (err != 0)
52              {
53                  throw new RuntimeException("Exec returned: " + err);
54              }
55          }
56          catch (IOException ioe)
57          {
58              throw new RuntimeException("Error exec: " + command, ioe);
59          }
60          catch (InterruptedException ex)
61          {
62              //ignore
63          }
64  
65          return err;
66  
67      }
68  
69  
70      // Inner class for continually pumping the input stream during
71      // Process's runtime.
72  
73      class StreamPumper extends Thread
74      {
75          private BufferedReader din;
76          private Level messageLevel;
77          private boolean endOfStream = false;
78          private static final int SLEEP_TIME = 5;
79  
80          public StreamPumper(InputStream is, Level messageLevel)
81          {
82              this.din = new BufferedReader(new InputStreamReader(is));
83              this.messageLevel = messageLevel;
84          }
85  
86          public void pumpStream() throws IOException
87          {
88              if (!endOfStream)
89              {
90                  String line = din.readLine();
91  
92                  if (line != null)
93                  {
94                      if (messageLevel == Level.INFO)
95                      {
96                          System.out.println("OUT: " + line);
97                      }
98                      else
99                      {
100                         System.out.println("ERR: " + line);
101                     }
102 
103                 }
104                 else
105                 {
106                     endOfStream = true;
107                 }
108             }
109         }
110 
111         public void run()
112         {
113             try
114             {
115                 try
116                 {
117                     while (!endOfStream)
118                     {
119                         pumpStream();
120                         sleep(SLEEP_TIME);
121                     }
122                 }
123                 catch (InterruptedException ie)
124                 {
125                     //ignore
126                 }
127                 din.close();
128             }
129             catch (IOException ioe)
130             {
131                 // ignore
132             }
133         }
134     }
135 
136 }
137 
138