View Javadoc
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 }