1 package org.codehaus.plexus.util.cli;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.util.Locale;
22 import java.util.Map;
23 import java.util.Properties;
24 import java.util.StringTokenizer;
25 import java.util.Vector;
26
27 import org.codehaus.plexus.util.Os;
28 import org.codehaus.plexus.util.StringUtils;
29 import org.kuali.common.util.Assert;
30
31 public abstract class CommandLineUtils {
32
33 public static int executeCommandLine(Commandline cl, StreamConsumer systemOut, StreamConsumer systemErr) throws CommandLineException {
34 return executeCommandLine(cl, null, systemOut, systemErr, 0);
35 }
36
37 public static int executeCommandLine(Commandline cl, StreamConsumer systemOut, StreamConsumer systemErr, int timeoutInSeconds) throws CommandLineException {
38 return executeCommandLine(cl, null, systemOut, systemErr, timeoutInSeconds);
39 }
40
41 public static int executeCommandLine(Commandline cl, InputStream systemIn, StreamConsumer systemOut, StreamConsumer systemErr) throws CommandLineException {
42 return executeCommandLine(cl, systemIn, systemOut, systemErr, 0);
43 }
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 public static int executeCommandLine(Commandline cl, InputStream systemIn, StreamConsumer systemOut, StreamConsumer systemErr, int timeoutInSeconds)
62 throws CommandLineException {
63 final CommandLineCallable future = executeCommandLineAsCallable(cl, systemIn, systemOut, systemErr, timeoutInSeconds);
64 return future.call();
65 }
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86 public static CommandLineCallable executeCommandLineAsCallable(Commandline cl, InputStream systemIn, StreamConsumer systemOut, StreamConsumer systemErr, int timeoutInSeconds)
87 throws CommandLineException {
88
89 Assert.noNulls(cl);
90
91 final Process p = cl.execute();
92 final StreamFeeder inputFeeder = systemIn != null ? new StreamFeeder(systemIn, p.getOutputStream()) : null;
93 final StreamPumper outputPumper = new StreamPumper(p.getInputStream(), systemOut);
94 final StreamPumper errorPumper = new StreamPumper(p.getErrorStream(), systemErr);
95
96 if (inputFeeder != null) {
97 inputFeeder.start();
98 }
99
100 outputPumper.start();
101 errorPumper.start();
102
103 final ProcessHook processHook = new ProcessHook(p);
104
105 ShutdownHookUtils.addShutDownHook(processHook);
106
107 return new CLICallable(timeoutInSeconds, inputFeeder, outputPumper, errorPumper, p, processHook);
108
109 }
110
111 public static void waitForAllPumpers(StreamFeeder inputFeeder, StreamPumper outputPumper, StreamPumper errorPumper) throws InterruptedException {
112 if (inputFeeder != null) {
113 inputFeeder.waitUntilDone();
114 }
115
116 outputPumper.waitUntilDone();
117 errorPumper.waitUntilDone();
118 }
119
120
121
122
123
124
125
126
127
128
129
130 public static Properties getSystemEnvVars() throws IOException {
131 return getSystemEnvVars(!Os.isFamily(Os.FAMILY_WINDOWS));
132 }
133
134
135
136
137
138
139
140
141
142
143 public static Properties getSystemEnvVars(boolean caseSensitive) throws IOException {
144 Properties envVars = new Properties();
145 Map<String, String> envs = System.getenv();
146 for (String key : envs.keySet()) {
147 String value = envs.get(key);
148 if (!caseSensitive) {
149 key = key.toUpperCase(Locale.ENGLISH);
150 }
151 envVars.put(key, value);
152 }
153 return envVars;
154 }
155
156 public static boolean isAlive(Process p) {
157 if (p == null) {
158 return false;
159 }
160
161 try {
162 p.exitValue();
163 return false;
164 } catch (IllegalThreadStateException e) {
165 return true;
166 }
167 }
168
169 public static String[] translateCommandline(String toProcess) throws Exception {
170 if ((toProcess == null) || (toProcess.length() == 0)) {
171 return new String[0];
172 }
173
174
175
176 final int normal = 0;
177 final int inQuote = 1;
178 final int inDoubleQuote = 2;
179 int state = normal;
180 StringTokenizer tok = new StringTokenizer(toProcess, "\"\' ", true);
181 Vector<String> v = new Vector<String>();
182 StringBuilder current = new StringBuilder();
183
184 while (tok.hasMoreTokens()) {
185 String nextTok = tok.nextToken();
186 switch (state) {
187 case inQuote:
188 if ("\'".equals(nextTok)) {
189 state = normal;
190 } else {
191 current.append(nextTok);
192 }
193 break;
194 case inDoubleQuote:
195 if ("\"".equals(nextTok)) {
196 state = normal;
197 } else {
198 current.append(nextTok);
199 }
200 break;
201 default:
202 if ("\'".equals(nextTok)) {
203 state = inQuote;
204 } else if ("\"".equals(nextTok)) {
205 state = inDoubleQuote;
206 } else if (" ".equals(nextTok)) {
207 if (current.length() != 0) {
208 v.addElement(current.toString());
209 current.setLength(0);
210 }
211 } else {
212 current.append(nextTok);
213 }
214 break;
215 }
216 }
217
218 if (current.length() != 0) {
219 v.addElement(current.toString());
220 }
221
222 if ((state == inQuote) || (state == inDoubleQuote)) {
223 throw new CommandLineException("unbalanced quotes in " + toProcess);
224 }
225
226 String[] args = new String[v.size()];
227 v.copyInto(args);
228 return args;
229 }
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244 @Deprecated
245 public static String quote(String argument) throws CommandLineException {
246 return quote(argument, false, false, true);
247 }
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262 @Deprecated
263 public static String quote(String argument, boolean wrapExistingQuotes) throws CommandLineException {
264 return quote(argument, false, false, wrapExistingQuotes);
265 }
266
267
268
269
270
271 @Deprecated
272 public static String quote(String argument, boolean escapeSingleQuotes, boolean escapeDoubleQuotes, boolean wrapExistingQuotes) throws CommandLineException {
273 if (argument.contains("\"")) {
274 if (argument.contains("\'")) {
275 throw new CommandLineException("Can't handle single and double quotes in same argument");
276 } else {
277 if (escapeSingleQuotes) {
278 return "\\\'" + argument + "\\\'";
279 } else if (wrapExistingQuotes) {
280 return '\'' + argument + '\'';
281 }
282 }
283 } else if (argument.contains("\'")) {
284 if (escapeDoubleQuotes) {
285 return "\\\"" + argument + "\\\"";
286 } else if (wrapExistingQuotes) {
287 return '\"' + argument + '\"';
288 }
289 } else if (argument.contains(" ")) {
290 if (escapeDoubleQuotes) {
291 return "\\\"" + argument + "\\\"";
292 } else {
293 return '\"' + argument + '\"';
294 }
295 }
296
297 return argument;
298 }
299
300 public static String toString(String[] line) {
301
302 if ((line == null) || (line.length == 0)) {
303 return "";
304 }
305
306
307 final StringBuilder result = new StringBuilder();
308 for (int i = 0; i < line.length; i++) {
309 if (i > 0) {
310 result.append(' ');
311 }
312 try {
313 result.append(StringUtils.quoteAndEscape(line[i], '\"'));
314 } catch (Exception e) {
315 System.err.println("Error quoting argument: " + e.getMessage());
316 }
317 }
318 return result.toString();
319 }
320
321 }