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