001package org.codehaus.plexus.util.cli; 002 003public class CLICallable implements CommandLineCallable { 004 005 public CLICallable(int timeoutInSeconds, StreamFeeder inputFeeder, StreamPumper outputPumper, StreamPumper errorPumper, Process p, ProcessHook processHook) { 006 this.timeoutInSeconds = timeoutInSeconds; 007 this.inputFeeder = inputFeeder; 008 this.outputPumper = outputPumper; 009 this.errorPumper = errorPumper; 010 this.p = p; 011 this.processHook = processHook; 012 } 013 014 private final int timeoutInSeconds; 015 private final StreamFeeder inputFeeder; 016 private final StreamPumper outputPumper; 017 private final StreamPumper errorPumper; 018 private final Process p; 019 private final ProcessHook processHook; 020 021 @Override 022 public Integer call() throws CommandLineException { 023 try { 024 int returnValue; 025 if (timeoutInSeconds <= 0) { 026 returnValue = p.waitFor(); 027 } else { 028 long now = System.currentTimeMillis(); 029 long timeoutInMillis = 1000L * timeoutInSeconds; 030 long finish = now + timeoutInMillis; 031 while (CommandLineUtils.isAlive(p) && (System.currentTimeMillis() < finish)) { 032 Thread.sleep(10); 033 } 034 if (CommandLineUtils.isAlive(p)) { 035 throw new InterruptedException("Process timeout out after " + timeoutInSeconds + " seconds"); 036 } 037 returnValue = p.exitValue(); 038 } 039 040 CommandLineUtils.waitForAllPumpers(inputFeeder, outputPumper, errorPumper); 041 042 if (outputPumper.getException() != null) { 043 throw new CommandLineException("Error inside systemOut parser", outputPumper.getException()); 044 } 045 046 if (errorPumper.getException() != null) { 047 throw new CommandLineException("Error inside systemErr parser", errorPumper.getException()); 048 } 049 050 return returnValue; 051 } catch (InterruptedException ex) { 052 if (inputFeeder != null) { 053 inputFeeder.disable(); 054 } 055 outputPumper.disable(); 056 errorPumper.disable(); 057 throw new CommandLineTimeOutException("Error while executing external command, process killed.", ex); 058 } finally { 059 ShutdownHookUtils.removeShutdownHook(processHook); 060 061 processHook.run(); 062 063 if (inputFeeder != null) { 064 inputFeeder.close(); 065 } 066 067 outputPumper.close(); 068 069 errorPumper.close(); 070 } 071 } 072 073 public int getTimeoutInSeconds() { 074 return timeoutInSeconds; 075 } 076 077 public StreamFeeder getInputFeeder() { 078 return inputFeeder; 079 } 080 081 public StreamPumper getOutputPumper() { 082 return outputPumper; 083 } 084 085 public StreamPumper getErrorPumper() { 086 return errorPumper; 087 } 088 089 public Process getP() { 090 return p; 091 } 092 093 public ProcessHook getProcessHook() { 094 return processHook; 095 } 096 097}