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