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: Option.java 1756753 2016-08-18 10:18:43Z britter $
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(String opt, 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(String opt, boolean hasArg, 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(String opt, String longOpt, boolean hasArg, 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(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(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(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(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(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(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(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(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(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(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             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(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(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(String defaultValue)
555     {
556         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         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(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         Option option = (Option) o;
645 
646 
647         if (opt != null ? !opt.equals(option.opt) : option.opt != null)
648         {
649             return false;
650         }
651         if (longOpt != null ? !longOpt.equals(option.longOpt) : option.longOpt != null)
652         {
653             return false;
654         }
655 
656         return true;
657     }
658 
659     @Override
660     public int hashCode()
661     {
662         int result;
663         result = opt != null ? opt.hashCode() : 0;
664         result = 31 * result + (longOpt != null ? longOpt.hashCode() : 0);
665         return result;
666     }
667 
668     /**
669      * A rather odd clone method - due to incorrect code in 1.0 it is public 
670      * and in 1.1 rather than throwing a CloneNotSupportedException it throws 
671      * a RuntimeException so as to maintain backwards compat at the API level. 
672      *
673      * After calling this method, it is very likely you will want to call 
674      * clearValues(). 
675      *
676      * @return a clone of this Option instance
677      * @throws RuntimeException if a {@link CloneNotSupportedException} has been thrown
678      * by {@code super.clone()}
679      */
680     @Override
681     public Object clone()
682     {
683         try
684         {
685             Option option = (Option) super.clone();
686             option.values = new ArrayList<String>(values);
687             return option;
688         }
689         catch (CloneNotSupportedException cnse)
690         {
691             throw new RuntimeException("A CloneNotSupportedException was thrown: " + cnse.getMessage());
692         }
693     }
694 
695     /**
696      * Clear the Option values. After a parse is complete, these are left with
697      * data in them and they need clearing if another parse is done.
698      *
699      * See: <a href="https://issues.apache.org/jira/browse/CLI-71">CLI-71</a>
700      */
701     void clearValues()
702     {
703         values.clear();
704     }
705 
706     /**
707      * This method is not intended to be used. It was a piece of internal 
708      * API that was made public in 1.0. It currently throws an UnsupportedOperationException.
709      *
710      * @param value the value to add
711      * @return always throws an {@link UnsupportedOperationException}
712      * @throws UnsupportedOperationException always
713      * @deprecated
714      */
715     @Deprecated
716     public boolean addValue(String value)
717     {
718         throw new UnsupportedOperationException("The addValue method is not intended for client use. "
719                 + "Subclasses should use the addValueForProcessing method instead. ");
720     }
721 
722     /**
723      * Tells if the option can accept more arguments.
724      * 
725      * @return false if the maximum number of arguments is reached
726      * @since 1.3
727      */
728     boolean acceptsArg()
729     {
730         return (hasArg() || hasArgs() || hasOptionalArg()) && (numberOfArgs <= 0 || values.size() < numberOfArgs);
731     }
732 
733     /**
734      * Tells if the option requires more arguments to be valid.
735      * 
736      * @return false if the option doesn't require more arguments
737      * @since 1.3
738      */
739     boolean requiresArg()
740     {
741         if (optionalArg)
742         {
743             return false;
744         }
745         if (numberOfArgs == UNLIMITED_VALUES)
746         {
747             return values.isEmpty();
748         }
749         return acceptsArg();
750     }
751     
752     /**
753      * Returns a {@link Builder} to create an {@link Option} using descriptive
754      * methods.  
755      * 
756      * @return a new {@link Builder} instance
757      * @since 1.3
758      */
759     public static Builder builder()
760     {
761         return builder(null);
762     }
763     
764     /**
765      * Returns a {@link Builder} to create an {@link Option} using descriptive
766      * methods.  
767      *
768      * @param opt short representation of the option
769      * @return a new {@link Builder} instance
770      * @throws IllegalArgumentException if there are any non valid Option characters in {@code opt}
771      * @since 1.3
772      */
773     public static Builder builder(final String opt)
774     {
775         return new Builder(opt);
776     }
777     
778     /**
779      * A nested builder class to create <code>Option</code> instances
780      * using descriptive methods.
781      * <p>
782      * Example usage:
783      * <pre>
784      * Option option = Option.builder("a")
785      *     .required(true)
786      *     .longOpt("arg-name")
787      *     .build();
788      * </pre>
789      * 
790      * @since 1.3
791      */
792     public static final class Builder 
793     {
794         /** the name of the option */
795         private final String opt;
796 
797         /** description of the option */
798         private String description;
799 
800         /** the long representation of the option */
801         private String longOpt;
802 
803         /** the name of the argument for this option */
804         private String argName;
805 
806         /** specifies whether this option is required to be present */
807         private boolean required;
808 
809         /** specifies whether the argument value of this Option is optional */
810         private boolean optionalArg;
811 
812         /** the number of argument values this option can have */
813         private int numberOfArgs = UNINITIALIZED;
814 
815         /** the type of this Option */
816         private Class<?> type = String.class;
817 
818         /** the character that is the value separator */
819         private char valuesep;
820 
821         /**
822          * Constructs a new <code>Builder</code> with the minimum
823          * required parameters for an <code>Option</code> instance.
824          * 
825          * @param opt short representation of the option
826          * @throws IllegalArgumentException if there are any non valid Option characters in {@code opt}
827          */
828         private Builder(final String opt) throws IllegalArgumentException
829         {
830             OptionValidator.validateOption(opt);
831             this.opt = opt;
832         }
833         
834         /**
835          * Sets the display name for the argument value.
836          *
837          * @param argName the display name for the argument value.
838          * @return this builder, to allow method chaining
839          */
840         public Builder argName(final String argName)
841         {
842             this.argName = argName;
843             return this;
844         }
845 
846         /**
847          * Sets the description for this option.
848          *
849          * @param description the description of the option.
850          * @return this builder, to allow method chaining
851          */
852         public Builder desc(final String description)
853         {
854             this.description = description;
855             return this;
856         }
857 
858         /**
859          * Sets the long name of the Option.
860          *
861          * @param longOpt the long name of the Option
862          * @return this builder, to allow method chaining
863          */        
864         public Builder longOpt(final String longOpt)
865         {
866             this.longOpt = longOpt;
867             return this;
868         }
869         
870         /** 
871          * Sets the number of argument values the Option can take.
872          *
873          * @param numberOfArgs the number of argument values
874          * @return this builder, to allow method chaining
875          */        
876         public Builder numberOfArgs(final int numberOfArgs)
877         {
878             this.numberOfArgs = numberOfArgs;
879             return this;
880         }
881         
882         /**
883          * Sets whether the Option can have an optional argument.
884          *
885          * @param isOptional specifies whether the Option can have
886          * an optional argument.
887          * @return this builder, to allow method chaining
888          */
889         public Builder optionalArg(final boolean isOptional)
890         {
891             this.optionalArg = isOptional;
892             return this;
893         }
894         
895         /**
896          * Marks this Option as required.
897          *
898          * @return this builder, to allow method chaining
899          */
900         public Builder required()
901         {
902             return required(true);
903         }
904 
905         /**
906          * Sets whether the Option is mandatory.
907          *
908          * @param required specifies whether the Option is mandatory
909          * @return this builder, to allow method chaining
910          */
911         public Builder required(final boolean required)
912         {
913             this.required = required;
914             return this;
915         }
916         
917         /**
918          * Sets the type of the Option.
919          *
920          * @param type the type of the Option
921          * @return this builder, to allow method chaining
922          */
923         public Builder type(final Class<?> type)
924         {
925             this.type = type;
926             return this;
927         }
928 
929         /**
930          * The Option will use '=' as a means to separate argument value.
931          *
932          * @return this builder, to allow method chaining
933          */
934         public Builder valueSeparator()
935         {
936             return valueSeparator('=');
937         }
938 
939         /**
940          * The Option will use <code>sep</code> as a means to
941          * separate argument values.
942          * <p>
943          * <b>Example:</b>
944          * <pre>
945          * Option opt = Option.builder("D").hasArgs()
946          *                                 .valueSeparator('=')
947          *                                 .build();
948          * Options options = new Options();
949          * options.addOption(opt);
950          * String[] args = {"-Dkey=value"};
951          * CommandLineParser parser = new DefaultParser();
952          * CommandLine line = parser.parse(options, args);
953          * String propertyName = line.getOptionValues("D")[0];  // will be "key"
954          * String propertyValue = line.getOptionValues("D")[1]; // will be "value"
955          * </pre>
956          *
957          * @param sep The value separator.
958          * @return this builder, to allow method chaining
959          */
960         public Builder valueSeparator(final char sep)
961         {
962             valuesep = sep;
963             return this;
964         }
965         
966         /**
967          * Indicates that the Option will require an argument.
968          * 
969          * @return this builder, to allow method chaining
970          */
971         public Builder hasArg()
972         {
973             return hasArg(true);
974         }
975 
976         /**
977          * Indicates if the Option has an argument or not.
978          * 
979          * @param hasArg specifies whether the Option takes an argument or not
980          * @return this builder, to allow method chaining
981          */
982         public Builder hasArg(final boolean hasArg)
983         {
984             // set to UNINITIALIZED when no arg is specified to be compatible with OptionBuilder
985             numberOfArgs = hasArg ? 1 : Option.UNINITIALIZED;
986             return this;
987         }
988 
989         /**
990          * Indicates that the Option can have unlimited argument values.
991          * 
992          * @return this builder, to allow method chaining
993          */
994         public Builder hasArgs()
995         {
996             numberOfArgs = Option.UNLIMITED_VALUES;
997             return this;
998         }
999 
1000         /**
1001          * Constructs an Option with the values declared by this {@link Builder}.
1002          * 
1003          * @return the new {@link Option}
1004          * @throws IllegalArgumentException if neither {@code opt} or {@code longOpt} has been set
1005          */
1006         public Option build()
1007         {
1008             if (opt == null && longOpt == null)
1009             {
1010                 throw new IllegalArgumentException("Either opt or longOpt must be specified");
1011             }
1012             return new Option(this);
1013         }
1014     }
1015 }