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