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
42 public class Shell
43 implements Cloneable
44 {
45 private static final char[] DEFAULT_QUOTING_TRIGGER_CHARS = { ' ' };
46
47 private String shellCommand;
48
49 private final List<String> shellArgs = new ArrayList<String>();
50
51 private boolean quotedArgumentsEnabled = true;
52
53 private String executable;
54
55 private String workingDir;
56
57 private boolean quotedExecutableEnabled = true;
58
59 private boolean singleQuotedArgumentEscaped = false;
60
61 private boolean singleQuotedExecutableEscaped = false;
62
63 private char argQuoteDelimiter = '\"';
64
65 private char exeQuoteDelimiter = '\"';
66
67
68
69
70
71
72 void setShellCommand( String shellCommand )
73 {
74 this.shellCommand = shellCommand;
75 }
76
77
78
79
80
81
82 String getShellCommand()
83 {
84 return shellCommand;
85 }
86
87
88
89
90
91
92
93 void setShellArgs( String[] shellArgs )
94 {
95 this.shellArgs.clear();
96 this.shellArgs.addAll( Arrays.asList( shellArgs ) );
97 }
98
99
100
101
102
103
104 String[] getShellArgs()
105 {
106 if ( ( shellArgs == null ) || shellArgs.isEmpty() )
107 {
108 return null;
109 }
110 else
111 {
112 return shellArgs.toArray( new String[shellArgs.size()] );
113 }
114 }
115
116
117
118
119
120
121
122
123 List<String> getCommandLine( String executable, String... arguments )
124 {
125 return getRawCommandLine( executable, arguments );
126 }
127
128 List<String> getRawCommandLine( String executable, String... arguments )
129 {
130 List<String> commandLine = new ArrayList<String>();
131 StringBuilder sb = new StringBuilder();
132
133 if ( executable != null )
134 {
135 String preamble = getExecutionPreamble();
136 if ( preamble != null )
137 {
138 sb.append( preamble );
139 }
140
141 if ( isQuotedExecutableEnabled() )
142 {
143 char[] escapeChars =
144 getEscapeChars( isSingleQuotedExecutableEscaped(), isDoubleQuotedExecutableEscaped() );
145
146 sb.append( StringUtils.quoteAndEscape( getExecutable(), getExecutableQuoteDelimiter(), escapeChars,
147 getQuotingTriggerChars(), '\\', false ) );
148 }
149 else
150 {
151 sb.append( getExecutable() );
152 }
153 }
154 for ( String argument : arguments )
155 {
156 if ( sb.length() > 0 )
157 {
158 sb.append( ' ' );
159 }
160
161 if ( isQuotedArgumentsEnabled() )
162 {
163 char[] escapeChars = getEscapeChars( isSingleQuotedArgumentEscaped(), isDoubleQuotedArgumentEscaped() );
164
165 sb.append( StringUtils.quoteAndEscape( argument, getArgumentQuoteDelimiter(), escapeChars,
166 getQuotingTriggerChars(), '\\', false ) );
167 }
168 else
169 {
170 sb.append( argument );
171 }
172 }
173
174 commandLine.add( sb.toString() );
175
176 return commandLine;
177 }
178
179 char[] getQuotingTriggerChars()
180 {
181 return DEFAULT_QUOTING_TRIGGER_CHARS;
182 }
183
184 String getExecutionPreamble()
185 {
186 return null;
187 }
188
189 char[] getEscapeChars( boolean includeSingleQuote, boolean includeDoubleQuote )
190 {
191 StringBuilder buf = new StringBuilder( 2 );
192 if ( includeSingleQuote )
193 {
194 buf.append( '\'' );
195 }
196
197 if ( includeDoubleQuote )
198 {
199 buf.append( '\"' );
200 }
201
202 char[] result = new char[buf.length()];
203 buf.getChars( 0, buf.length(), result, 0 );
204
205 return result;
206 }
207
208 protected boolean isDoubleQuotedArgumentEscaped()
209 {
210 return false;
211 }
212
213 protected boolean isSingleQuotedArgumentEscaped()
214 {
215 return singleQuotedArgumentEscaped;
216 }
217
218 boolean isDoubleQuotedExecutableEscaped()
219 {
220 return false;
221 }
222
223 boolean isSingleQuotedExecutableEscaped()
224 {
225 return singleQuotedExecutableEscaped;
226 }
227
228 void setArgumentQuoteDelimiter( char argQuoteDelimiter )
229 {
230 this.argQuoteDelimiter = argQuoteDelimiter;
231 }
232
233 char getArgumentQuoteDelimiter()
234 {
235 return argQuoteDelimiter;
236 }
237
238 void setExecutableQuoteDelimiter( char exeQuoteDelimiter )
239 {
240 this.exeQuoteDelimiter = exeQuoteDelimiter;
241 }
242
243 char getExecutableQuoteDelimiter()
244 {
245 return exeQuoteDelimiter;
246 }
247
248
249
250
251
252
253
254
255
256 public List<String> getShellCommandLine( String... arguments )
257 {
258
259 List<String> commandLine = new ArrayList<String>();
260
261 if ( getShellCommand() != null )
262 {
263 commandLine.add( getShellCommand() );
264 }
265
266 if ( getShellArgs() != null )
267 {
268 commandLine.addAll( getShellArgsList() );
269 }
270
271 commandLine.addAll( getCommandLine( getExecutable(), arguments ) );
272
273 return commandLine;
274
275 }
276
277 List<String> getShellArgsList()
278 {
279 return shellArgs;
280 }
281
282 public void setQuotedArgumentsEnabled( boolean quotedArgumentsEnabled )
283 {
284 this.quotedArgumentsEnabled = quotedArgumentsEnabled;
285 }
286
287 boolean isQuotedArgumentsEnabled()
288 {
289 return quotedArgumentsEnabled;
290 }
291
292 void setQuotedExecutableEnabled( boolean quotedExecutableEnabled )
293 {
294 this.quotedExecutableEnabled = quotedExecutableEnabled;
295 }
296
297 boolean isQuotedExecutableEnabled()
298 {
299 return quotedExecutableEnabled;
300 }
301
302
303
304
305 public void setExecutable( String executable )
306 {
307 if ( ( executable == null ) || ( executable.length() == 0 ) )
308 {
309 return;
310 }
311 this.executable = executable.replace( '/', File.separatorChar ).replace( '\\', File.separatorChar );
312 }
313
314 public String getExecutable()
315 {
316 return executable;
317 }
318
319
320
321
322 public void setWorkingDirectory( String path )
323 {
324 if ( path != null )
325 {
326 workingDir = path;
327 }
328 }
329
330
331
332
333 public void setWorkingDirectory( File workingDir )
334 {
335 if ( workingDir != null )
336 {
337 this.workingDir = workingDir.getAbsolutePath();
338 }
339 }
340
341 public File getWorkingDirectory()
342 {
343 return workingDir == null ? null : new File( workingDir );
344 }
345
346 String getWorkingDirectoryAsString()
347 {
348 return workingDir;
349 }
350
351 public Object clone()
352 {
353 throw new RuntimeException( "Do we ever clone this?" );
354
355
356
357
358
359 }
360
361 void setSingleQuotedArgumentEscaped( boolean singleQuotedArgumentEscaped )
362 {
363 this.singleQuotedArgumentEscaped = singleQuotedArgumentEscaped;
364 }
365
366 void setSingleQuotedExecutableEscaped( boolean singleQuotedExecutableEscaped )
367 {
368 this.singleQuotedExecutableEscaped = singleQuotedExecutableEscaped;
369 }
370
371 }