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