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 1544827 2013-11-23 16:16:54Z tn $
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 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      * @return num the number of argument values
420      */
421     public int getArgs()
422     {
423         return numberOfArgs;
424     }
425 
426     /**
427      * Adds the specified value to this Option.
428      * 
429      * @param value is a/the value of this Option
430      */
431     void addValueForProcessing(String value)
432     {
433         if (numberOfArgs == UNINITIALIZED)
434         {
435             throw new RuntimeException("NO_ARGS_ALLOWED");
436         }
437         processValue(value);
438     }
439 
440     /**
441      * Processes the value.  If this Option has a value separator
442      * the value will have to be parsed into individual tokens.  When
443      * n-1 tokens have been processed and there are more value separators
444      * in the value, parsing is ceased and the remaining characters are
445      * added as a single token.
446      *
447      * @param value The String to be processed.
448      *
449      * @since 1.0.1
450      */
451     private void processValue(String value)
452     {
453         // this Option has a separator character
454         if (hasValueSeparator())
455         {
456             // get the separator character
457             char sep = getValueSeparator();
458 
459             // store the index for the value separator
460             int index = value.indexOf(sep);
461 
462             // while there are more value separators
463             while (index != -1)
464             {
465                 // next value to be added 
466                 if (values.size() == (numberOfArgs - 1))
467                 {
468                     break;
469                 }
470 
471                 // store
472                 add(value.substring(0, index));
473 
474                 // parse
475                 value = value.substring(index + 1);
476 
477                 // get new index
478                 index = value.indexOf(sep);
479             }
480         }
481 
482         // store the actual value or the last value that has been parsed
483         add(value);
484     }
485 
486     /**
487      * Add the value to this Option.  If the number of arguments
488      * is greater than zero and there is enough space in the list then
489      * add the value.  Otherwise, throw a runtime exception.
490      *
491      * @param value The value to be added to this Option
492      *
493      * @since 1.0.1
494      */
495     private void add(String value)
496     {
497         if (!acceptsArg())
498         {
499             throw new RuntimeException("Cannot add value, list full.");
500         }
501 
502         // store value
503         values.add(value);
504     }
505 
506     /**
507      * Returns the specified value of this Option or 
508      * <code>null</code> if there is no value.
509      *
510      * @return the value/first value of this Option or 
511      * <code>null</code> if there is no value.
512      */
513     public String getValue()
514     {
515         return hasNoValues() ? null : values.get(0);
516     }
517 
518     /**
519      * Returns the specified value of this Option or 
520      * <code>null</code> if there is no value.
521      *
522      * @param index The index of the value to be returned.
523      *
524      * @return the specified value of this Option or 
525      * <code>null</code> if there is no value.
526      *
527      * @throws IndexOutOfBoundsException if index is less than 1
528      * or greater than the number of the values for this Option.
529      */
530     public String getValue(int index) throws IndexOutOfBoundsException
531     {
532         return hasNoValues() ? null : values.get(index);
533     }
534 
535     /**
536      * Returns the value/first value of this Option or the 
537      * <code>defaultValue</code> if there is no value.
538      *
539      * @param defaultValue The value to be returned if ther
540      * is no value.
541      *
542      * @return the value/first value of this Option or the 
543      * <code>defaultValue</code> if there are no values.
544      */
545     public String getValue(String defaultValue)
546     {
547         String value = getValue();
548 
549         return (value != null) ? value : defaultValue;
550     }
551 
552     /**
553      * Return the values of this Option as a String array 
554      * or null if there are no values
555      *
556      * @return the values of this Option as a String array 
557      * or null if there are no values
558      */
559     public String[] getValues()
560     {
561         return hasNoValues() ? null : values.toArray(new String[values.size()]);
562     }
563 
564     /**
565      * @return the values of this Option as a List
566      * or null if there are no values
567      */
568     public List<String> getValuesList()
569     {
570         return values;
571     }
572 
573     /** 
574      * Dump state, suitable for debugging.
575      *
576      * @return Stringified form of this object
577      */
578     @Override
579     public String toString()
580     {
581         StringBuilder buf = new StringBuilder().append("[ option: ");
582 
583         buf.append(opt);
584 
585         if (longOpt != null)
586         {
587             buf.append(" ").append(longOpt);
588         }
589 
590         buf.append(" ");
591 
592         if (hasArgs())
593         {
594             buf.append("[ARG...]");
595         }
596         else if (hasArg())
597         {
598             buf.append(" [ARG]");
599         }
600 
601         buf.append(" :: ").append(description);
602 
603         if (type != null)
604         {
605             buf.append(" :: ").append(type);
606         }
607 
608         buf.append(" ]");
609 
610         return buf.toString();
611     }
612 
613     /**
614      * Returns whether this Option has any values.
615      *
616      * @return whether this Option has any values.
617      */
618     private boolean hasNoValues()
619     {
620         return values.isEmpty();
621     }
622 
623     @Override
624     public boolean equals(Object o)
625     {
626         if (this == o)
627         {
628             return true;
629         }
630         if (o == null || getClass() != o.getClass())
631         {
632             return false;
633         }
634 
635         Option option = (Option) o;
636 
637 
638         if (opt != null ? !opt.equals(option.opt) : option.opt != null)
639         {
640             return false;
641         }
642         if (longOpt != null ? !longOpt.equals(option.longOpt) : option.longOpt != null)
643         {
644             return false;
645         }
646 
647         return true;
648     }
649 
650     @Override
651     public int hashCode()
652     {
653         int result;
654         result = opt != null ? opt.hashCode() : 0;
655         result = 31 * result + (longOpt != null ? longOpt.hashCode() : 0);
656         return result;
657     }
658 
659     /**
660      * A rather odd clone method - due to incorrect code in 1.0 it is public 
661      * and in 1.1 rather than throwing a CloneNotSupportedException it throws 
662      * a RuntimeException so as to maintain backwards compat at the API level. 
663      *
664      * After calling this method, it is very likely you will want to call 
665      * clearValues(). 
666      *
667      * @return a clone of this Option instance
668      * @throws RuntimeException if a {@link CloneNotSupportedException} has been thrown
669      * by {@link super#clone()}
670      */
671     @Override
672     public Object clone()
673     {
674         try
675         {
676             Option option = (Option) super.clone();
677             option.values = new ArrayList<String>(values);
678             return option;
679         }
680         catch (CloneNotSupportedException cnse)
681         {
682             throw new RuntimeException("A CloneNotSupportedException was thrown: " + cnse.getMessage());
683         }
684     }
685 
686     /**
687      * Clear the Option values. After a parse is complete, these are left with
688      * data in them and they need clearing if another parse is done.
689      *
690      * See: <a href="https://issues.apache.org/jira/browse/CLI-71">CLI-71</a>
691      */
692     void clearValues()
693     {
694         values.clear();
695     }
696 
697     /**
698      * This method is not intended to be used. It was a piece of internal 
699      * API that was made public in 1.0. It currently throws an UnsupportedOperationException.
700      *
701      * @param value the value to add
702      * @return always throws an {@link UnsupportedOperationException}
703      * @throws UnsupportedOperationException always
704      * @deprecated
705      */
706     @Deprecated
707     public boolean addValue(String value)
708     {
709         throw new UnsupportedOperationException("The addValue method is not intended for client use. "
710                 + "Subclasses should use the addValueForProcessing method instead. ");
711     }
712 
713     /**
714      * Tells if the option can accept more arguments.
715      * 
716      * @return false if the maximum number of arguments is reached
717      * @since 1.3
718      */
719     boolean acceptsArg()
720     {
721         return (hasArg() || hasArgs() || hasOptionalArg()) && (numberOfArgs <= 0 || values.size() < numberOfArgs);
722     }
723 
724     /**
725      * Tells if the option requires more arguments to be valid.
726      * 
727      * @return false if the option doesn't require more arguments
728      * @since 1.3
729      */
730     boolean requiresArg()
731     {
732         if (optionalArg)
733         {
734             return false;
735         }
736         if (numberOfArgs == UNLIMITED_VALUES)
737         {
738             return values.isEmpty();
739         }
740         return acceptsArg();
741     }
742     
743     /**
744      * Returns a {@link Builder} to create an {@link Option} using descriptive
745      * methods.  
746      * 
747      * @return a new {@link Builder} instance
748      * @since 1.3
749      */
750     public static Builder builder()
751     {
752         return builder(null);
753     }
754     
755     /**
756      * Returns a {@link Builder} to create an {@link Option} using descriptive
757      * methods.  
758      *
759      * @param opt short representation of the option
760      * @return a new {@link Builder} instance
761      * @throws IllegalArgumentException if there are any non valid Option characters in {@code opt}
762      * @since 1.3
763      */
764     public static Builder builder(final String opt)
765     {
766         return new Builder(opt);
767     }
768     
769     /**
770      * A nested builder class to create <code>Option</code> instances
771      * using descriptive methods.
772      * <p>
773      * Example usage:
774      * <pre>
775      * Option option = Option.builder("a")
776      *     .required(true)
777      *     .longOpt("arg-name")
778      *     .build();
779      * </pre>
780      * 
781      * @since 1.3
782      */
783     public static final class Builder 
784     {
785         /** the name of the option */
786         private final String opt;
787 
788         /** description of the option */
789         private String description;
790 
791         /** the long representation of the option */
792         private String longOpt;
793 
794         /** the name of the argument for this option */
795         private String argName;
796 
797         /** specifies whether this option is required to be present */
798         private boolean required;
799 
800         /** specifies whether the argument value of this Option is optional */
801         private boolean optionalArg;
802 
803         /** the number of argument values this option can have */
804         private int numberOfArgs = UNINITIALIZED;
805 
806         /** the type of this Option */
807         private Class<?> type = String.class;
808 
809         /** the character that is the value separator */
810         private char valuesep;
811 
812         /**
813          * Constructs a new <code>Builder</code> with the minimum
814          * required parameters for an <code>Option</code> instance.
815          * 
816          * @param opt short representation of the option
817          * @throws IllegalArgumentException if there are any non valid Option characters in {@code opt}
818          */
819         private Builder(final String opt) throws IllegalArgumentException
820         {
821             OptionValidator.validateOption(opt);
822             this.opt = opt;
823         }
824         
825         /**
826          * Sets the display name for the argument value.
827          *
828          * @param argName the display name for the argument value.
829          * @return this builder, to allow method chaining
830          */
831         public Builder argName(final String argName)
832         {
833             this.argName = argName;
834             return this;
835         }
836 
837         /**
838          * Sets the description for this option.
839          *
840          * @param description the description of the option.
841          * @return this builder, to allow method chaining
842          */
843         public Builder desc(final String description)
844         {
845             this.description = description;
846             return this;
847         }
848 
849         /**
850          * Sets the long name of the Option.
851          *
852          * @param longOpt the long name of the Option
853          * @return this builder, to allow method chaining
854          */        
855         public Builder longOpt(final String longOpt)
856         {
857             this.longOpt = longOpt;
858             return this;
859         }
860         
861         /** 
862          * Sets the number of argument values the Option can take.
863          *
864          * @param numberOfArgs the number of argument values
865          * @return this builder, to allow method chaining
866          */        
867         public Builder numberOfArgs(final int numberOfArgs)
868         {
869             this.numberOfArgs = numberOfArgs;
870             return this;
871         }
872         
873         /**
874          * Sets whether the Option can have an optional argument.
875          *
876          * @param isOptional specifies whether the Option can have
877          * an optional argument.
878          * @return this builder, to allow method chaining
879          */
880         public Builder optionalArg(final boolean isOptional)
881         {
882             this.optionalArg = isOptional;
883             return this;
884         }
885         
886         /**
887          * Marks this Option as required.
888          *
889          * @return this builder, to allow method chaining
890          */
891         public Builder required()
892         {
893             return required(true);
894         }
895 
896         /**
897          * Sets whether the Option is mandatory.
898          *
899          * @param required specifies whether the Option is mandatory
900          * @return this builder, to allow method chaining
901          */
902         public Builder required(final boolean required)
903         {
904             this.required = required;
905             return this;
906         }
907         
908         /**
909          * Sets the type of the Option.
910          *
911          * @param type the type of the Option
912          * @return this builder, to allow method chaining
913          */
914         public Builder type(final Class<?> type)
915         {
916             this.type = type;
917             return this;
918         }
919 
920         /**
921          * The Option will use '=' as a means to separate argument value.
922          *
923          * @return this builder, to allow method chaining
924          */
925         public Builder valueSeparator()
926         {
927             return valueSeparator('=');
928         }
929 
930         /**
931          * The Option will use <code>sep</code> as a means to
932          * separate argument values.
933          * <p>
934          * <b>Example:</b>
935          * <pre>
936          * Option opt = Option.builder("D").hasArgs()
937          *                                 .valueSeparator('=')
938          *                                 .build();
939          * Options options = new Options();
940          * options.addOption(opt);
941          * String[] args = {"-Dkey=value"};
942          * CommandLineParser parser = new DefaultParser();
943          * CommandLine line = parser.parse(options, args);
944          * String propertyName = line.getOptionValues("D")[0];  // will be "key"
945          * String propertyValue = line.getOptionValues("D")[1]; // will be "value"
946          * </pre>
947          *
948          * @param sep The value separator.
949          * @return this builder, to allow method chaining
950          */
951         public Builder valueSeparator(final char sep)
952         {
953             valuesep = sep;
954             return this;
955         }
956         
957         /**
958          * Indicates that the Option will require an argument.
959          * 
960          * @return this builder, to allow method chaining
961          */
962         public Builder hasArg()
963         {
964             return hasArg(true);
965         }
966 
967         /**
968          * Indicates if the Option has an argument or not.
969          * 
970          * @param hasArg specifies whether the Option takes an argument or not
971          * @return this builder, to allow method chaining
972          */
973         public Builder hasArg(final boolean hasArg)
974         {
975             // set to UNINITIALIZED when no arg is specified to be compatible with OptionBuilder
976             numberOfArgs = hasArg ? 1 : Option.UNINITIALIZED;
977             return this;
978         }
979 
980         /**
981          * Indicates that the Option can have unlimited argument values.
982          * 
983          * @return this builder, to allow method chaining
984          */
985         public Builder hasArgs()
986         {
987             numberOfArgs = Option.UNLIMITED_VALUES;
988             return this;
989         }
990 
991         /**
992          * Constructs an Option with the values declared by this {@link Builder}.
993          * 
994          * @return the new {@link Option}
995          * @throws IllegalArgumentException if neither {@code opt} or {@code longOpt} has been set
996          */
997         public Option build()
998         {
999             if (opt == null && longOpt == null)
1000             {
1001                 throw new IllegalArgumentException("Either opt or longOpt must be specified");
1002             }
1003             return new Option(this);
1004         }
1005     }
1006 }