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      public BourneShell()
38      {
39          setShellCommand( "/bin/sh" );
40          setArgumentQuoteDelimiter( '\'' );
41          setExecutableQuoteDelimiter( '\"' );
42          setSingleQuotedArgumentEscaped( true );
43          setSingleQuotedExecutableEscaped( false );
44          setQuotedExecutableEnabled( true );
45      }
46  
47      /**
48       * {@inheritDoc}
49       */
50      public String getExecutable()
51      {
52          if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
53          {
54              return super.getExecutable();
55          }
56  
57          return unifyQuotes( super.getExecutable() );
58      }
59  
60      public List<String> getShellArgsList()
61      {
62          List<String> shellArgs = new ArrayList<String>();
63          List<String> existingShellArgs = super.getShellArgsList();
64  
65          if ( ( existingShellArgs != null ) && !existingShellArgs.isEmpty() )
66          {
67              shellArgs.addAll( existingShellArgs );
68          }
69  
70          shellArgs.add( "-c" );
71  
72          return shellArgs;
73      }
74  
75      public String[] getShellArgs()
76      {
77          String[] shellArgs = super.getShellArgs();
78          if ( shellArgs == null )
79          {
80              shellArgs = new String[0];
81          }
82  
83          if ( ( shellArgs.length > 0 ) && !shellArgs[shellArgs.length - 1].equals( "-c" ) )
84          {
85              String[] newArgs = new String[shellArgs.length + 1];
86  
87              System.arraycopy( shellArgs, 0, newArgs, 0, shellArgs.length );
88              newArgs[shellArgs.length] = "-c";
89  
90              shellArgs = newArgs;
91          }
92  
93          return shellArgs;
94      }
95  
96      protected String getExecutionPreamble()
97      {
98          if ( getWorkingDirectoryAsString() == null )
99          {
100             return null;
101         }
102 
103         String dir = getWorkingDirectoryAsString();
104         StringBuilder sb = new StringBuilder();
105         sb.append( "cd " );
106 
107         sb.append( unifyQuotes( dir ) );
108         sb.append( " && " );
109 
110         return sb.toString();
111     }
112 
113     protected char[] getQuotingTriggerChars()
114     {
115         return BASH_QUOTING_TRIGGER_CHARS;
116     }
117 
118     /**
119      * <p>Unify quotes in a path for the Bourne Shell.</p>
120      * <p/>
121      * <pre>
122      * BourneShell.unifyQuotes(null)                       = null
123      * BourneShell.unifyQuotes("")                         = (empty)
124      * BourneShell.unifyQuotes("/test/quotedpath'abc")     = /test/quotedpath\'abc
125      * BourneShell.unifyQuotes("/test/quoted path'abc")    = "/test/quoted path'abc"
126      * BourneShell.unifyQuotes("/test/quotedpath\"abc")    = "/test/quotedpath\"abc"
127      * BourneShell.unifyQuotes("/test/quoted path\"abc")   = "/test/quoted path\"abc"
128      * BourneShell.unifyQuotes("/test/quotedpath\"'abc")   = "/test/quotedpath\"'abc"
129      * BourneShell.unifyQuotes("/test/quoted path\"'abc")  = "/test/quoted path\"'abc"
130      * </pre>
131      *
132      * @param path not null path.
133      * @return the path unified correctly for the Bourne shell.
134      */
135     private static String unifyQuotes( String path )
136     {
137         if ( path == null )
138         {
139             return null;
140         }
141 
142         if ( path.indexOf( ' ' ) == -1 && path.indexOf( '\'' ) != -1 && path.indexOf( '"' ) == -1 )
143         {
144             return StringUtils.escape( path );
145         }
146 
147         return StringUtils.quoteAndEscape( path, '\"', BASH_QUOTING_TRIGGER_CHARS );
148     }
149 }