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 }