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