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.Iterator;
23  import java.util.LinkedList;
24  import java.util.List;
25  import java.util.Objects;
26  import java.util.Properties;
27  import java.util.function.Consumer;
28  import java.util.function.Supplier;
29  
30  /**
31   * Represents list of arguments parsed against a {@link Options} descriptor.
32   * <p>
33   * It allows querying of a boolean {@link #hasOption(String opt)}, in addition to retrieving the
34   * {@link #getOptionValue(String opt)} for options requiring arguments.
35   * </p>
36   * <p>
37   * Additionally, any left-over or unrecognized arguments, are available for further processing.
38   * </p>
39   */
40  public class CommandLine implements Serializable {
41  
42      /**
43       * A nested builder class to create {@code CommandLine} instance using descriptive methods.
44       *
45       * @since 1.4
46       */
47      public static final class Builder {
48  
49          /**
50           * Prints an Option to {@link System#out}.
51           */
52          static final Consumer<Option> DEPRECATED_HANDLER = o -> System.out.println(o.toDeprecatedString());
53  
54          /** The unrecognized options/arguments */
55          private final List<String> args = new LinkedList<>();
56  
57          /** The processed options */
58          private final List<Option> options = new ArrayList<>();
59  
60          /**
61           * Deprecated Option handler.
62           */
63          private Consumer<Option> deprecatedHandler = DEPRECATED_HANDLER;
64  
65          /**
66           * Adds left-over unrecognized option/argument.
67           *
68           * @param arg the unrecognized option/argument.
69           *
70           * @return this Builder instance for method chaining.
71           */
72          public Builder addArg(final String arg) {
73              if (arg != null) {
74                  args.add(arg);
75              }
76              return this;
77          }
78  
79          /**
80           * Adds an option to the command line. The values of the option are stored.
81           *
82           * @param opt the processed option.
83           *
84           * @return this Builder instance for method chaining.
85           */
86          public Builder addOption(final Option opt) {
87              if (opt != null) {
88                  options.add(opt);
89              }
90              return this;
91          }
92  
93          /**
94           * Creates the new instance.
95           *
96           * @return the new instance.
97           */
98          public CommandLine build() {
99              return new CommandLine(args, options, deprecatedHandler);
100         }
101 
102         /**
103          * Sets the deprecated option handler.
104          *
105          * @param deprecatedHandler the deprecated option handler.
106          * @return {@code this} instance.
107          * @since 1.7.0
108          */
109         public Builder setDeprecatedHandler(final Consumer<Option> deprecatedHandler) {
110             this.deprecatedHandler = deprecatedHandler;
111             return this;
112         }
113     }
114 
115     /** The serial version UID. */
116     private static final long serialVersionUID = 1L;
117 
118     /**
119      * Creates a new builder.
120      *
121      * @return a new builder.
122      * @since 1.7.0
123      */
124     public static Builder builder() {
125         return new Builder();
126     }
127 
128     /** The unrecognized options/arguments */
129     private final List<String> args;
130 
131     /** The processed options */
132     private final List<Option> options;
133 
134     /**
135      * The deprecated option handler.
136      * <p>
137      * If you want to serialize this field, use a serialization proxy.
138      * </p>
139      */
140     private final transient Consumer<Option> deprecatedHandler;
141 
142     /**
143      * Creates a command line.
144      */
145     protected CommandLine() {
146         this(new LinkedList<>(), new ArrayList<>(), Builder.DEPRECATED_HANDLER);
147     }
148 
149     /**
150      * Creates a command line.
151      */
152     private CommandLine(final List<String> args, final List<Option> options, final Consumer<Option> deprecatedHandler) {
153         this.args = Objects.requireNonNull(args, "args");
154         this.options = Objects.requireNonNull(options, "options");
155         this.deprecatedHandler = deprecatedHandler;
156     }
157 
158     /**
159      * Adds left-over unrecognized option/argument.
160      *
161      * @param arg the unrecognized option/argument.
162      */
163     protected void addArg(final String arg) {
164         if (arg != null) {
165             args.add(arg);
166         }
167     }
168 
169     /**
170      * Adds an option to the command line. The values of the option are stored.
171      *
172      * @param opt the processed option.
173      */
174     protected void addOption(final Option opt) {
175         if (opt != null) {
176             options.add(opt);
177         }
178     }
179 
180     private <T> T get(final Supplier<T> supplier) {
181         return supplier == null ? null : supplier.get();
182     }
183 
184     /**
185      * Gets any left-over non-recognized options and arguments
186      *
187      * @return remaining items passed in but not parsed as a {@code List}.
188      */
189     public List<String> getArgList() {
190         return args;
191     }
192 
193     /**
194      * Gets any left-over non-recognized options and arguments
195      *
196      * @return remaining items passed in but not parsed as an array.
197      */
198     public String[] getArgs() {
199         return args.toArray(Util.EMPTY_STRING_ARRAY);
200     }
201 
202     /**
203      * Gets the {@code Object} type of this {@code Option}.
204      *
205      * @deprecated due to System.err message. Instead use getParsedOptionValue(char)
206      * @param opt the name of the option.
207      * @return the type of opt.
208      */
209     @Deprecated
210     public Object getOptionObject(final char opt) {
211         return getOptionObject(String.valueOf(opt));
212     }
213 
214     /**
215      * Gets the {@code Object} type of this {@code Option}.
216      *
217      * @param opt the name of the option.
218      * @return the type of this {@code Option}.
219      * @deprecated due to System.err message. Instead use getParsedOptionValue(String)
220      */
221     @Deprecated
222     public Object getOptionObject(final String opt) {
223         try {
224             return getParsedOptionValue(opt);
225         } catch (final ParseException pe) {
226             System.err.println("Exception found converting " + opt + " to desired type: " + pe.getMessage());
227             return null;
228         }
229     }
230 
231     /**
232      * Gets the map of values associated to the option. This is convenient for options specifying Java properties like
233      * <code>-Dparam1=value1
234      * -Dparam2=value2</code>. All odd numbered values are property keys
235      * and even numbered values are property values.  If there are an odd number of values
236      * the last value is assumed to be a boolean flag and the value is "true".
237      *
238      * @param option name of the option.
239      * @return The Properties mapped by the option, never {@code null} even if the option doesn't exists.
240      * @since 1.5.0
241      */
242     public Properties getOptionProperties(final Option option) {
243         final Properties props = new Properties();
244         for (final Option processedOption : options) {
245             if (processedOption.equals(option)) {
246                 processPropertiesFromValues(props, processedOption.getValuesList());
247             }
248         }
249         return props;
250     }
251 
252     /**
253      * Gets the map of values associated to the option. This is convenient for options specifying Java properties like
254      * <code>-Dparam1=value1
255      * -Dparam2=value2</code>. The first argument of the option is the key, and the 2nd argument is the value. If the option
256      * has only one argument ({@code -Dfoo}) it is considered as a boolean flag and the value is {@code "true"}.
257      *
258      * @param opt name of the option.
259      * @return The Properties mapped by the option, never {@code null} even if the option doesn't exists.
260      * @since 1.2
261      */
262     public Properties getOptionProperties(final String opt) {
263         final Properties props = new Properties();
264         for (final Option option : options) {
265             if (opt.equals(option.getOpt()) || opt.equals(option.getLongOpt())) {
266                 processPropertiesFromValues(props, option.getValuesList());
267             }
268         }
269         return props;
270     }
271 
272     /**
273      * Gets an array of the processed {@link Option}s.
274      *
275      * @return an array of the processed {@link Option}s.
276      */
277     public Option[] getOptions() {
278         return options.toArray(Option.EMPTY_ARRAY);
279     }
280 
281     /**
282      * Gets the first argument, if any, of this option.
283      *
284      * @param opt the character name of the option.
285      * @return Value of the argument if option is set, and has an argument, otherwise null.
286      */
287     public String getOptionValue(final char opt) {
288         return getOptionValue(String.valueOf(opt));
289     }
290 
291     /**
292      * Gets the argument, if any, of an option.
293      *
294      * @param opt character name of the option
295      * @param defaultValue is the default value to be returned if the option is not specified.
296      * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}.
297      */
298     public String getOptionValue(final char opt, final String defaultValue) {
299         return getOptionValue(String.valueOf(opt), () -> defaultValue);
300     }
301 
302     /**
303      * Gets the argument, if any, of an option.
304      *
305      * @param opt character name of the option
306      * @param defaultValue is a supplier for the default value to be returned if the option is not specified.
307      * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}.
308      * @since 1.7.0
309      */
310     public String getOptionValue(final char opt, final Supplier<String> defaultValue) {
311         return getOptionValue(String.valueOf(opt), defaultValue);
312     }
313 
314     /**
315      * Gets the first argument, if any, of this option.
316      *
317      * @param option the option.
318      * @return Value of the argument if option is set, and has an argument, otherwise null.
319      * @since 1.5.0
320      */
321     public String getOptionValue(final Option option) {
322         final String[] values = getOptionValues(option);
323         return values == null ? null : values[0];
324     }
325 
326     /**
327      * Gets the first argument, if any, of an option.
328      *
329      * @param option the option.
330      * @param defaultValue is the default value to be returned if the option is not specified.
331      * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}.
332      * @since 1.5.0
333      */
334     public String getOptionValue(final Option option, final String defaultValue) {
335         return getOptionValue(option, () -> defaultValue);
336     }
337 
338     /**
339      * Gets the first argument, if any, of an option.
340      *
341      * @param option the option.
342      * @param defaultValue is a supplier for the default value to be returned if the option is not specified.
343      * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}.
344      * @since 1.7.0
345      */
346     public String getOptionValue(final Option option, final Supplier<String> defaultValue) {
347         final String answer = getOptionValue(option);
348         return answer != null ? answer : get(defaultValue);
349     }
350 
351     /**
352      * Gets the first argument, if any, of this option group.
353      *
354      * @param optionGroup the option group.
355      * @return Value of the argument if option group is selected, and has an argument, otherwise null.
356      * @since 1.9.0
357      */
358     public String getOptionValue(final OptionGroup optionGroup) {
359         final String[] values = getOptionValues(optionGroup);
360         return values == null ? null : values[0];
361     }
362 
363     /**
364      * Gets the first argument, if any, of an option group.
365      *
366      * @param optionGroup the option group.
367      * @param defaultValue is the default value to be returned if the option group is not selected.
368      * @return Value of the argument if option group is selected, and has an argument, otherwise {@code defaultValue}.
369      * @since 1.9.0
370      */
371     public String getOptionValue(final OptionGroup optionGroup, final String defaultValue) {
372         return getOptionValue(optionGroup, () -> defaultValue);
373     }
374 
375     /**
376      * Gets the first argument, if any, of an option group.
377      *
378      * @param optionGroup the option group..
379      * @param defaultValue is a supplier for the default value to be returned if the option group is not selected.
380      * @return Value of the argument if option group is selected, and has an argument, otherwise {@code defaultValue}.
381      * @since 1.9.0
382      */
383     public String getOptionValue(final OptionGroup optionGroup, final Supplier<String> defaultValue) {
384         final String answer = getOptionValue(optionGroup);
385         return answer != null ? answer : get(defaultValue);
386     }
387 
388 
389     /**
390      * Gets the first argument, if any, of this option.
391      *
392      * @param opt the name of the option.
393      * @return Value of the argument if option is set, and has an argument, otherwise null.
394      */
395     public String getOptionValue(final String opt) {
396         return getOptionValue(resolveOption(opt));
397     }
398 
399     /**
400      * Gets the first argument, if any, of an option.
401      *
402      * @param opt name of the option.
403      * @param defaultValue is the default value to be returned if the option is not specified.
404      * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}.
405      */
406     public String getOptionValue(final String opt, final String defaultValue) {
407         return getOptionValue(resolveOption(opt), () -> defaultValue);
408     }
409 
410     /**
411      * Gets the first argument, if any, of an option.
412      *
413      * @param opt name of the option.
414      * @param defaultValue is a supplier for the default value to be returned if the option is not specified.
415      * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}.
416      * @since 1.7.0
417      */
418     public String getOptionValue(final String opt, final Supplier<String> defaultValue) {
419         return getOptionValue(resolveOption(opt), defaultValue);
420     }
421 
422 
423     /**
424      * Gets the array of values, if any, of an option.
425      *
426      * @param opt character name of the option.
427      * @return Values of the argument if option is set, and has an argument, otherwise null.
428      */
429     public String[] getOptionValues(final char opt) {
430         return getOptionValues(String.valueOf(opt));
431     }
432 
433     /**
434      * Gets the array of values, if any, of an option.
435      *
436      * @param option the option.
437      * @return Values of the argument if option is set, and has an argument, otherwise null.
438      * @since 1.5.0
439      */
440     public String[] getOptionValues(final Option option) {
441         if (option == null) {
442             return null;
443         }
444         final List<String> values = new ArrayList<>();
445         for (final Option processedOption : options) {
446             if (processedOption.equals(option)) {
447                 if (option.isDeprecated()) {
448                     handleDeprecated(option);
449                 }
450                 values.addAll(processedOption.getValuesList());
451             }
452         }
453         return values.isEmpty() ? null : values.toArray(Util.EMPTY_STRING_ARRAY);
454     }
455 
456     /**
457      * Gets the array of values, if any, of an option group.
458      *
459      * @param optionGroup the option group.
460      * @return Values of the argument if option group is selected, and has an argument, otherwise null.
461      * @since 1.9.0
462      */
463     public String[] getOptionValues(final OptionGroup optionGroup) {
464         if (optionGroup == null || !optionGroup.isSelected()) {
465             return null;
466         }
467         return getOptionValues(optionGroup.getSelected());
468     }
469 
470     /**
471      * Gets the array of values, if any, of an option.
472      *
473      * @param opt string name of the option.
474      * @return Values of the argument if option is set, and has an argument, otherwise null.
475      */
476     public String[] getOptionValues(final String opt) {
477         return getOptionValues(resolveOption(opt));
478     }
479 
480     /**
481      * Gets a version of this {@code Option} converted to a particular type.
482      *
483      * @param opt the name of the option.
484      * @param <T> The return type for the method.
485      * @return the value parsed into a particular object.
486      * @throws ParseException if there are problems turning the option value into the desired type
487      * @see PatternOptionBuilder
488      * @since 1.5.0
489      */
490     public <T> T getParsedOptionValue(final char opt) throws ParseException {
491         return getParsedOptionValue(String.valueOf(opt));
492     }
493 
494     /**
495      * Gets a version of this {@code Option} converted to a particular type.
496      *
497      * @param opt the name of the option.
498      * @param defaultValue the default value to return if opt is not set.
499      * @param <T> The return type for the method.
500      * @return the value parsed into a particular object.
501      * @throws ParseException if there are problems turning the option value into the desired type
502      * @see PatternOptionBuilder
503      * @since 1.7.0
504      */
505     public <T> T getParsedOptionValue(final char opt, final Supplier<T> defaultValue) throws ParseException {
506         return getParsedOptionValue(String.valueOf(opt), defaultValue);
507     }
508 
509     /**
510      * Gets a version of this {@code Option} converted to a particular type.
511      *
512      * @param opt the name of the option.
513      * @param defaultValue the default value to return if opt is not set.
514      * @param <T> The return type for the method.
515      * @return the value parsed into a particular object.
516      * @throws ParseException if there are problems turning the option value into the desired type
517      * @see PatternOptionBuilder
518      * @since 1.7.0
519      */
520     public <T> T getParsedOptionValue(final char opt, final T defaultValue) throws ParseException {
521         return getParsedOptionValue(String.valueOf(opt), defaultValue);
522     }
523 
524     /**
525      * Gets a version of this {@code Option} converted to a particular type.
526      *
527      * @param option the option.
528      * @param <T> The return type for the method.
529      * @return the value parsed into a particular object.
530      * @throws ParseException if there are problems turning the option value into the desired type
531      * @see PatternOptionBuilder
532      * @since 1.5.0
533      */
534     public <T> T getParsedOptionValue(final Option option) throws ParseException {
535         return getParsedOptionValue(option, () -> null);
536     }
537 
538     /**
539      * Gets a version of this {@code Option} converted to a particular type.
540      *
541      * @param option the option.
542      * @param defaultValue the default value to return if opt is not set.
543      * @param <T> The return type for the method.
544      * @return the value parsed into a particular object.
545      * @throws ParseException if there are problems turning the option value into the desired type
546      * @see PatternOptionBuilder
547      * @since 1.7.0
548      */
549     @SuppressWarnings("unchecked")
550     public <T> T getParsedOptionValue(final Option option, final Supplier<T> defaultValue) throws ParseException {
551         if (option == null) {
552             return get(defaultValue);
553         }
554         final String res = getOptionValue(option);
555         try {
556             if (res == null) {
557                 return get(defaultValue);
558             }
559             return (T) option.getConverter().apply(res);
560         } catch (final Throwable e) {
561             throw ParseException.wrap(e);
562         }
563     }
564 
565     /**
566      * Gets a version of this {@code Option} converted to a particular type.
567      *
568      * @param option the option.
569      * @param defaultValue the default value to return if opt is not set.
570      * @param <T> The return type for the method.
571      * @return the value parsed into a particular object.
572      * @throws ParseException if there are problems turning the option value into the desired type
573      * @see PatternOptionBuilder
574      * @since 1.7.0
575      */
576     public <T> T getParsedOptionValue(final Option option, final T defaultValue) throws ParseException {
577         return getParsedOptionValue(option, () -> defaultValue);
578     }
579 
580     /**
581      * Gets a version of this {@code OptionGroup} converted to a particular type.
582      *
583      * @param optionGroup the option group.
584      * @param <T> The return type for the method.
585      * @return the value parsed into a particular object.
586      * @throws ParseException if there are problems turning the selected option value into the desired type
587      * @see PatternOptionBuilder
588      * @since 1.9.0
589      */
590     public <T> T getParsedOptionValue(final OptionGroup optionGroup) throws ParseException {
591         return getParsedOptionValue(optionGroup, () -> null);
592     }
593 
594     /**
595      * Gets a version of this {@code OptionGroup} converted to a particular type.
596      *
597      * @param optionGroup the option group.
598      * @param defaultValue the default value to return if opt is not set.
599      * @param <T> The return type for the method.
600      * @return the value parsed into a particular object.
601      * @throws ParseException if there are problems turning the selected option value into the desired type
602      * @see PatternOptionBuilder
603      * @since 1.9.0
604      */
605     public <T> T getParsedOptionValue(final OptionGroup optionGroup, final Supplier<T> defaultValue) throws ParseException {
606         if (optionGroup == null || !optionGroup.isSelected()) {
607             return get(defaultValue);
608         }
609         return getParsedOptionValue(optionGroup.getSelected(), defaultValue);
610     }
611 
612     /**
613      * Gets a version of this {@code OptionGroup} converted to a particular type.
614      *
615      * @param optionGroup the option group.
616      * @param defaultValue the default value to return if an option is not selected.
617      * @param <T> The return type for the method.
618      * @return the value parsed into a particular object.
619      * @throws ParseException if there are problems turning the option value into the desired type
620      * @see PatternOptionBuilder
621      * @since 1.9.0
622      */
623     public <T> T getParsedOptionValue(final OptionGroup optionGroup, final T defaultValue) throws ParseException {
624         return getParsedOptionValue(optionGroup, () -> defaultValue);
625     }
626 
627     /**
628      * Gets a version of this {@code Option} converted to a particular type.
629      *
630      * @param opt the name of the option.
631      * @param <T> The return type for the method.
632      * @return the value parsed into a particular object.
633      * @throws ParseException if there are problems turning the option value into the desired type
634      * @see PatternOptionBuilder
635      * @since 1.2
636      */
637     public <T> T getParsedOptionValue(final String opt) throws ParseException {
638         return getParsedOptionValue(resolveOption(opt));
639     }
640 
641     /**
642      * Gets a version of this {@code Option} converted to a particular type.
643      *
644      * @param opt the name of the option.
645      * @param defaultValue the default value to return if opt is not set.
646      * @param <T> The return type for the method.
647      * @return the value parsed into a particular object.
648      * @throws ParseException if there are problems turning the option value into the desired type
649      * @see PatternOptionBuilder
650      * @since 1.7.0
651      */
652     public <T> T getParsedOptionValue(final String opt, final Supplier<T> defaultValue) throws ParseException {
653         return getParsedOptionValue(resolveOption(opt), defaultValue);
654     }
655 
656     /**
657      * Gets a version of this {@code Option} converted to a particular type.
658      *
659      * @param opt the name of the option.
660      * @param defaultValue the default value to return if opt is not set.
661      * @param <T> The return type for the method.
662      * @return the value parsed into a particular object.
663      * @throws ParseException if there are problems turning the option value into the desired type
664      * @see PatternOptionBuilder
665      * @since 1.7.0
666      */
667     public <T> T getParsedOptionValue(final String opt, final T defaultValue) throws ParseException {
668         return getParsedOptionValue(resolveOption(opt), defaultValue);
669     }
670 
671     /**
672      * Handles deprecated options.
673      *
674      * @param option a deprecated option.
675      */
676     private void handleDeprecated(final Option option) {
677         if (deprecatedHandler != null) {
678             deprecatedHandler.accept(option);
679         }
680     }
681 
682     /**
683      * jkeyes - commented out until it is implemented properly
684      * <p>
685      * Dump state, suitable for debugging.
686      * </p>
687      *
688      * @return Stringified form of this object.
689      */
690 
691     /*
692      * public String toString() { StringBuilder buf = new StringBuilder();
693      *
694      * buf.append("[ CommandLine: [ options: "); buf.append(options.toString()); buf.append(" ] [ args: ");
695      * buf.append(args.toString()); buf.append(" ] ]");
696      *
697      * return buf.toString(); }
698      */
699 
700     /**
701      * Tests to see if an option has been set.
702      *
703      * @param opt character name of the option.
704      * @return true if set, false if not.
705      */
706     public boolean hasOption(final char opt) {
707         return hasOption(String.valueOf(opt));
708     }
709 
710     /**
711      * Tests to see if an option has been set.
712      *
713      * @param opt the option to check.
714      * @return true if set, false if not.
715      * @since 1.5.0
716      */
717     public boolean hasOption(final Option opt) {
718         final boolean result = options.contains(opt);
719         if (result && opt.isDeprecated()) {
720             handleDeprecated(opt);
721         }
722         return result;
723     }
724 
725     /**
726      * Tests to see if an option has been set.
727      *
728      * @param optionGroup the option group to check.
729      * @return true if set, false if not.
730      * @since 1.9.0
731      */
732     public boolean hasOption(final OptionGroup optionGroup) {
733         if (optionGroup == null || !optionGroup.isSelected()) {
734             return false;
735         }
736         return hasOption(optionGroup.getSelected());
737     }
738 
739     /**
740      * Tests to see if an option has been set.
741      *
742      * @param opt Short name of the option.
743      * @return true if set, false if not.
744      */
745     public boolean hasOption(final String opt) {
746         return hasOption(resolveOption(opt));
747     }
748 
749     /**
750      * Returns an iterator over the Option members of CommandLine.
751      *
752      * @return an {@code Iterator} over the processed {@link Option} members of this {@link CommandLine}.
753      */
754     public Iterator<Option> iterator() {
755         return options.iterator();
756     }
757 
758     /**
759      * Parses a list of values as properties.  All odd numbered values are property keys
760      * and even numbered values are property values.  If there are an odd number of values
761      * the last value is assumed to be a boolean with a value of "true".
762      * @param props the properties to update.
763      * @param values the list of values to parse.
764      */
765     private void processPropertiesFromValues(final Properties props, final List<String> values) {
766         for (int i = 0; i < values.size(); i += 2) {
767             if (i + 1 < values.size()) {
768                 props.put(values.get(i), values.get(i + 1));
769             } else {
770                 props.put(values.get(i), "true");
771             }
772         }
773     }
774 
775     /**
776      * Retrieves the option object given the long or short option as a String
777      *
778      * @param opt short or long name of the option, may be null.
779      * @return Canonicalized option.
780      */
781     private Option resolveOption(final String opt) {
782         final String actual = Util.stripLeadingHyphens(opt);
783         if (actual != null) {
784             for (final Option option : options) {
785                 if (actual.equals(option.getOpt()) || actual.equals(option.getLongOpt())) {
786                     return option;
787                 }
788             }
789         }
790         return null;
791     }
792 }