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