1 package org.codehaus.plexus.util.cli;
2
3 public class CLICallable implements CommandLineCallable {
4
5 public CLICallable(int timeoutInSeconds, StreamFeeder inputFeeder, StreamPumper outputPumper, StreamPumper errorPumper, Process p, ProcessHook processHook) {
6 this.timeoutInSeconds = timeoutInSeconds;
7 this.inputFeeder = inputFeeder;
8 this.outputPumper = outputPumper;
9 this.errorPumper = errorPumper;
10 this.p = p;
11 this.processHook = processHook;
12 }
13
14 private final int timeoutInSeconds;
15 private final StreamFeeder inputFeeder;
16 private final StreamPumper outputPumper;
17 private final StreamPumper errorPumper;
18 private final Process p;
19 private final ProcessHook processHook;
20
21 @Override
22 public Integer call() throws CommandLineException {
23 try {
24 int returnValue;
25 if (timeoutInSeconds <= 0) {
26 returnValue = p.waitFor();
27 } else {
28 long now = System.currentTimeMillis();
29 long timeoutInMillis = 1000L * timeoutInSeconds;
30 long finish = now + timeoutInMillis;
31 while (CommandLineUtils.isAlive(p) && (System.currentTimeMillis() < finish)) {
32 Thread.sleep(10);
33 }
34 if (CommandLineUtils.isAlive(p)) {
35 throw new InterruptedException("Process timeout out after " + timeoutInSeconds + " seconds");
36 }
37 returnValue = p.exitValue();
38 }
39
40 CommandLineUtils.waitForAllPumpers(inputFeeder, outputPumper, errorPumper);
41
42 if (outputPumper.getException() != null) {
43 throw new CommandLineException("Error inside systemOut parser", outputPumper.getException());
44 }
45
46 if (errorPumper.getException() != null) {
47 throw new CommandLineException("Error inside systemErr parser", errorPumper.getException());
48 }
49
50 return returnValue;
51 } catch (InterruptedException ex) {
52 if (inputFeeder != null) {
53 inputFeeder.disable();
54 }
55 outputPumper.disable();
56 errorPumper.disable();
57 throw new CommandLineTimeOutException("Error while executing external command, process killed.", ex);
58 } finally {
59 ShutdownHookUtils.removeShutdownHook(processHook);
60
61 processHook.run();
62
63 if (inputFeeder != null) {
64 inputFeeder.close();
65 }
66
67 outputPumper.close();
68
69 errorPumper.close();
70 }
71 }
72
73 public int getTimeoutInSeconds() {
74 return timeoutInSeconds;
75 }
76
77 public StreamFeeder getInputFeeder() {
78 return inputFeeder;
79 }
80
81 public StreamPumper getOutputPumper() {
82 return outputPumper;
83 }
84
85 public StreamPumper getErrorPumper() {
86 return errorPumper;
87 }
88
89 public Process getP() {
90 return p;
91 }
92
93 public ProcessHook getProcessHook() {
94 return processHook;
95 }
96
97 }