View Javadoc
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  }