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.List;
23  
24  /**
25   * Describes a single command-line option.  It maintains
26   * information regarding the short-name of the option, the long-name,
27   * if any exists, a flag indicating if an argument is required for
28   * this option, and a self-documenting description of the option.
29   * <p>
30   * An Option is not created independently, but is created through
31   * an instance of {@link Options}. An Option is required to have
32   * at least a short or a long-name.
33   * <p>
34   * <b>Note:</b> once an {@link Option} has been added to an instance
35   * of {@link Options}, it's required flag may not be changed anymore.
36   *
37   * @see org.apache.commons.cli.Options
38   * @see org.apache.commons.cli.CommandLine
39   *
40   * @version $Id$
41   */
42  public class Option implements Cloneable, Serializable
43  {
44      /** constant that specifies the number of argument values has not been specified */
45      public static final int UNINITIALIZED = -1;
46  
47      /** constant that specifies the number of argument values is infinite */
48      public static final int UNLIMITED_VALUES = -2;
49  
50      /** The serial version UID. */
51      private static final long serialVersionUID = 1L;
52  
53      /** the name of the option */
54      private final String opt;
55  
56      /** the long representation of the option */
57      private String longOpt;
58  
59      /** the name of the argument for this option */
60      private String argName;
61  
62      /** description of the option */
63      private String description;
64  
65      /** specifies whether this option is required to be present */
66      private boolean required;
67  
68      /** specifies whether the argument value of this Option is optional */
69      private boolean optionalArg;
70  
71      /** the number of argument values this option can have */
72      private int numberOfArgs = UNINITIALIZED;
73  
74      /** the type of this Option */
75      private Class<?> type = String.class;
76  
77      /** the list of argument values **/
78      private List<String> values = new ArrayList<String>();
79  
80      /** the character that is the value separator */
81      private char valuesep;
82  
83      /**
84       * Private constructor used by the nested Builder class.
85       * 
86       * @param builder builder used to create this option
87       */
88      private Option(final Builder builder)
89      {
90          this.argName = builder.argName;
91          this.description = builder.description;
92          this.longOpt = builder.longOpt;
93          this.numberOfArgs = builder.numberOfArgs;
94          this.opt = builder.opt;
95          this.optionalArg = builder.optionalArg;
96          this.required = builder.required;
97          this.type = builder.type;
98          this.valuesep = builder.valuesep;
99      }
100     
101     /**
102      * Creates an Option using the specified parameters.
103      * The option does not take an argument.
104      *
105      * @param opt short representation of the option
106      * @param description describes the function of the option
107      *
108      * @throws IllegalArgumentException if there are any non valid
109      * Option characters in <code>opt</code>.
110      */
111     public Option(final String opt, final String description) throws IllegalArgumentException
112     {
113         this(opt, null, false, description);
114     }
115 
116     /**
117      * Creates an Option using the specified parameters.
118      *
119      * @param opt short representation of the option
120      * @param hasArg specifies whether the Option takes an argument or not
121      * @param description describes the function of the option
122      *
123      * @throws IllegalArgumentException if there are any non valid
124      * Option characters in <code>opt</code>.
125      */
126     public Option(final String opt, final boolean hasArg, final String description) throws IllegalArgumentException
127     {
128         this(opt, null, hasArg, description);
129     }
130 
131     /**
132      * Creates an Option using the specified parameters.
133      *
134      * @param opt short representation of the option
135      * @param longOpt the long representation of the option
136      * @param hasArg specifies whether the Option takes an argument or not
137      * @param description describes the function of the option
138      *
139      * @throws IllegalArgumentException if there are any non valid
140      * Option characters in <code>opt</code>.
141      */
142     public Option(final String opt, final String longOpt, final boolean hasArg, final String description)
143            throws IllegalArgumentException
144     {
145         // ensure that the option is valid
146         OptionValidator.validateOption(opt);
147 
148         this.opt = opt;
149         this.longOpt = longOpt;
150 
151         // if hasArg is set then the number of arguments is 1
152         if (hasArg)
153         {
154             this.numberOfArgs = 1;
155         }
156 
157         this.description = description;
158     }
159 
160     /**
161      * Returns the id of this Option.  This is only set when the
162      * Option shortOpt is a single character.  This is used for switch
163      * statements.
164      *
165      * @return the id of this Option
166      */
167     public int getId()
168     {
169         return getKey().charAt(0);
170     }
171 
172     /**
173      * Returns the 'unique' Option identifier.
174      * 
175      * @return the 'unique' Option identifier
176      */
177     String getKey()
178     {
179         // if 'opt' is null, then it is a 'long' option
180         return (opt == null) ? longOpt : opt;
181     }
182 
183     /** 
184      * Retrieve the name of this Option.
185      *
186      * It is this String which can be used with
187      * {@link CommandLine#hasOption(String opt)} and
188      * {@link CommandLine#getOptionValue(String opt)} to check
189      * for existence and argument.
190      *
191      * @return The name of this option
192      */
193     public String getOpt()
194     {
195         return opt;
196     }
197 
198     /**
199      * Retrieve the type of this Option.
200      * 
201      * @return The type of this option
202      */
203     public Object getType()
204     {
205         return type;
206     }
207 
208     /**
209      * Sets the type of this Option.
210      * <p>
211      * <b>Note:</b> this method is kept for binary compatibility and the
212      * input type is supposed to be a {@link Class} object. 
213      *
214      * @param type the type of this Option
215      * @deprecated since 1.3, use {@link #setType(Class)} instead
216      */
217     @Deprecated
218     public void setType(final Object type)
219     {
220         setType((Class<?>) type);
221     }
222 
223     /**
224      * Sets the type of this Option.
225      *
226      * @param type the type of this Option
227      * @since 1.3
228      */
229     public void setType(final Class<?> type)
230     {
231         this.type = type;
232     }
233 
234     /** 
235      * Retrieve the long name of this Option.
236      *
237      * @return Long name of this option, or null, if there is no long name
238      */
239     public String getLongOpt()
240     {
241         return longOpt;
242     }
243 
244     /**
245      * Sets the long name of this Option.
246      *
247      * @param longOpt the long name of this Option
248      */
249     public void setLongOpt(final String longOpt)
250     {
251         this.longOpt = longOpt;
252     }
253 
254     /**
255      * Sets whether this Option can have an optional argument.
256      *
257      * @param optionalArg specifies whether the Option can have
258      * an optional argument.
259      */
260     public void setOptionalArg(final boolean optionalArg)
261     {
262         this.optionalArg = optionalArg;
263     }
264 
265     /**
266      * @return whether this Option can have an optional argument
267      */
268     public boolean hasOptionalArg()
269     {
270         return optionalArg;
271     }
272 
273     /** 
274      * Query to see if this Option has a long name
275      *
276      * @return boolean flag indicating existence of a long name
277      */
278     public boolean hasLongOpt()
279     {
280         return longOpt != null;
281     }
282 
283     /** 
284      * Query to see if this Option requires an argument
285      *
286      * @return boolean flag indicating if an argument is required
287      */
288     public boolean hasArg()
289     {
290         return numberOfArgs > 0 || numberOfArgs == UNLIMITED_VALUES;
291     }
292 
293     /** 
294      * Retrieve the self-documenting description of this Option
295      *
296      * @return The string description of this option
297      */
298     public String getDescription()
299     {
300         return description;
301     }
302 
303     /**
304      * Sets the self-documenting description of this Option
305      *
306      * @param description The description of this option
307      * @since 1.1
308      */
309     public void setDescription(final String description)
310     {
311         this.description = description;
312     }
313 
314     /** 
315      * Query to see if this Option is mandatory
316      *
317      * @return boolean flag indicating whether this Option is mandatory
318      */
319     public boolean isRequired()
320     {
321         return required;
322     }
323 
324     /**
325      * Sets whether this Option is mandatory.
326      *
327      * @param required specifies whether this Option is mandatory
328      */
329     public void setRequired(final boolean required)
330     {
331         this.required = required;
332     }
333 
334     /**
335      * Sets the display name for the argument value.
336      *
337      * @param argName the display name for the argument value.
338      */
339     public void setArgName(final String argName)
340     {
341         this.argName = argName;
342     }
343 
344     /**
345      * Gets the display name for the argument value.
346      *
347      * @return the display name for the argument value.
348      */
349     public String getArgName()
350     {
351         return argName;
352     }
353 
354     /**
355      * Returns whether the display name for the argument value has been set.
356      *
357      * @return if the display name for the argument value has been set.
358      */
359     public boolean hasArgName()
360     {
361         return argName != null && argName.length() > 0;
362     }
363 
364     /** 
365      * Query to see if this Option can take many values.
366      *
367      * @return boolean flag indicating if multiple values are allowed
368      */
369     public boolean hasArgs()
370     {
371         return numberOfArgs > 1 || numberOfArgs == UNLIMITED_VALUES;
372     }
373 
374     /** 
375      * Sets the number of argument values this Option can take.
376      *
377      * @param num the number of argument values
378      */
379     public void setArgs(final int num)
380     {
381         this.numberOfArgs = num;
382     }
383 
384     /**
385      * Sets the value separator.  For example if the argument value
386      * was a Java property, the value separator would be '='.
387      *
388      * @param sep The value separator.
389      */
390     public void setValueSeparator(final char sep)
391     {
392         this.valuesep = sep;
393     }
394 
395     /**
396      * Returns the value separator character.
397      *
398      * @return the value separator character.
399      */
400     public char getValueSeparator()
401     {
402         return valuesep;
403     }
404 
405     /**
406      * Return whether this Option has specified a value separator.
407      * 
408      * @return whether this Option has specified a value separator.
409      * @since 1.1
410      */
411     public boolean hasValueSeparator()
412     {
413         return valuesep > 0;
414     }
415 
416     /** 
417      * Returns the number of argument values this Option can take.
418      * 
419      * <p>
420      * A value equal to the constant {@link #UNINITIALIZED} (= -1) indicates
421      * the number of arguments has not been specified.
422      * A value equal to the constant {@link #UNLIMITED_VALUES} (= -2) indicates
423      * that this options takes an unlimited amount of values.
424      * </p>
425      *
426      * @return num the number of argument values
427      * @see #UNINITIALIZED
428      * @see #UNLIMITED_VALUES
429      */
430     public int getArgs()
431     {
432         return numberOfArgs;
433     }
434 
435     /**
436      * Adds the specified value to this Option.
437      * 
438      * @param value is a/the value of this Option
439      */
440     void addValueForProcessing(final String value)
441     {
442         if (numberOfArgs == UNINITIALIZED)
443         {
444             throw new RuntimeException("NO_ARGS_ALLOWED");
445         }
446         processValue(value);
447     }
448 
449     /**
450      * Processes the value.  If this Option has a value separator
451      * the value will have to be parsed into individual tokens.  When
452      * n-1 tokens have been processed and there are more value separators
453      * in the value, parsing is ceased and the remaining characters are
454      * added as a single token.
455      *
456      * @param value The String to be processed.
457      *
458      * @since 1.0.1
459      */
460     private void processValue(String value)
461     {
462         // this Option has a separator character
463         if (hasValueSeparator())
464         {
465             // get the separator character
466             final char sep = getValueSeparator();
467 
468             // store the index for the value separator
469             int index = value.indexOf(sep);
470 
471             // while there are more value separators
472             while (index != -1)
473             {
474                 // next value to be added 
475                 if (values.size() == numberOfArgs - 1)
476                 {
477                     break;
478                 }
479 
480                 // store
481                 add(value.substring(0, index));
482 
483                 // parse
484                 value = value.substring(index + 1);
485 
486                 // get new index
487                 index = value.indexOf(sep);
488             }
489         }
490 
491         // store the actual value or the last value that has been parsed
492         add(value);
493     }
494 
495     /**
496      * Add the value to this Option.  If the number of arguments
497      * is greater than zero and there is enough space in the list then
498      * add the value.  Otherwise, throw a runtime exception.
499      *
500      * @param value The value to be added to this Option
501      *
502      * @since 1.0.1
503      */
504     private void add(final String value)
505     {
506         if (!acceptsArg())
507         {
508             throw new RuntimeException("Cannot add value, list full.");
509         }
510 
511         // store value
512         values.add(value);
513     }
514 
515     /**
516      * Returns the specified value of this Option or 
517      * <code>null</code> if there is no value.
518      *
519      * @return the value/first value of this Option or 
520      * <code>null</code> if there is no value.
521      */
522     public String getValue()
523     {
524         return hasNoValues() ? null : values.get(0);
525     }
526 
527     /**
528      * Returns the specified value of this Option or 
529      * <code>null</code> if there is no value.
530      *
531      * @param index The index of the value to be returned.
532      *
533      * @return the specified value of this Option or 
534      * <code>null</code> if there is no value.
535      *
536      * @throws IndexOutOfBoundsException if index is less than 1
537      * or greater than the number of the values for this Option.
538      */
539     public String getValue(final int index) throws IndexOutOfBoundsException
540     {
541         return hasNoValues() ? null : values.get(index);
542     }
543 
544     /**
545      * Returns the value/first value of this Option or the 
546      * <code>defaultValue</code> if there is no value.
547      *
548      * @param defaultValue The value to be returned if there
549      * is no value.
550      *
551      * @return the value/first value of this Option or the 
552      * <code>defaultValue</code> if there are no values.
553      */
554     public String getValue(final String defaultValue)
555     {
556         final String value = getValue();
557 
558         return (value != null) ? value : defaultValue;
559     }
560 
561     /**
562      * Return the values of this Option as a String array 
563      * or null if there are no values
564      *
565      * @return the values of this Option as a String array 
566      * or null if there are no values
567      */
568     public String[] getValues()
569     {
570         return hasNoValues() ? null : values.toArray(new String[values.size()]);
571     }
572 
573     /**
574      * @return the values of this Option as a List
575      * or null if there are no values
576      */
577     public List<String> getValuesList()
578     {
579         return values;
580     }
581 
582     /** 
583      * Dump state, suitable for debugging.
584      *
585      * @return Stringified form of this object
586      */
587     @Override
588     public String toString()
589     {
590         final StringBuilder buf = new StringBuilder().append("[ option: ");
591 
592         buf.append(opt);
593 
594         if (longOpt != null)
595         {
596             buf.append(" ").append(longOpt);
597         }
598 
599         buf.append(" ");
600 
601         if (hasArgs())
602         {
603             buf.append("[ARG...]");
604         }
605         else if (hasArg())
606         {
607             buf.append(" [ARG]");
608         }
609 
610         buf.append(" :: ").append(description);
611 
612         if (type != null)
613         {
614             buf.append(" :: ").append(type);
615         }
616 
617         buf.append(" ]");
618 
619         return buf.toString();
620     }
621 
622     /**
623      * Returns whether this Option has any values.
624      *
625      * @return whether this Option has any values.
626      */
627     private boolean hasNoValues()
628     {
629         return values.isEmpty();
630     }
631 
632     @Override
633     public boolean equals(final Object o)
634     {
635         if (this == o)
636         {
637             return true;
638         }
639         if (o == null || getClass() != o.getClass())
640         {
641             return false;
642         }
643 
644         final Option option = (Option) o;
645 
646         if (opt != null ? !opt.equals(option.opt) : option.opt != null)
647         {
648             return false;
649         }
650         if (longOpt != null ? !longOpt.equals(option.longOpt) : option.longOpt != null)
651         {
652             return false;
653         }
654 
655         return true;
656     }
657 
658     @Override
659     public int hashCode()
660     {
661         int result;
662         result = opt != null ? opt.hashCode() : 0;
663         result = 31 * result + (longOpt != null ? longOpt.hashCode() : 0);
664         return result;
665     }
666 
667     /**
668      * A rather odd clone method - due to incorrect code in 1.0 it is public 
669      * and in 1.1 rather than throwing a CloneNotSupportedException it throws 
670      * a RuntimeException so as to maintain backwards compat at the API level. 
671      *
672      * After calling this method, it is very likely you will want to call 
673      * clearValues(). 
674      *
675      * @return a clone of this Option instance
676      * @throws RuntimeException if a {@link CloneNotSupportedException} has been thrown
677      * by {@code super.clone()}
678      */
679     @Override
680     public Object clone()
681     {
682         try
683         {
684             final Option option = (Option) super.clone();
685             option.values = new ArrayList<String>(values);
686             return option;
687         }
688         catch (final CloneNotSupportedException cnse)
689         {
690             throw new RuntimeException("A CloneNotSupportedException was thrown: " + cnse.getMessage());
691         }
692     }
693 
694     /**
695      * Clear the Option values. After a parse is complete, these are left with
696      * data in them and they need clearing if another parse is done.
697      *
698      * See: <a href="https://issues.apache.org/jira/browse/CLI-71">CLI-71</a>
699      */
700     void clearValues()
701     {
702         values.clear();
703     }
704 
705     /**
706      * This method is not intended to be used. It was a piece of internal 
707      * API that was made public in 1.0. It currently throws an UnsupportedOperationException.
708      *
709      * @param value the value to add
710      * @return always throws an {@link UnsupportedOperationException}
711      * @throws UnsupportedOperationException always
712      * @deprecated
713      */
714     @Deprecated
715     public boolean addValue(final String value)
716     {
717         throw new UnsupportedOperationException("The addValue method is not intended for client use. "
718                 + "Subclasses should use the addValueForProcessing method instead. ");
719     }
720 
721     /**
722      * Tells if the option can accept more arguments.
723      * 
724      * @return false if the maximum number of arguments is reached
725      * @since 1.3
726      */
727     boolean acceptsArg()
728     {
729         return (hasArg() || hasArgs() || hasOptionalArg()) && (numberOfArgs <= 0 || values.size() < numberOfArgs);
730     }
731 
732     /**
733      * Tells if the option requires more arguments to be valid.
734      * 
735      * @return false if the option doesn't require more arguments
736      * @since 1.3
737      */
738     boolean requiresArg()
739     {
740         if (optionalArg)
741         {
742             return false;
743         }
744         if (numberOfArgs == UNLIMITED_VALUES)
745         {
746             return values.isEmpty();
747         }
748         return acceptsArg();
749     }
750     
751     /**
752      * Returns a {@link Builder} to create an {@link Option} using descriptive
753      * methods.  
754      * 
755      * @return a new {@link Builder} instance
756      * @since 1.3
757      */
758     public static Builder builder()
759     {
760         return builder(null);
761     }
762     
763     /**
764      * Returns a {@link Builder} to create an {@link Option} using descriptive
765      * methods.  
766      *
767      * @param opt short representation of the option
768      * @return a new {@link Builder} instance
769      * @throws IllegalArgumentException if there are any non valid Option characters in {@code opt}
770      * @since 1.3
771      */
772     public static Builder builder(final String opt)
773     {
774         return new Builder(opt);
775     }
776     
777     /**
778      * A nested builder class to create <code>Option</code> instances
779      * using descriptive methods.
780      * <p>
781      * Example usage:
782      * <pre>
783      * Option option = Option.builder("a")
784      *     .required(true)
785      *     .longOpt("arg-name")
786      *     .build();
787      * </pre>
788      * 
789      * @since 1.3
790      */
791     public static final class Builder 
792     {
793         /** the name of the option */
794         private final String opt;
795 
796         /** description of the option */
797         private String description;
798 
799         /** the long representation of the option */
800         private String longOpt;
801 
802         /** the name of the argument for this option */
803         private String argName;
804 
805         /** specifies whether this option is required to be present */
806         private boolean required;
807 
808         /** specifies whether the argument value of this Option is optional */
809         private boolean optionalArg;
810 
811         /** the number of argument values this option can have */
812         private int numberOfArgs = UNINITIALIZED;
813 
814         /** the type of this Option */
815         private Class<?> type = String.class;
816 
817         /** the character that is the value separator */
818         private char valuesep;
819 
820         /**
821          * Constructs a new <code>Builder</code> with the minimum
822          * required parameters for an <code>Option</code> instance.
823          * 
824          * @param opt short representation of the option
825          * @throws IllegalArgumentException if there are any non valid Option characters in {@code opt}
826          */
827         private Builder(final String opt) throws IllegalArgumentException
828         {
829             OptionValidator.validateOption(opt);
830             this.opt = opt;
831         }
832         
833         /**
834          * Sets the display name for the argument value.
835          *
836          * @param argName the display name for the argument value.
837          * @return this builder, to allow method chaining
838          */
839         public Builder argName(final String argName)
840         {
841             this.argName = argName;
842             return this;
843         }
844 
845         /**
846          * Sets the description for this option.
847          *
848          * @param description the description of the option.
849          * @return this builder, to allow method chaining
850          */
851         public Builder desc(final String description)
852         {
853             this.description = description;
854             return this;
855         }
856 
857         /**
858          * Sets the long name of the Option.
859          *
860          * @param longOpt the long name of the Option
861          * @return this builder, to allow method chaining
862          */        
863         public Builder longOpt(final String longOpt)
864         {
865             this.longOpt = longOpt;
866             return this;
867         }
868         
869         /** 
870          * Sets the number of argument values the Option can take.
871          *
872          * @param numberOfArgs the number of argument values
873          * @return this builder, to allow method chaining
874          */        
875         public Builder numberOfArgs(final int numberOfArgs)
876         {
877             this.numberOfArgs = numberOfArgs;
878             return this;
879         }
880         
881         /**
882          * Sets whether the Option can have an optional argument.
883          *
884          * @param isOptional specifies whether the Option can have
885          * an optional argument.
886          * @return this builder, to allow method chaining
887          */
888         public Builder optionalArg(final boolean isOptional)
889         {
890             this.optionalArg = isOptional;
891             return this;
892         }
893         
894         /**
895          * Marks this Option as required.
896          *
897          * @return this builder, to allow method chaining
898          */
899         public Builder required()
900         {
901             return required(true);
902         }
903 
904         /**
905          * Sets whether the Option is mandatory.
906          *
907          * @param required specifies whether the Option is mandatory
908          * @return this builder, to allow method chaining
909          */
910         public Builder required(final boolean required)
911         {
912             this.required = required;
913             return this;
914         }
915         
916         /**
917          * Sets the type of the Option.
918          *
919          * @param type the type of the Option
920          * @return this builder, to allow method chaining
921          */
922         public Builder type(final Class<?> type)
923         {
924             this.type = type;
925             return this;
926         }
927 
928         /**
929          * The Option will use '=' as a means to separate argument value.
930          *
931          * @return this builder, to allow method chaining
932          */
933         public Builder valueSeparator()
934         {
935             return valueSeparator('=');
936         }
937 
938         /**
939          * The Option will use <code>sep</code> as a means to
940          * separate argument values.
941          * <p>
942          * <b>Example:</b>
943          * <pre>
944          * Option opt = Option.builder("D").hasArgs()
945          *                                 .valueSeparator('=')
946          *                                 .build();
947          * Options options = new Options();
948          * options.addOption(opt);
949          * String[] args = {"-Dkey=value"};
950          * CommandLineParser parser = new DefaultParser();
951          * CommandLine line = parser.parse(options, args);
952          * String propertyName = line.getOptionValues("D")[0];  // will be "key"
953          * String propertyValue = line.getOptionValues("D")[1]; // will be "value"
954          * </pre>
955          *
956          * @param sep The value separator.
957          * @return this builder, to allow method chaining
958          */
959         public Builder valueSeparator(final char sep)
960         {
961             valuesep = sep;
962             return this;
963         }
964         
965         /**
966          * Indicates that the Option will require an argument.
967          * 
968          * @return this builder, to allow method chaining
969          */
970         public Builder hasArg()
971         {
972             return hasArg(true);
973         }
974 
975         /**
976          * Indicates if the Option has an argument or not.
977          * 
978          * @param hasArg specifies whether the Option takes an argument or not
979          * @return this builder, to allow method chaining
980          */
981         public Builder hasArg(final boolean hasArg)
982         {
983             // set to UNINITIALIZED when no arg is specified to be compatible with OptionBuilder
984             numberOfArgs = hasArg ? 1 : Option.UNINITIALIZED;
985             return this;
986         }
987 
988         /**
989          * Indicates that the Option can have unlimited argument values.
990          * 
991          * @return this builder, to allow method chaining
992          */
993         public Builder hasArgs()
994         {
995             numberOfArgs = Option.UNLIMITED_VALUES;
996             return this;
997         }
998 
999         /**
1000          * Constructs an Option with the values declared by this {@link Builder}.
1001          * 
1002          * @return the new {@link Option}
1003          * @throws IllegalArgumentException if neither {@code opt} or {@code longOpt} has been set
1004          */
1005         public Option build()
1006         {
1007             if (opt == null && longOpt == null)
1008             {
1009                 throw new IllegalArgumentException("Either opt or longOpt must be specified");
1010             }
1011             return new Option(this);
1012         }
1013     }
1014 }