View Javadoc
1   package org.codehaus.plexus.util.cli.shell;
2   
3   /*
4    * Copyright The Codehaus Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import java.util.Arrays;
20  import java.util.List;
21  
22  /**
23   * <p>
24   * Implementation to call the CMD Shell present on Windows NT, 2000 and XP
25   * </p>
26   *
27   * @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
28   * @since 1.2
29   *
30   */
31  public class CmdShell
32      extends Shell
33  {
34      public CmdShell()
35      {
36          setShellCommand( "cmd.exe" );
37          setQuotedExecutableEnabled( true );
38          setShellArgs( new String[] { "/X", "/C" } );
39      }
40  
41      /**
42       * <p>
43       * Specific implementation that quotes all the command line.
44       * </p>
45       * <p>
46       * Workaround for http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6468220
47       * </p>
48       * <p>
49       * From cmd.exe /? output:
50       * </p>
51       *
52       * <pre>
53       *      If /C or /K is specified, then the remainder of the command line after
54       *      the switch is processed as a command line, where the following logic is
55       *      used to process quote (&quot;) characters:
56       *
57       *      1.  If all of the following conditions are met, then quote characters
58       *      on the command line are preserved:
59       *
60       *      - no /S switch
61       *      - exactly two quote characters
62       *      - no special characters between the two quote characters,
63       *      where special is one of: &amp;&lt;&gt;()@&circ;|
64       *      - there are one or more whitespace characters between the
65       *      the two quote characters
66       *      - the string between the two quote characters is the name
67       *      of an executable file.
68       *
69       *      2.  Otherwise, old behavior is to see if the first character is
70       *      a quote character and if so, strip the leading character and
71       *      remove the last quote character on the command line, preserving
72       *      any text after the last quote character.
73       * </pre>
74       * <p>
75       * Always quoting the entire command line, regardless of these conditions appears to make Windows processes invoke
76       * successfully.
77       * </p>
78       */
79      @Override
80      public List<String> getCommandLine( String executable, String[] arguments )
81      {
82          StringBuilder sb = new StringBuilder();
83          sb.append( "\"" );
84          sb.append( super.getCommandLine( executable, arguments ).get( 0 ) );
85          sb.append( "\"" );
86  
87          return Arrays.asList( new String[] { sb.toString() } );
88      }
89  }