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