1 //
2 // ========================================================================
3 // Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // All rights reserved. This program and the accompanying materials
6 // are made available under the terms of the Eclipse Public License v1.0
7 // and Apache License v2.0 which accompanies this distribution.
8 //
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
11 //
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
14 //
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
17 //
18
19 package org.eclipse.jetty.start;
20
21 import java.io.File;
22 import java.util.ArrayList;
23 import java.util.List;
24
25 public class CommandLineBuilder
26 {
27 public static File findExecutable(File root, String path)
28 {
29 String npath = path.replace('/',File.separatorChar);
30 File exe = new File(root,npath);
31 if (!exe.exists())
32 {
33 return null;
34 }
35 return exe;
36 }
37
38 public static String findJavaBin()
39 {
40 File javaHome = new File(System.getProperty("java.home"));
41 if (!javaHome.exists())
42 {
43 return null;
44 }
45
46 File javabin = findExecutable(javaHome,"bin/java");
47 if (javabin != null)
48 {
49 return javabin.getAbsolutePath();
50 }
51
52 javabin = findExecutable(javaHome,"bin/java.exe");
53 if (javabin != null)
54 {
55 return javabin.getAbsolutePath();
56 }
57
58 return "java";
59 }
60
61 /**
62 * Perform an optional quoting of the argument, being intelligent with spaces and quotes as needed. If a subString is set in quotes it won't the subString
63 * won't be escaped.
64 *
65 * @param arg the argument to quote
66 * @return the quoted and escaped argument
67 */
68 public static String quote(String arg)
69 {
70 boolean needsQuoting = (arg.indexOf(' ') >= 0) || (arg.indexOf('"') >= 0);
71 if (!needsQuoting)
72 {
73 return arg;
74 }
75 StringBuilder buf = new StringBuilder();
76 // buf.append('"');
77 boolean escaped = false;
78 boolean quoted = false;
79 for (char c : arg.toCharArray())
80 {
81 if (!quoted && !escaped && ((c == '"') || (c == ' ')))
82 {
83 buf.append("\\");
84 }
85 // don't quote text in single quotes
86 if (!escaped && (c == '\''))
87 {
88 quoted = !quoted;
89 }
90 escaped = (c == '\\');
91 buf.append(c);
92 }
93 // buf.append('"');
94 return buf.toString();
95 }
96
97 private List<String> args;
98
99 public CommandLineBuilder()
100 {
101 args = new ArrayList<String>();
102 }
103
104 public CommandLineBuilder(String bin)
105 {
106 this();
107 args.add(bin);
108 }
109
110 /**
111 * Add a simple argument to the command line.
112 * <p>
113 * Will quote arguments that have a space in them.
114 *
115 * @param arg
116 * the simple argument to add
117 */
118 public void addArg(String arg)
119 {
120 if (arg != null)
121 {
122 args.add(quote(arg));
123 }
124 }
125
126 /**
127 * Similar to {@link #addArg(String)} but concats both name + value with an "=" sign, quoting were needed, and excluding the "=" portion if the value is
128 * undefined or empty.
129 *
130 * <pre>
131 * addEqualsArg("-Dname", "value") = "-Dname=value"
132 * addEqualsArg("-Djetty.home", "/opt/company inc/jetty (7)/") = "-Djetty.home=/opt/company\ inc/jetty\ (7)/"
133 * addEqualsArg("-Djenkins.workspace", "/opt/workspaces/jetty jdk7/") = "-Djenkins.workspace=/opt/workspaces/jetty\ jdk7/"
134 * addEqualsArg("-Dstress", null) = "-Dstress"
135 * addEqualsArg("-Dstress", "") = "-Dstress"
136 * </pre>
137 *
138 * @param name
139 * the name
140 * @param value
141 * the value
142 */
143 public void addEqualsArg(String name, String value)
144 {
145 if ((value != null) && (value.length() > 0))
146 {
147 args.add(quote(name + "=" + value));
148 }
149 else
150 {
151 args.add(quote(name));
152 }
153 }
154
155 /**
156 * Add a simple argument to the command line.
157 * <p>
158 * Will <b>NOT</b> quote/escape arguments that have a space in them.
159 *
160 * @param arg
161 * the simple argument to add
162 */
163 public void addRawArg(String arg)
164 {
165 if (arg != null)
166 {
167 args.add(arg);
168 }
169 }
170
171 public List<String> getArgs()
172 {
173 return args;
174 }
175
176 @Override
177 public String toString()
178 {
179 return toString(" ");
180 }
181
182 public String toString(String delim)
183 {
184 StringBuilder buf = new StringBuilder();
185
186 for (String arg : args)
187 {
188 if (buf.length()>0)
189 {
190 buf.append(delim);
191 }
192 buf.append(quote(arg));
193 }
194
195 return buf.toString();
196 }
197
198 public void debug()
199 {
200 if (!StartLog.isDebugEnabled())
201 {
202 return;
203 }
204
205 int len = args.size();
206 StartLog.debug("Command Line: %,d entries",args.size());
207 for (int i = 0; i < len; i++)
208 {
209 StartLog.debug(" [%d]: \"%s\"",i,args.get(i));
210 }
211 }
212 }