1 23 24 package org.enhydra.xml.xmlc.misc; 25 26 import java.io.BufferedReader ; 27 import java.io.IOException ; 28 import java.io.InputStream ; 29 import java.io.InputStreamReader ; 30 import java.io.OutputStream ; 31 import java.io.OutputStreamWriter ; 32 import java.io.PrintWriter ; 33 34 import org.enhydra.xml.io.ErrorReporter; 35 import org.enhydra.xml.xmlc.XMLCException; 36 37 40 public class ProcessRunner { 41 44 public static final int PASS_STDOUT = 0x01; 45 public static final int PASS_STDERR = 0x02; 46 public static final int COLLECT_STDOUT = 0x04; 47 public static final int COLLECT_STDERR = 0x08; 48 public static final int STDERR_TO_REPORTER = 0x10; 49 public static final int DUMP_STDERR_ON_FAIL = 0x20; 50 public static final int NO_EXCEPTION_ON_ERR_EXIT = 0x40; 51 52 55 private OutputStream stdoutStream; 56 private OutputStream stderrStream; 57 58 61 private StringBuffer stdoutBuf; 62 private StringBuffer stderrBuf; 63 64 67 private int options; 68 69 72 int exitCode; 73 74 77 private class OutputMonitorThread extends Thread { 78 private BufferedReader input; 79 private PrintWriter output; 80 private StringBuffer outputBuf; 81 private IOException ioException = null; 82 private boolean terminateRequested; 83 84 91 OutputMonitorThread(InputStream in, 92 OutputStream out, 93 StringBuffer outBuf) { 94 input = new BufferedReader (new InputStreamReader (in)); 95 if (out != null) { 96 output = new PrintWriter (new OutputStreamWriter (out), true); 97 } 98 outputBuf = outBuf; 99 } 100 101 104 public void terminate() { 105 interrupt(); 106 terminateRequested = true; 107 } 108 109 113 public IOException getException() { 114 return ioException; 115 } 116 117 118 121 private void copyStream() throws IOException { 122 String line; 123 while ((line = input.readLine()) != null) { 124 if (output != null) { 125 output.println(line); 126 } 127 if (outputBuf != null) { 128 outputBuf.append(line); 129 outputBuf.append('\n'); 130 } 131 } 132 } 133 134 137 public void run() { 138 try { 139 copyStream(); 140 } catch (IOException except) { 141 ioException = except; 142 } 143 if (output != null) { 144 output.flush(); 145 } 146 } 147 } 148 149 152 public ProcessRunner(int opts) { 153 setOptions(opts); 154 } 155 156 159 public void setOptions(int opts) { 160 options = opts; 161 if ((options & PASS_STDOUT) != 0) { 162 stdoutStream = System.out; 163 } else { 164 stdoutStream = null; 165 } 166 if ((options & PASS_STDERR) != 0) { 167 stderrStream = System.err; 168 } else { 169 stderrStream = null; 170 } 171 if ((options & DUMP_STDERR_ON_FAIL) != 0) { 172 options |= COLLECT_STDERR; 173 } 174 } 175 176 179 public int getOptions() { 180 return options; 181 } 182 183 186 public int getExitCode() { 187 return exitCode; 188 } 189 190 193 private void dumpStderr(ErrorReporter errorReporter) { 194 if ((options & DUMP_STDERR_ON_FAIL) != 0) { 195 errorReporter.error(stderrBuf.toString()); 196 } 197 } 198 199 202 private void monProc(Process proc) 203 throws IOException , InterruptedException { 204 205 if ((options & COLLECT_STDOUT) != 0) { 207 stdoutBuf = new StringBuffer (); 208 } else { 209 stdoutBuf = null; 210 } 211 if ((options & COLLECT_STDERR) != 0) { 212 stderrBuf = new StringBuffer (); 213 } else { 214 stderrBuf = null; 215 } 216 217 OutputMonitorThread outMon = 218 new OutputMonitorThread(proc.getInputStream(), 219 stdoutStream, 220 stdoutBuf); 221 OutputMonitorThread errMon = 222 new OutputMonitorThread(proc.getErrorStream(), 223 stderrStream, 224 stderrBuf); 225 try { 226 outMon.start(); 227 errMon.start(); 228 proc.waitFor(); 229 } catch (InterruptedException except) { 230 try { 231 proc.destroy(); 233 proc.waitFor(); 234 } catch (InterruptedException drop) { 235 } 237 outMon.terminate(); 238 errMon.terminate(); 239 } finally { 240 outMon.join(); 241 errMon.join(); 242 } 243 if (outMon.getException() != null) { 244 throw outMon.getException(); 245 } 246 if (errMon.getException() != null) { 247 throw errMon.getException(); 248 } 249 } 250 251 259 public void run(String [] cmd, 260 ErrorReporter errorReporter, 261 PrintWriter verboseOut, 262 String failMsg) throws XMLCException { 263 if (verboseOut != null) { 264 for (int i = 0; i < cmd.length; i++) { 265 if (i > 0) { 266 verboseOut.print(" "); 267 } 268 verboseOut.print(cmd[i]); 269 } 270 verboseOut.println(); 271 } 272 273 Process proc; 274 exitCode = 0; 275 try { 276 proc = Runtime.getRuntime().exec(cmd); 277 monProc(proc); 278 } catch (IOException except) { 279 dumpStderr(errorReporter); 280 throw new XMLCException(except); 281 } catch (InterruptedException except) { 282 dumpStderr(errorReporter); 283 throw new XMLCException(except); 284 } 285 exitCode = proc.exitValue(); 286 if (exitCode != 0) { 287 dumpStderr(errorReporter); 288 if ((options & NO_EXCEPTION_ON_ERR_EXIT) == 0) { 289 throw new XMLCException(failMsg); 290 } 291 } 292 } 293 294 297 public String getStdout() { 298 return stdoutBuf.toString(); 299 } 300 301 304 public String getStderr() { 305 return stderrBuf.toString(); 306 } 307 } 308 | Popular Tags |