1 package org.codehaus.plexus.util.cli.shell;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import org.codehaus.plexus.util.StringUtils;
20
21 import java.io.File;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.List;
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 public class Shell
41 implements Cloneable
42 {
43 private static final char[] DEFAULT_QUOTING_TRIGGER_CHARS = { ' ' };
44
45 private String shellCommand;
46
47 private List<String> shellArgs = new ArrayList<String>();
48
49 private boolean quotedArgumentsEnabled = true;
50
51 private boolean unconditionallyQuote = false;
52
53 private String executable;
54
55 private String workingDir;
56
57 private boolean quotedExecutableEnabled = true;
58
59 private boolean doubleQuotedArgumentEscaped = false;
60
61 private boolean singleQuotedArgumentEscaped = false;
62
63 private boolean doubleQuotedExecutableEscaped = false;
64
65 private boolean singleQuotedExecutableEscaped = false;
66
67 private char argQuoteDelimiter = '\"';
68
69 private char exeQuoteDelimiter = '\"';
70
71 private String argumentEscapePattern = "\\%s";
72
73
74
75
76
77
78 public void setUnconditionalQuoting(boolean unconditionallyQuote)
79 {
80 this.unconditionallyQuote = unconditionallyQuote;
81 }
82
83
84
85
86
87
88 public void setShellCommand( String shellCommand )
89 {
90 this.shellCommand = shellCommand;
91 }
92
93
94
95
96
97
98
99 public String getShellCommand()
100 {
101 return shellCommand;
102 }
103
104
105
106
107
108
109
110 public void setShellArgs( String[] shellArgs )
111 {
112 this.shellArgs.clear();
113 this.shellArgs.addAll( Arrays.asList( shellArgs ) );
114 }
115
116
117
118
119
120
121
122 public String[] getShellArgs()
123 {
124 if ( ( shellArgs == null ) || shellArgs.isEmpty() )
125 {
126 return null;
127 }
128 else
129 {
130 return (String[]) shellArgs.toArray( new String[shellArgs.size()] );
131 }
132 }
133
134
135
136
137
138
139
140
141 public List<String> getCommandLine( String executable, String[] arguments )
142 {
143 return getRawCommandLine( executable, arguments );
144 }
145
146 protected String quoteOneItem(String inputString, boolean isExecutable)
147 {
148 char[] escapeChars = getEscapeChars( isSingleQuotedExecutableEscaped(), isDoubleQuotedExecutableEscaped() );
149 return StringUtils.quoteAndEscape(
150 inputString,
151 isExecutable ? getExecutableQuoteDelimiter() : getArgumentQuoteDelimiter(),
152 escapeChars,
153 getQuotingTriggerChars(),
154 '\\',
155 unconditionallyQuote
156 );
157 }
158
159 protected List<String> getRawCommandLine( String executable, String[] arguments )
160 {
161 List<String> commandLine = new ArrayList<String>();
162 StringBuilder sb = new StringBuilder();
163
164 if ( executable != null )
165 {
166 String preamble = getExecutionPreamble();
167 if ( preamble != null )
168 {
169 sb.append( preamble );
170 }
171
172 if ( isQuotedExecutableEnabled() )
173 {
174 sb.append( quoteOneItem( getOriginalExecutable(), true ) );
175 }
176 else
177 {
178 sb.append( getExecutable() );
179 }
180 }
181 for ( String argument : arguments )
182 {
183 if ( sb.length() > 0 )
184 {
185 sb.append( " " );
186 }
187
188 if ( isQuotedArgumentsEnabled() )
189 {
190 sb.append( quoteOneItem( argument, false ) );
191 }
192 else
193 {
194 sb.append( argument );
195 }
196 }
197
198 commandLine.add( sb.toString() );
199
200 return commandLine;
201 }
202
203 protected char[] getQuotingTriggerChars()
204 {
205 return DEFAULT_QUOTING_TRIGGER_CHARS;
206 }
207
208 protected String getExecutionPreamble()
209 {
210 return null;
211 }
212
213 protected char[] getEscapeChars( boolean includeSingleQuote, boolean includeDoubleQuote )
214 {
215 StringBuilder buf = new StringBuilder( 2 );
216 if ( includeSingleQuote )
217 {
218 buf.append( '\'' );
219 }
220
221 if ( includeDoubleQuote )
222 {
223 buf.append( '\"' );
224 }
225
226 char[] result = new char[buf.length()];
227 buf.getChars( 0, buf.length(), result, 0 );
228
229 return result;
230 }
231
232 protected boolean isDoubleQuotedArgumentEscaped()
233 {
234 return doubleQuotedArgumentEscaped;
235 }
236
237 protected boolean isSingleQuotedArgumentEscaped()
238 {
239 return singleQuotedArgumentEscaped;
240 }
241
242 protected boolean isDoubleQuotedExecutableEscaped()
243 {
244 return doubleQuotedExecutableEscaped;
245 }
246
247 protected boolean isSingleQuotedExecutableEscaped()
248 {
249 return singleQuotedExecutableEscaped;
250 }
251
252 protected void setArgumentQuoteDelimiter( char argQuoteDelimiter )
253 {
254 this.argQuoteDelimiter = argQuoteDelimiter;
255 }
256
257 protected char getArgumentQuoteDelimiter()
258 {
259 return argQuoteDelimiter;
260 }
261
262 protected void setExecutableQuoteDelimiter( char exeQuoteDelimiter )
263 {
264 this.exeQuoteDelimiter = exeQuoteDelimiter;
265 }
266
267 protected char getExecutableQuoteDelimiter()
268 {
269 return exeQuoteDelimiter;
270 }
271
272 protected void setArgumentEscapePattern(String argumentEscapePattern)
273 {
274 this.argumentEscapePattern = argumentEscapePattern;
275 }
276
277 protected String getArgumentEscapePattern() {
278 return argumentEscapePattern;
279 }
280
281
282
283
284
285
286
287
288
289 public List<String> getShellCommandLine( String[] arguments )
290 {
291
292 List<String> commandLine = new ArrayList<String>();
293
294 if ( getShellCommand() != null )
295 {
296 commandLine.add( getShellCommand() );
297 }
298
299 if ( getShellArgs() != null )
300 {
301 commandLine.addAll( getShellArgsList() );
302 }
303
304 commandLine.addAll( getCommandLine( getOriginalExecutable(), arguments ) );
305
306 return commandLine;
307
308 }
309
310 public List<String> getShellArgsList()
311 {
312 return shellArgs;
313 }
314
315 public void addShellArg( String arg )
316 {
317 shellArgs.add( arg );
318 }
319
320 public void setQuotedArgumentsEnabled( boolean quotedArgumentsEnabled )
321 {
322 this.quotedArgumentsEnabled = quotedArgumentsEnabled;
323 }
324
325 public boolean isQuotedArgumentsEnabled()
326 {
327 return quotedArgumentsEnabled;
328 }
329
330 public void setQuotedExecutableEnabled( boolean quotedExecutableEnabled )
331 {
332 this.quotedExecutableEnabled = quotedExecutableEnabled;
333 }
334
335 public boolean isQuotedExecutableEnabled()
336 {
337 return quotedExecutableEnabled;
338 }
339
340
341
342
343 public void setExecutable( String executable )
344 {
345 if ( ( executable == null ) || ( executable.length() == 0 ) )
346 {
347 return;
348 }
349 this.executable = executable.replace( '/', File.separatorChar ).replace( '\\', File.separatorChar );
350 }
351
352 public String getExecutable()
353 {
354 return executable;
355 }
356
357
358
359
360 public void setWorkingDirectory( String path )
361 {
362 if ( path != null )
363 {
364 workingDir = path;
365 }
366 }
367
368
369
370
371 public void setWorkingDirectory( File workingDir )
372 {
373 if ( workingDir != null )
374 {
375 this.workingDir = workingDir.getAbsolutePath();
376 }
377 }
378
379 public File getWorkingDirectory()
380 {
381 return workingDir == null ? null : new File( workingDir );
382 }
383
384 public String getWorkingDirectoryAsString()
385 {
386 return workingDir;
387 }
388
389 public void clearArguments()
390 {
391 shellArgs.clear();
392 }
393
394 public Object clone()
395 {
396 Shellutil/cli/shell/Shell.html#Shell">Shell shell = new Shell();
397 shell.setExecutable( getExecutable() );
398 shell.setWorkingDirectory( getWorkingDirectory() );
399 shell.setShellArgs( getShellArgs() );
400 return shell;
401 }
402
403 public String getOriginalExecutable()
404 {
405 return executable;
406 }
407
408 public List<String> getOriginalCommandLine( String executable, String[] arguments )
409 {
410 return getRawCommandLine( executable, arguments );
411 }
412
413 protected void setDoubleQuotedArgumentEscaped( boolean doubleQuotedArgumentEscaped )
414 {
415 this.doubleQuotedArgumentEscaped = doubleQuotedArgumentEscaped;
416 }
417
418 protected void setDoubleQuotedExecutableEscaped( boolean doubleQuotedExecutableEscaped )
419 {
420 this.doubleQuotedExecutableEscaped = doubleQuotedExecutableEscaped;
421 }
422
423 protected void setSingleQuotedArgumentEscaped( boolean singleQuotedArgumentEscaped )
424 {
425 this.singleQuotedArgumentEscaped = singleQuotedArgumentEscaped;
426 }
427
428 protected void setSingleQuotedExecutableEscaped( boolean singleQuotedExecutableEscaped )
429 {
430 this.singleQuotedExecutableEscaped = singleQuotedExecutableEscaped;
431 }
432 }
433
434