]> git.argeo.org Git - gpl/argeo-slc.git/blob - maven/org.argeo.slc.maven.plugin/src/main/java/org/argeo/slc/maven/plugin/SystemCall.java
Equinox Execution
[gpl/argeo-slc.git] / maven / org.argeo.slc.maven.plugin / src / main / java / org / argeo / slc / maven / plugin / SystemCall.java
1 package org.argeo.slc.maven.plugin;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.InputStreamReader;
7 import java.io.OutputStream;
8 import java.util.List;
9
10 import org.apache.commons.io.IOUtils;
11
12 public class SystemCall implements Runnable {
13 private String execDir;
14
15 private String cmd = null;
16 private String[] command = null;
17
18 private boolean synchronous = true;
19 private boolean captureStdIn = false;
20
21 public SystemCall() {
22
23 }
24
25 public SystemCall(String execDir, String cmd, boolean captureStdIn) {
26 super();
27 this.execDir = execDir;
28 this.cmd = cmd;
29 this.synchronous = true;
30 this.captureStdIn = captureStdIn;
31 }
32
33 public SystemCall(String execDir, String[] command, boolean captureStdIn) {
34 super();
35 this.execDir = execDir;
36 this.command = command;
37 this.synchronous = true;
38 this.captureStdIn = captureStdIn;
39 }
40
41 public void run() {
42 try {
43 // Execution directory
44 File dir = null;
45 if (execDir != null) {
46 // Replace '/' by local file separator, for portability
47 execDir.replace('/', File.separatorChar);
48 dir = new File(execDir).getCanonicalFile();
49 }
50
51 final Process process;
52
53 if (cmd != null) {
54 process = Runtime.getRuntime().exec(cmd, null, dir);
55 } else if (command != null) {
56 process = Runtime.getRuntime().exec(command, null, dir);
57 ;
58 } else {
59 throw new RuntimeException("No command specified");
60 }
61
62 Runtime.getRuntime().addShutdownHook(new Thread() {
63
64 public void run() {
65 if (process != null) {
66 try {
67 process.exitValue();
68 } catch (Exception e) {
69 process.destroy();
70 System.err.println("Killed process " + process);
71 }
72 }
73 }
74 });
75
76 // Manage standard streams
77 StreamReaderThread stdOutThread = new StreamReaderThread(process
78 .getInputStream(), false);
79 stdOutThread.start();
80 // TODO: understand why streams are not properly flushed
81 StreamReaderThread stdErrThread = new StreamReaderThread(process
82 .getInputStream(), false);
83 stdErrThread.start();
84 if (captureStdIn)
85 new StdInThread(process.getOutputStream()).start();
86
87 // Wait for the end of the process
88 if (synchronous) {
89 int exitCode = process.waitFor();
90 if (exitCode != 0) {
91 Thread.sleep(5000);// leave the process a chance to log
92 System.err.println("Process return exit code " + exitCode);
93 }
94 } else {
95 // asynchronous: return
96 }
97 } catch (Exception e) {
98 throw new RuntimeException("Could not execute command " + cmd, e);
99 }
100
101 }
102
103 /**
104 * Shortcut method returning the current exec dir if the specified one is
105 * null.
106 */
107 private String getUsedDir(File dir) {
108 if (dir == null)
109 return System.getProperty("user.dir");
110 else
111 return dir.getPath();
112 }
113
114 public void setCmd(String command) {
115 this.cmd = command;
116 }
117
118 public void setExecDir(String execdir) {
119 this.execDir = execdir;
120 }
121
122 public void setCommand(String[] command) {
123 this.command = command;
124 }
125
126 protected synchronized void write(String str, boolean isErr) {
127 if (isErr) {
128 System.err.print(str);
129 System.err.flush();
130 } else {
131 System.out.print(str);
132 System.out.flush();
133 }
134 notifyAll();
135 }
136
137 protected class StreamReaderThread extends Thread {
138 private final InputStream stream;
139 private final boolean isErr;
140
141 public StreamReaderThread(InputStream stream, boolean isErr) {
142 this.stream = stream;
143 this.isErr = isErr;
144 }
145
146 public void run() {
147 // BufferedReader in = null;
148 InputStreamReader isr = null;
149 try {
150 isr = new InputStreamReader(stream);
151 int c;
152 StringBuffer buf = new StringBuffer(256);
153 char lastCr = '\n';
154 while ((c = isr.read()) != -1) {
155 char cr = (char) c;
156
157 buf.append(cr);
158
159 boolean write = false;
160 if (lastCr == '>' && cr == ' ')
161 write = true;
162 else if (cr == '\n')
163 write = true;
164
165 lastCr = cr;
166 if (write) {
167 write(buf.toString(), isErr);
168 buf = new StringBuffer(256);
169 }
170
171 // if (isErr) {
172 // System.err.print(cr);
173 // if (cr == '\n' || cr == '>')
174 // System.err.flush();
175 // } else {
176 // System.out.print(cr);
177 // if (cr == '\n' || cr == '>')
178 // System.out.flush();
179 // }
180 }
181 // String line = null;
182 // while ((line = in.readLine()) != null) {
183 // stdOutCallback(line);
184 // System.out.
185 // }
186 } catch (IOException e) {
187 // catch silently
188 // because the other methods
189 // to check whether the stream
190 // is closed would probably
191 // be to costly
192 } finally {
193 if (synchronous)
194 IOUtils.closeQuietly(isr);
195 }
196 }
197 }
198
199 protected class StdInThread extends Thread {
200 private final OutputStream stream;
201
202 public StdInThread(OutputStream stream) {
203 this.stream = stream;
204 }
205
206 public void run() {
207 // BufferedReader in = null;
208 // Writer out = null;
209 InputStreamReader isr = null;
210 try {
211 // out = new OutputStreamWriter(stream);
212 isr = new InputStreamReader(System.in);
213 int c;
214 while ((c = isr.read()) != -1) {
215 stream.write(c);
216 stream.flush();
217 }
218
219 /*
220 * in = new BufferedReader(new InputStreamReader(System.in));
221 * String line = null; while ((line = in.readLine()) != null) {
222 * out.write(line); out.write("\n"); out.flush(); }
223 */
224 } catch (IOException e) {
225 throw new RuntimeException("Could not write to stdin stream", e);
226 } finally {
227 if (synchronous) {
228 IOUtils.closeQuietly(isr);
229 // IOUtils.closeQuietly(in);
230 // IOUtils.closeQuietly(out);
231 }
232 }
233 }
234
235 }
236 }