View Javadoc
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 }