001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.commons.cli;
019
020 import java.io.Serializable;
021 import java.util.ArrayList;
022 import java.util.Collection;
023 import java.util.Iterator;
024 import java.util.LinkedList;
025 import java.util.List;
026 import java.util.Properties;
027
028 /**
029 * Represents list of arguments parsed against a {@link Options} descriptor.
030 *
031 * <p>It allows querying of a boolean {@link #hasOption(String opt)},
032 * in addition to retrieving the {@link #getOptionValue(String opt)}
033 * for options requiring arguments.</p>
034 *
035 * <p>Additionally, any left-over or unrecognized arguments,
036 * are available for further processing.</p>
037 *
038 * @author bob mcwhirter (bob @ werken.com)
039 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
040 * @author John Keyes (john at integralsource.com)
041 * @version $Revision: 735247 $, $Date: 2009-01-17 00:23:35 -0800 (Sat, 17 Jan 2009) $
042 */
043 public class CommandLine implements Serializable
044 {
045 private static final long serialVersionUID = 1L;
046
047 /** the unrecognised options/arguments */
048 private List args = new LinkedList();
049
050 /** the processed options */
051 private List options = new ArrayList();
052
053 /**
054 * Creates a command line.
055 */
056 CommandLine()
057 {
058 // nothing to do
059 }
060
061 /**
062 * Query to see if an option has been set.
063 *
064 * @param opt Short name of the option
065 * @return true if set, false if not
066 */
067 public boolean hasOption(String opt)
068 {
069 return options.contains(resolveOption(opt));
070 }
071
072 /**
073 * Query to see if an option has been set.
074 *
075 * @param opt character name of the option
076 * @return true if set, false if not
077 */
078 public boolean hasOption(char opt)
079 {
080 return hasOption(String.valueOf(opt));
081 }
082
083 /**
084 * Return the <code>Object</code> type of this <code>Option</code>.
085 *
086 * @param opt the name of the option
087 * @return the type of this <code>Option</code>
088 * @deprecated due to System.err message. Instead use getParsedOptionValue(String)
089 */
090 public Object getOptionObject(String opt)
091 {
092 try {
093 return getParsedOptionValue(opt);
094 } catch(ParseException pe) {
095 System.err.println("Exception found converting " + opt + " to desired type: " +
096 pe.getMessage() );
097 return null;
098 }
099 }
100
101 /**
102 * Return a version of this <code>Option</code> converted to a particular type.
103 *
104 * @param opt the name of the option
105 * @return the value parsed into a particluar object
106 * @throws ParseException if there are problems turning the option value into the desired type
107 * @see PatternOptionBuilder
108 */
109 public Object getParsedOptionValue(String opt)
110 throws ParseException
111 {
112 String res = getOptionValue(opt);
113
114 Option option = resolveOption(opt);
115 if (option == null)
116 {
117 return null;
118 }
119
120 Object type = option.getType();
121
122 return (res == null) ? null : TypeHandler.createValue(res, type);
123 }
124
125 /**
126 * Return the <code>Object</code> type of this <code>Option</code>.
127 *
128 * @param opt the name of the option
129 * @return the type of opt
130 */
131 public Object getOptionObject(char opt)
132 {
133 return getOptionObject(String.valueOf(opt));
134 }
135
136 /**
137 * Retrieve the argument, if any, of this option.
138 *
139 * @param opt the name of the option
140 * @return Value of the argument if option is set, and has an argument,
141 * otherwise null.
142 */
143 public String getOptionValue(String opt)
144 {
145 String[] values = getOptionValues(opt);
146
147 return (values == null) ? null : values[0];
148 }
149
150 /**
151 * Retrieve the argument, if any, of this option.
152 *
153 * @param opt the character name of the option
154 * @return Value of the argument if option is set, and has an argument,
155 * otherwise null.
156 */
157 public String getOptionValue(char opt)
158 {
159 return getOptionValue(String.valueOf(opt));
160 }
161
162 /**
163 * Retrieves the array of values, if any, of an option.
164 *
165 * @param opt string name of the option
166 * @return Values of the argument if option is set, and has an argument,
167 * otherwise null.
168 */
169 public String[] getOptionValues(String opt)
170 {
171 List values = new ArrayList();
172
173 for (Iterator it = options.iterator(); it.hasNext();)
174 {
175 Option option = (Option) it.next();
176 if (opt.equals(option.getOpt()) || opt.equals(option.getLongOpt()))
177 {
178 values.addAll(option.getValuesList());
179 }
180 }
181
182 return values.isEmpty() ? null : (String[]) values.toArray(new String[values.size()]);
183 }
184
185 /**
186 * Retrieves the option object given the long or short option as a String
187 *
188 * @param opt short or long name of the option
189 * @return Canonicalized option
190 */
191 private Option resolveOption(String opt)
192 {
193 opt = Util.stripLeadingHyphens(opt);
194 for (Iterator it = options.iterator(); it.hasNext();)
195 {
196 Option option = (Option) it.next();
197 if (opt.equals(option.getOpt()))
198 {
199 return option;
200 }
201
202 if (opt.equals(option.getLongOpt()))
203 {
204 return option;
205 }
206
207 }
208 return null;
209 }
210
211 /**
212 * Retrieves the array of values, if any, of an option.
213 *
214 * @param opt character name of the option
215 * @return Values of the argument if option is set, and has an argument,
216 * otherwise null.
217 */
218 public String[] getOptionValues(char opt)
219 {
220 return getOptionValues(String.valueOf(opt));
221 }
222
223 /**
224 * Retrieve the argument, if any, of an option.
225 *
226 * @param opt name of the option
227 * @param defaultValue is the default value to be returned if the option
228 * is not specified
229 * @return Value of the argument if option is set, and has an argument,
230 * otherwise <code>defaultValue</code>.
231 */
232 public String getOptionValue(String opt, String defaultValue)
233 {
234 String answer = getOptionValue(opt);
235
236 return (answer != null) ? answer : defaultValue;
237 }
238
239 /**
240 * Retrieve the argument, if any, of an option.
241 *
242 * @param opt character name of the option
243 * @param defaultValue is the default value to be returned if the option
244 * is not specified
245 * @return Value of the argument if option is set, and has an argument,
246 * otherwise <code>defaultValue</code>.
247 */
248 public String getOptionValue(char opt, String defaultValue)
249 {
250 return getOptionValue(String.valueOf(opt), defaultValue);
251 }
252
253 /**
254 * Retrieve the map of values associated to the option. This is convenient
255 * for options specifying Java properties like <tt>-Dparam1=value1
256 * -Dparam2=value2</tt>. The first argument of the option is the key, and
257 * the 2nd argument is the value. If the option has only one argument
258 * (<tt>-Dfoo</tt>) it is considered as a boolean flag and the value is
259 * <tt>"true"</tt>.
260 *
261 * @param opt name of the option
262 * @return The Properties mapped by the option, never <tt>null</tt>
263 * even if the option doesn't exists
264 * @since 1.2
265 */
266 public Properties getOptionProperties(String opt)
267 {
268 Properties props = new Properties();
269
270 for (Iterator it = options.iterator(); it.hasNext();)
271 {
272 Option option = (Option) it.next();
273
274 if (opt.equals(option.getOpt()) || opt.equals(option.getLongOpt()))
275 {
276 List values = option.getValuesList();
277 if (values.size() >= 2)
278 {
279 // use the first 2 arguments as the key/value pair
280 props.put(values.get(0), values.get(1));
281 }
282 else if (values.size() == 1)
283 {
284 // no explicit value, handle it as a boolean
285 props.put(values.get(0), "true");
286 }
287 }
288 }
289
290 return props;
291 }
292
293 /**
294 * Retrieve any left-over non-recognized options and arguments
295 *
296 * @return remaining items passed in but not parsed as an array
297 */
298 public String[] getArgs()
299 {
300 String[] answer = new String[args.size()];
301
302 args.toArray(answer);
303
304 return answer;
305 }
306
307 /**
308 * Retrieve any left-over non-recognized options and arguments
309 *
310 * @return remaining items passed in but not parsed as a <code>List</code>.
311 */
312 public List getArgList()
313 {
314 return args;
315 }
316
317 /**
318 * jkeyes
319 * - commented out until it is implemented properly
320 * <p>Dump state, suitable for debugging.</p>
321 *
322 * @return Stringified form of this object
323 */
324
325 /*
326 public String toString() {
327 StringBuffer buf = new StringBuffer();
328
329 buf.append("[ CommandLine: [ options: ");
330 buf.append(options.toString());
331 buf.append(" ] [ args: ");
332 buf.append(args.toString());
333 buf.append(" ] ]");
334
335 return buf.toString();
336 }
337 */
338
339 /**
340 * Add left-over unrecognized option/argument.
341 *
342 * @param arg the unrecognised option/argument.
343 */
344 void addArg(String arg)
345 {
346 args.add(arg);
347 }
348
349 /**
350 * Add an option to the command line. The values of the option are stored.
351 *
352 * @param opt the processed option
353 */
354 void addOption(Option opt)
355 {
356 options.add(opt);
357 }
358
359 /**
360 * Returns an iterator over the Option members of CommandLine.
361 *
362 * @return an <code>Iterator</code> over the processed {@link Option}
363 * members of this {@link CommandLine}
364 */
365 public Iterator iterator()
366 {
367 return options.iterator();
368 }
369
370 /**
371 * Returns an array of the processed {@link Option}s.
372 *
373 * @return an array of the processed {@link Option}s.
374 */
375 public Option[] getOptions()
376 {
377 Collection processed = options;
378
379 // reinitialise array
380 Option[] optionsArray = new Option[processed.size()];
381
382 // return the array
383 return (Option[]) processed.toArray(optionsArray);
384 }
385 }