1 10 package org.mmbase.util.externalprocess; 11 12 import java.io.IOException ; 13 import java.io.InputStream ; 14 import java.io.OutputStream ; 15 import java.io.PipedInputStream ; 16 import java.io.PipedOutputStream ; 17 18 import org.mmbase.util.logging.Logger; 19 import org.mmbase.util.logging.Logging; 20 21 28 public class CommandLauncher { 29 30 31 private static final Logger log = Logging.getLoggerInstance(CommandLauncher.class); 32 33 36 private static final int BUFFER_SIZE = 1024; 37 38 41 protected static final long DELAY = 50L; 42 43 47 protected static int counter = 0; 48 49 52 protected Process process; 53 54 57 protected String [] commandArgs; 58 59 62 protected String name = ""; 63 64 67 private String lineSeparator; 68 69 76 public CommandLauncher(String name) { 77 process = null; 78 this.name = counter++ +" " + name; 79 lineSeparator = System.getProperty("line.separator", "\n"); 80 } 81 82 86 public String [] getCommandArgs() { 87 return commandArgs; 88 } 89 90 96 protected String [] constructCommandArray(String command, String [] commandArgs) { 97 98 String [] args = new String [1 + commandArgs.length]; 99 args[0] = command; 100 System.arraycopy(commandArgs, 0, args, 1, commandArgs.length); 101 return args; 102 } 103 104 110 public void execute(String command) throws ProcessException { 111 112 if (log.isDebugEnabled()) { 113 printCommandLine(new String [] { command }); 114 } 115 try { 116 process = ProcessFactory.getFactory().exec(command); 117 } catch (IOException e) { 118 throw new ProcessException("An I/O error occured: " + e.getMessage()); 119 } catch (SecurityException e) { 120 throw new ProcessException( 121 "A security manager exists and its checkExec method " + "doesn't allow creation of a subprocess."); 122 } catch (NullPointerException e) { 123 throw new ProcessException("Command is null."); 124 } catch (IllegalArgumentException e) { 125 throw new ProcessException("Command is empty."); 126 } 127 } 128 129 135 public void execute(String [] commandArgs) throws ProcessException { 136 if (log.isDebugEnabled()) { 137 printCommandLine(commandArgs); 138 } 139 try { 140 process = ProcessFactory.getFactory().exec(commandArgs); 141 } catch (IOException e) { 142 throw new ProcessException("An I/O error occured: " + e.getMessage()); 143 } catch (SecurityException e) { 144 throw new ProcessException( 145 "A security manager exists and its checkExec method " + "doesn't allow creation of a subprocess."); 146 } catch (NullPointerException e) { 147 throw new ProcessException("Command is null."); 148 } catch (IllegalArgumentException e) { 149 throw new ProcessException("Command is empty."); 150 } 151 } 152 153 160 public void execute(String commandPath, String [] args) throws ProcessException { 161 commandArgs = constructCommandArray(commandPath, args); 162 execute(commandArgs); 163 } 164 165 172 public void execute(String [] commandArgs, String [] env) throws ProcessException { 173 174 if (log.isDebugEnabled()) { 175 printCommandLine(commandArgs); 176 } 177 try { 178 process = ProcessFactory.getFactory().exec(commandArgs, env); 179 } catch (IOException e) { 180 throw new ProcessException("An I/O error occured: " + e.getMessage()); 181 } catch (SecurityException e) { 182 throw new ProcessException( 183 "A security manager exists and its checkExec method " + "doesn't allow creation of a subprocess."); 184 } catch (NullPointerException e) { 185 throw new ProcessException("Command is null."); 186 } catch (IllegalArgumentException e) { 187 throw new ProcessException("Command is empty."); 188 } 189 } 190 191 199 public void execute(String commandPath, String [] args, String [] env) throws ProcessException { 200 201 commandArgs = constructCommandArray(commandPath, args); 202 execute(commandArgs, env); 203 } 204 205 213 public void execute(String [] commandArgs, String [] env, String changeToDirectory) throws ProcessException { 214 215 if (log.isDebugEnabled()) { 216 printCommandLine(commandArgs); 217 } 218 try { 219 process = ProcessFactory.getFactory().exec(commandArgs, env, changeToDirectory); 220 } catch (IOException e) { 221 throw new ProcessException("An I/O error occured: " + e.getMessage()); 222 } catch (SecurityException e) { 223 throw new ProcessException( 224 "A security manager exists and its checkExec method " + "doesn't allow creation of a subprocess."); 225 } catch (NullPointerException e) { 226 throw new ProcessException("Command is null."); 227 } catch (IllegalArgumentException e) { 228 throw new ProcessException("Command is empty."); 229 } 230 } 231 232 241 public void execute(String commandPath, String [] args, String [] env, String changeToDirectory) 242 throws ProcessException { 243 244 commandArgs = constructCommandArray(commandPath, args); 245 execute(commandArgs, env, changeToDirectory); 246 } 247 248 255 public void waitAndRead(OutputStream out, OutputStream err) throws ProcessException { 256 if (process == null) { 257 throw new ProcessException("Process not yet executed"); 258 } 259 260 ProcessClosure reader = new ProcessClosure(name, process, null, out, err); 261 reader.readBlocking(); } 263 264 276 public void waitAndRead(OutputStream output, OutputStream err, IProgressMonitor monitor) throws ProcessException { 277 if (process == null) { 278 throw new ProcessException("Process not yet executed"); 279 } 280 281 PipedOutputStream errOutPipe = new PipedOutputStream (); 282 PipedOutputStream outputPipe = new PipedOutputStream (); 283 PipedInputStream errInPipe, inputPipe; 284 try { 285 errInPipe = new PipedInputStream (errOutPipe); 286 inputPipe = new PipedInputStream (outputPipe); 287 } catch (IOException e) { 288 throw new ProcessException("Command canceled"); 289 } 290 291 ProcessClosure closure = new ProcessClosure(name, process, null, outputPipe, errOutPipe); 292 closure.readNonBlocking(); 293 294 processStreams(closure, output, inputPipe, err, errInPipe, monitor); 295 } 296 297 305 public void waitAndWrite(InputStream in, OutputStream out, OutputStream err) throws ProcessException { 306 if (process == null) { 307 throw new ProcessException("Process not yet executed"); 308 } 309 310 ProcessClosure reader = new ProcessClosure(name, process, in, out, err); 311 reader.writeBlocking(); } 313 314 327 public void waitAndWrite(InputStream in, OutputStream output, OutputStream err, IProgressMonitor monitor) 328 throws ProcessException { 329 if (process == null) { 330 throw new ProcessException("Process not yet executed"); 331 } 332 333 PipedOutputStream errOutPipe = new PipedOutputStream (); 334 PipedOutputStream outputPipe = new PipedOutputStream (); 335 PipedInputStream errInPipe, inputPipe; 336 try { 337 errInPipe = new PipedInputStream (errOutPipe); 338 inputPipe = new PipedInputStream (outputPipe); 339 } catch (IOException e) { 340 throw new ProcessException("Command canceled"); 341 } 342 343 ProcessClosure closure = new ProcessClosure(name, process, in, outputPipe, errOutPipe); 344 closure.readNonBlocking(); 345 closure.writeNonBlocking(); 346 347 processStreams(closure, output, inputPipe, err, errInPipe, monitor); 348 } 349 350 364 protected void processStreams( 365 ProcessClosure closure, 366 OutputStream output, 367 PipedInputStream inputPipe, 368 OutputStream err, 369 PipedInputStream errInPipe, 370 IProgressMonitor monitor) 371 throws ProcessException { 372 373 monitor.begin(); 374 375 byte buffer[] = new byte[BUFFER_SIZE]; 376 int nbytes; 377 while (!monitor.isCanceled() && closure.isAlive()) { 378 nbytes = 0; 379 try { 380 if (errInPipe.available() > 0) { 381 nbytes = errInPipe.read(buffer); 382 err.write(buffer, 0, nbytes); 383 err.flush(); 384 } 385 if (inputPipe.available() > 0) { 386 nbytes = inputPipe.read(buffer); 387 output.write(buffer, 0, nbytes); 388 output.flush(); 389 } 390 } catch (IOException e) {} 391 if (nbytes == 0) { 392 try { 393 Thread.sleep(DELAY); 394 } catch (InterruptedException ie) {} 395 } else { 396 monitor.worked(); 397 } 398 } 399 400 if (monitor.isCanceled()) { 402 closure.terminate(); 403 throw new ProcessException("Command canceled"); 404 } 405 406 try { 407 process.waitFor(); 408 } catch (InterruptedException e) { 409 } 412 413 try { 415 while (errInPipe.available() > 0 || inputPipe.available() > 0) { 416 nbytes = 0; 417 if (errInPipe.available() > 0) { 418 nbytes = errInPipe.read(buffer); 419 err.write(buffer, 0, nbytes); 420 err.flush(); 421 } 422 if (inputPipe.available() > 0) { 423 nbytes = inputPipe.read(buffer); 424 output.write(buffer, 0, nbytes); 425 output.flush(); 426 } 427 if (nbytes != 0) { 428 monitor.worked(); 429 } 430 } 431 } catch (IOException e) {} finally { 432 try { 433 errInPipe.close(); 434 } catch (IOException e) {} 435 try { 436 inputPipe.close(); 437 } catch (IOException e) {} 438 } 439 440 monitor.done(); 441 } 442 443 448 public void printCommandLine(String [] commandArgs) { 449 StringBuffer buf = new StringBuffer (); 450 for (int i = 0; i < commandArgs.length; i++) { 451 buf.append(commandArgs[i]); 452 buf.append(' '); 453 } 454 buf.append(lineSeparator); 455 log.debug(buf.toString()); 456 } 457 } 458 | Popular Tags |