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   *
31   * <p>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.</p>
34   *
35   * <p>Additionally, any left-over or unrecognized arguments,
36   * are available for further processing.</p>
37   *
38   * @author bob mcwhirter (bob @ werken.com)
39   * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
40   * @author John Keyes (john at integralsource.com)
41   * @version $Revision: 735247 $, $Date: 2009-01-17 08:23:35 +0000 (Sat, 17 Jan 2009) $
42   */
43  public class CommandLine implements Serializable
44  {
45      private static final long serialVersionUID = 1L;
46  
47      /** the unrecognised options/arguments */
48      private List args = new LinkedList();
49  
50      /** the processed options */
51      private List options = new ArrayList();
52  
53      /**
54       * Creates a command line.
55       */
56      CommandLine()
57      {
58          // nothing to do
59      }
60  
61      /** 
62       * Query to see if an option has been set.
63       *
64       * @param opt Short name of the option
65       * @return true if set, false if not
66       */
67      public boolean hasOption(String opt)
68      {
69          return options.contains(resolveOption(opt));
70      }
71  
72      /** 
73       * Query to see if an option has been set.
74       *
75       * @param opt character name of the option
76       * @return true if set, false if not
77       */
78      public boolean hasOption(char opt)
79      {
80          return hasOption(String.valueOf(opt));
81      }
82  
83      /**
84       * Return the <code>Object</code> type of this <code>Option</code>.
85       *
86       * @param opt the name of the option
87       * @return the type of this <code>Option</code>
88       * @deprecated due to System.err message. Instead use getParsedOptionValue(String)
89       */
90      public Object getOptionObject(String opt)
91      {
92          try {
93              return getParsedOptionValue(opt);
94          } catch(ParseException pe) {
95              System.err.println("Exception found converting " + opt + " to desired type: " + 
96                  pe.getMessage() );
97              return null;
98          }
99      }
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 }