1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.commons.cli;
19
20 import java.io.Serializable;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Iterator;
24 import java.util.LinkedList;
25 import java.util.List;
26 import java.util.Properties;
27
28 /**
29 * Represents list of arguments parsed against a {@link Options} descriptor.
30 * <p>
31 * It allows querying of a boolean {@link #hasOption(String opt)},
32 * in addition to retrieving the {@link #getOptionValue(String opt)}
33 * for options requiring arguments.
34 * <p>
35 * Additionally, any left-over or unrecognized arguments,
36 * are available for further processing.
37 *
38 * @version $Id: CommandLine.java 1444365 2013-02-09 14:21:27Z tn $
39 */
40 public class CommandLine implements Serializable
41 {
42 /** The serial version UID. */
43 private static final long serialVersionUID = 1L;
44
45 /** the unrecognised options/arguments */
46 private final List<String> args = new LinkedList<String>();
47
48 /** the processed options */
49 private final List<Option> options = new ArrayList<Option>();
50
51 /**
52 * Creates a command line.
53 */
54 protected CommandLine()
55 {
56 // nothing to do
57 }
58
59 /**
60 * Query to see if an option has been set.
61 *
62 * @param opt Short name of the option
63 * @return true if set, false if not
64 */
65 public boolean hasOption(String opt)
66 {
67 return options.contains(resolveOption(opt));
68 }
69
70 /**
71 * Query to see if an option has been set.
72 *
73 * @param opt character name of the option
74 * @return true if set, false if not
75 */
76 public boolean hasOption(char opt)
77 {
78 return hasOption(String.valueOf(opt));
79 }
80
81 /**
82 * Return the <code>Object</code> type of this <code>Option</code>.
83 *
84 * @param opt the name of the option
85 * @return the type of this <code>Option</code>
86 * @deprecated due to System.err message. Instead use getParsedOptionValue(String)
87 */
88 @Deprecated
89 public Object getOptionObject(String opt)
90 {
91 try
92 {
93 return getParsedOptionValue(opt);
94 }
95 catch (ParseException pe)
96 {
97 System.err.println("Exception found converting " + opt + " to desired type: " + pe.getMessage());
98 return null;
99 }
100 }
101
102 /**
103 * Return a version of this <code>Option</code> converted to a particular type.
104 *
105 * @param opt the name of the option
106 * @return the value parsed into a particular object
107 * @throws ParseException if there are problems turning the option value into the desired type
108 * @see PatternOptionBuilder
109 * @since 1.2
110 */
111 public Object getParsedOptionValue(String opt) throws ParseException
112 {
113 String res = getOptionValue(opt);
114 Option option = resolveOption(opt);
115
116 if (option == null || res == null)
117 {
118 return null;
119 }
120
121 return TypeHandler.createValue(res, option.getType());
122 }
123
124 /**
125 * Return the <code>Object</code> type of this <code>Option</code>.
126 *
127 * @param opt the name of the option
128 * @return the type of opt
129 */
130 public Object getOptionObject(char opt)
131 {
132 return getOptionObject(String.valueOf(opt));
133 }
134
135 /**
136 * Retrieve the first argument, if any, of this option.
137 *
138 * @param opt the name of the option
139 * @return Value of the argument if option is set, and has an argument,
140 * otherwise null.
141 */
142 public String getOptionValue(String opt)
143 {
144 String[] values = getOptionValues(opt);
145
146 return (values == null) ? null : values[0];
147 }
148
149 /**
150 * Retrieve the first argument, if any, of this option.
151 *
152 * @param opt the character name of the option
153 * @return Value of the argument if option is set, and has an argument,
154 * otherwise null.
155 */
156 public String getOptionValue(char opt)
157 {
158 return getOptionValue(String.valueOf(opt));
159 }
160
161 /**
162 * Retrieves the array of values, if any, of an option.
163 *
164 * @param opt string name of the option
165 * @return Values of the argument if option is set, and has an argument,
166 * otherwise null.
167 */
168 public String[] getOptionValues(String opt)
169 {
170 List<String> values = new ArrayList<String>();
171
172 for (Option option : options)
173 {
174 if (opt.equals(option.getOpt()) || opt.equals(option.getLongOpt()))
175 {
176 values.addAll(option.getValuesList());
177 }
178 }
179
180 return values.isEmpty() ? null : values.toArray(new String[values.size()]);
181 }
182
183 /**
184 * Retrieves the option object given the long or short option as a String
185 *
186 * @param opt short or long name of the option
187 * @return Canonicalized option
188 */
189 private Option resolveOption(String opt)
190 {
191 opt = Util.stripLeadingHyphens(opt);
192 for (Option option : options)
193 {
194 if (opt.equals(option.getOpt()))
195 {
196 return option;
197 }
198
199 if (opt.equals(option.getLongOpt()))
200 {
201 return option;
202 }
203
204 }
205 return null;
206 }
207
208 /**
209 * Retrieves the array of values, if any, of an option.
210 *
211 * @param opt character name of the option
212 * @return Values of the argument if option is set, and has an argument,
213 * otherwise null.
214 */
215 public String[] getOptionValues(char opt)
216 {
217 return getOptionValues(String.valueOf(opt));
218 }
219
220 /**
221 * Retrieve the first argument, if any, of an option.
222 *
223 * @param opt name of the option
224 * @param defaultValue is the default value to be returned if the option
225 * is not specified
226 * @return Value of the argument if option is set, and has an argument,
227 * otherwise <code>defaultValue</code>.
228 */
229 public String getOptionValue(String opt, String defaultValue)
230 {
231 String answer = getOptionValue(opt);
232
233 return (answer != null) ? answer : defaultValue;
234 }
235
236 /**
237 * Retrieve the argument, if any, of an option.
238 *
239 * @param opt character name of the option
240 * @param defaultValue is the default value to be returned if the option
241 * is not specified
242 * @return Value of the argument if option is set, and has an argument,
243 * otherwise <code>defaultValue</code>.
244 */
245 public String getOptionValue(char opt, String defaultValue)
246 {
247 return getOptionValue(String.valueOf(opt), defaultValue);
248 }
249
250 /**
251 * Retrieve the map of values associated to the option. This is convenient
252 * for options specifying Java properties like <tt>-Dparam1=value1
253 * -Dparam2=value2</tt>. The first argument of the option is the key, and
254 * the 2nd argument is the value. If the option has only one argument
255 * (<tt>-Dfoo</tt>) it is considered as a boolean flag and the value is
256 * <tt>"true"</tt>.
257 *
258 * @param opt name of the option
259 * @return The Properties mapped by the option, never <tt>null</tt>
260 * even if the option doesn't exists
261 * @since 1.2
262 */
263 public Properties getOptionProperties(String opt)
264 {
265 Properties props = new Properties();
266
267 for (Option option : options)
268 {
269 if (opt.equals(option.getOpt()) || opt.equals(option.getLongOpt()))
270 {
271 List<String> values = option.getValuesList();
272 if (values.size() >= 2)
273 {
274 // use the first 2 arguments as the key/value pair
275 props.put(values.get(0), values.get(1));
276 }
277 else if (values.size() == 1)
278 {
279 // no explicit value, handle it as a boolean
280 props.put(values.get(0), "true");
281 }
282 }
283 }
284
285 return props;
286 }
287
288 /**
289 * Retrieve any left-over non-recognized options and arguments
290 *
291 * @return remaining items passed in but not parsed as an array
292 */
293 public String[] getArgs()
294 {
295 String[] answer = new String[args.size()];
296
297 args.toArray(answer);
298
299 return answer;
300 }
301
302 /**
303 * Retrieve any left-over non-recognized options and arguments
304 *
305 * @return remaining items passed in but not parsed as a <code>List</code>.
306 */
307 public List<String> getArgList()
308 {
309 return args;
310 }
311
312 /**
313 * jkeyes
314 * - commented out until it is implemented properly
315 * <p>Dump state, suitable for debugging.</p>
316 *
317 * @return Stringified form of this object
318 */
319
320 /*
321 public String toString() {
322 StringBuilder buf = new StringBuilder();
323
324 buf.append("[ CommandLine: [ options: ");
325 buf.append(options.toString());
326 buf.append(" ] [ args: ");
327 buf.append(args.toString());
328 buf.append(" ] ]");
329
330 return buf.toString();
331 }
332 */
333
334 /**
335 * Add left-over unrecognized option/argument.
336 *
337 * @param arg the unrecognised option/argument.
338 */
339 protected void addArg(String arg)
340 {
341 args.add(arg);
342 }
343
344 /**
345 * Add an option to the command line. The values of the option are stored.
346 *
347 * @param opt the processed option
348 */
349 protected void addOption(Option opt)
350 {
351 options.add(opt);
352 }
353
354 /**
355 * Returns an iterator over the Option members of CommandLine.
356 *
357 * @return an <code>Iterator</code> over the processed {@link Option}
358 * members of this {@link CommandLine}
359 */
360 public Iterator<Option> iterator()
361 {
362 return options.iterator();
363 }
364
365 /**
366 * Returns an array of the processed {@link Option}s.
367 *
368 * @return an array of the processed {@link Option}s.
369 */
370 public Option[] getOptions()
371 {
372 Collection<Option> processed = options;
373
374 // reinitialise array
375 Option[] optionsArray = new Option[processed.size()];
376
377 // return the array
378 return processed.toArray(optionsArray);
379 }
380 }