1 //
2 // ========================================================================
3 // Copyright (c) 1995-2014 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
66 * @return
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 * <p>
130 *
131 * <pre>
132 * addEqualsArg("-Dname", "value") = "-Dname=value"
133 * addEqualsArg("-Djetty.home", "/opt/company inc/jetty (7)/") = "-Djetty.home=/opt/company\ inc/jetty\ (7)/"
134 * addEqualsArg("-Djenkins.workspace", "/opt/workspaces/jetty jdk7/") = "-Djenkins.workspace=/opt/workspaces/jetty\ jdk7/"
135 * addEqualsArg("-Dstress", null) = "-Dstress"
136 * addEqualsArg("-Dstress", "") = "-Dstress"
137 * </pre>
138 *
139 * @param name
140 * the name
141 * @param value
142 * the value
143 */
144 public void addEqualsArg(String name, String value)
145 {
146 if ((value != null) && (value.length() > 0))
147 {
148 args.add(quote(name + "=" + value));
149 }
150 else
151 {
152 args.add(quote(name));
153 }
154 }
155
156 /**
157 * Add a simple argument to the command line.
158 * <p>
159 * Will <b>NOT</b> quote/escape arguments that have a space in them.
160 *
161 * @param arg
162 * the simple argument to add
163 */
164 public void addRawArg(String arg)
165 {
166 if (arg != null)
167 {
168 args.add(arg);
169 }
170 }
171
172 public List<String> getArgs()
173 {
174 return args;
175 }
176
177 @Override
178 public String toString()
179 {
180 StringBuilder buf = new StringBuilder();
181
182 boolean delim = false;
183 for (String arg : args)
184 {
185 if (delim)
186 {
187 buf.append(' ');
188 }
189 buf.append(quote(arg));
190 delim = true;
191 }
192
193 return buf.toString();
194 }
195
196 public void debug()
197 {
198 if (!StartLog.isDebugEnabled())
199 {
200 return;
201 }
202
203 int len = args.size();
204 StartLog.debug("Command Line: %,d entries",args.size());
205 for (int i = 0; i < len; i++)
206 {
207 StartLog.debug(" [%d]: \"%s\"",i,args.get(i));
208 }
209 }
210 }