1 package org.apache.maven.shared.utils.cli.shell;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22
23 import java.util.ArrayList;
24 import java.util.List;
25 import org.apache.maven.shared.utils.Os;
26 import org.apache.maven.shared.utils.StringUtils;
27
28 /**
29 * @author Jason van Zyl
30 */
31 public class BourneShell
32 extends Shell
33 {
34 private static final char[] BASH_QUOTING_TRIGGER_CHARS =
35 { ' ', '$', ';', '&', '|', '<', '>', '*', '?', '(', ')', '[', ']', '{', '}', '`' };
36
37 /**
38 * Create instance of BournShell.
39 */
40 public BourneShell()
41 {
42 setShellCommand( "/bin/sh" );
43 setArgumentQuoteDelimiter( '\'' );
44 setExecutableQuoteDelimiter( '\"' );
45 setSingleQuotedArgumentEscaped( true );
46 setSingleQuotedExecutableEscaped( false );
47 setQuotedExecutableEnabled( true );
48 }
49
50 /**
51 * {@inheritDoc}
52 */
53 public String getExecutable()
54 {
55 if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
56 {
57 return super.getExecutable();
58 }
59
60 return unifyQuotes( super.getExecutable() );
61 }
62
63 /** {@inheritDoc} */
64 public List<String> getShellArgsList()
65 {
66 List<String> shellArgs = new ArrayList<String>();
67 List<String> existingShellArgs = super.getShellArgsList();
68
69 if ( ( existingShellArgs != null ) && !existingShellArgs.isEmpty() )
70 {
71 shellArgs.addAll( existingShellArgs );
72 }
73
74 shellArgs.add( "-c" );
75
76 return shellArgs;
77 }
78
79 /** {@inheritDoc} */
80 public String[] getShellArgs()
81 {
82 String[] shellArgs = super.getShellArgs();
83 if ( shellArgs == null )
84 {
85 shellArgs = new String[0];
86 }
87
88 if ( ( shellArgs.length > 0 ) && !shellArgs[shellArgs.length - 1].equals( "-c" ) )
89 {
90 String[] newArgs = new String[shellArgs.length + 1];
91
92 System.arraycopy( shellArgs, 0, newArgs, 0, shellArgs.length );
93 newArgs[shellArgs.length] = "-c";
94
95 shellArgs = newArgs;
96 }
97
98 return shellArgs;
99 }
100
101 /** {@inheritDoc} */
102 protected String getExecutionPreamble()
103 {
104 if ( getWorkingDirectoryAsString() == null )
105 {
106 return null;
107 }
108
109 String dir = getWorkingDirectoryAsString();
110 StringBuilder sb = new StringBuilder();
111 sb.append( "cd " );
112
113 sb.append( unifyQuotes( dir ) );
114 sb.append( " && " );
115
116 return sb.toString();
117 }
118
119 /** {@inheritDoc} */
120 protected char[] getQuotingTriggerChars()
121 {
122 return BASH_QUOTING_TRIGGER_CHARS;
123 }
124
125 /**
126 * <p>Unify quotes in a path for the Bourne Shell.</p>
127 * <p/>
128 * <pre>
129 * BourneShell.unifyQuotes(null) = null
130 * BourneShell.unifyQuotes("") = (empty)
131 * BourneShell.unifyQuotes("/test/quotedpath'abc") = /test/quotedpath\'abc
132 * BourneShell.unifyQuotes("/test/quoted path'abc") = "/test/quoted path'abc"
133 * BourneShell.unifyQuotes("/test/quotedpath\"abc") = "/test/quotedpath\"abc"
134 * BourneShell.unifyQuotes("/test/quoted path\"abc") = "/test/quoted path\"abc"
135 * BourneShell.unifyQuotes("/test/quotedpath\"'abc") = "/test/quotedpath\"'abc"
136 * BourneShell.unifyQuotes("/test/quoted path\"'abc") = "/test/quoted path\"'abc"
137 * </pre>
138 *
139 * @param path not null path.
140 * @return the path unified correctly for the Bourne shell.
141 */
142 private static String unifyQuotes( String path )
143 {
144 if ( path == null )
145 {
146 return null;
147 }
148
149 if ( path.indexOf( ' ' ) == -1 && path.indexOf( '\'' ) != -1 && path.indexOf( '"' ) == -1 )
150 {
151 return StringUtils.escape( path );
152 }
153
154 return StringUtils.quoteAndEscape( path, '\"', BASH_QUOTING_TRIGGER_CHARS );
155 }
156 }