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 https://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.lang.reflect.Array; 022import java.util.ArrayList; 023import java.util.Iterator; 024import java.util.LinkedList; 025import java.util.List; 026import java.util.Objects; 027import java.util.Properties; 028import java.util.function.Consumer; 029import java.util.function.Supplier; 030 031/** 032 * Represents list of arguments parsed against a {@link Options} descriptor. 033 * <p> 034 * It allows querying of a boolean {@link #hasOption(String optionName)}, in addition to retrieving the 035 * {@link #getOptionValue(String optionName)} for options requiring arguments. 036 * </p> 037 * <p> 038 * Additionally, any left-over or unrecognized arguments, are available for further processing. 039 * </p> 040 */ 041public class CommandLine implements Serializable { 042 043 /** 044 * A nested builder class to create {@code CommandLine} instance using descriptive methods. 045 * 046 * @since 1.4 047 */ 048 public static final class Builder implements Supplier<CommandLine> { 049 050 /** 051 * Prints an Option to {@link System#out}. 052 */ 053 static final Consumer<Option> DEPRECATED_HANDLER = o -> System.out.println(o.toDeprecatedString()); 054 055 /** The unrecognized options/arguments */ 056 private final List<String> args = new LinkedList<>(); 057 058 /** The processed options */ 059 private final List<Option> options = new ArrayList<>(); 060 061 /** 062 * Deprecated Option handler. 063 */ 064 private Consumer<Option> deprecatedHandler = DEPRECATED_HANDLER; 065 066 /** 067 * Constructs a new instance. 068 * 069 * @deprecated Use {@link #builder()}. 070 */ 071 @Deprecated 072 public Builder() { 073 // empty 074 } 075 076 /** 077 * Adds left-over unrecognized option/argument. 078 * 079 * @param arg the unrecognized option/argument. 080 * @return this Builder instance for method chaining. 081 */ 082 public Builder addArg(final String arg) { 083 if (arg != null) { 084 args.add(arg); 085 } 086 return this; 087 } 088 089 /** 090 * Adds an option to the command line. The values of the option are stored. 091 * 092 * @param option the processed option. 093 * @return this Builder instance for method chaining. 094 */ 095 public Builder addOption(final Option option) { 096 if (option != null) { 097 options.add(option); 098 } 099 return this; 100 } 101 102 /** 103 * Creates a new instance. 104 * 105 * @return a new instance. 106 * @deprecated Use {@link #get()}. 107 */ 108 @Deprecated 109 public CommandLine build() { 110 return get(); 111 } 112 113 /** 114 * Creates a new instance. 115 * 116 * @return a new instance. 117 * @since 1.10.0 118 */ 119 @Override 120 public CommandLine get() { 121 return new CommandLine(args, options, deprecatedHandler); 122 } 123 124 /** 125 * Sets the deprecated option handler. 126 * 127 * @param deprecatedHandler the deprecated option handler. 128 * @return {@code this} instance. 129 * @since 1.7.0 130 */ 131 public Builder setDeprecatedHandler(final Consumer<Option> deprecatedHandler) { 132 this.deprecatedHandler = deprecatedHandler; 133 return this; 134 } 135 } 136 137 /** The serial version UID. */ 138 private static final long serialVersionUID = 1L; 139 140 /** 141 * Creates a new builder. 142 * 143 * @return a new builder. 144 * @since 1.7.0 145 */ 146 public static Builder builder() { 147 return new Builder(); 148 } 149 150 /** The unrecognized options/arguments */ 151 private final List<String> args; 152 153 /** The processed options */ 154 private final List<Option> options; 155 156 /** 157 * The deprecated option handler. 158 * <p> 159 * If you want to serialize this field, use a serialization proxy. 160 * </p> 161 */ 162 private final transient Consumer<Option> deprecatedHandler; 163 164 /** 165 * Creates a command line. 166 */ 167 protected CommandLine() { 168 this(new LinkedList<>(), new ArrayList<>(), Builder.DEPRECATED_HANDLER); 169 } 170 171 /** 172 * Creates a command line. 173 */ 174 private CommandLine(final List<String> args, final List<Option> options, final Consumer<Option> deprecatedHandler) { 175 this.args = Objects.requireNonNull(args, "args"); 176 this.options = Objects.requireNonNull(options, "options"); 177 this.deprecatedHandler = deprecatedHandler; 178 } 179 180 /** 181 * Adds left-over unrecognized option/argument. 182 * 183 * @param arg the unrecognized option/argument. 184 */ 185 protected void addArg(final String arg) { 186 if (arg != null) { 187 args.add(arg); 188 } 189 } 190 191 /** 192 * Adds an option to the command line. The values of the option are stored. 193 * 194 * @param option the processed option. 195 */ 196 protected void addOption(final Option option) { 197 if (option != null) { 198 options.add(option); 199 } 200 } 201 202 /** 203 * Gets the first element or null if values is null. 204 * 205 * @param values the array to query. 206 * @return the first element or null if values is null. 207 */ 208 private String first(final String[] values) { 209 return values == null ? null : values[0]; 210 } 211 212 private <T> T get(final Supplier<T> supplier) { 213 return supplier == null ? null : supplier.get(); 214 } 215 216 /** 217 * Gets any left-over non-recognized options and arguments. 218 * 219 * @return remaining items passed in but not parsed as a {@code List}. 220 */ 221 public List<String> getArgList() { 222 return args; 223 } 224 225 /** 226 * Gets any left-over non-recognized options and arguments. 227 * 228 * @return remaining items passed in but not parsed as an array. 229 */ 230 public String[] getArgs() { 231 return args.toArray(Util.EMPTY_STRING_ARRAY); 232 } 233 234 /** 235 * Gets the number of times this option appears in the command line 236 * 237 * @param optionChar the character name of the option. 238 * @return Number of times the option is present. 239 * @since 1.11.0 240 */ 241 public int getOptionCount(final char optionChar) { 242 return getOptionCount(String.valueOf(optionChar)); 243 } 244 245 /** 246 * Gets the number of times this option appears in the command line. 247 * 248 * @param option the option. 249 * @return Number of times the option is present. 250 * @since 1.11.0 251 */ 252 public int getOptionCount(final Option option) { 253 return (int) options.stream().filter(opt -> Objects.equals(opt, option)).count(); 254 } 255 256 /** 257 * Gets the number of times this option appears in the command line 258 * 259 * @param optionName the name of the option. 260 * @return Number of times the option is present. 261 * @since 1.11.0 262 */ 263 public int getOptionCount(final String optionName) { 264 return getOptionCount(resolveOption(optionName)); 265 } 266 267 /** 268 * Gets the {@code Object} type of this {@code Option}. 269 * 270 * @deprecated due to System.err message; use {@link #getParsedOptionValue(char)} instead. 271 * @param optionChar the name of the option. 272 * @return the type of opt. 273 */ 274 @Deprecated 275 public Object getOptionObject(final char optionChar) { 276 return getOptionObject(String.valueOf(optionChar)); 277 } 278 279 /** 280 * Gets the {@code Object} type of this {@code Option}. 281 * 282 * @param optionName the name of the option. 283 * @return the type of this {@code Option}. 284 * @deprecated due to System.err message; use {@link #getParsedOptionValue(String)} instead. 285 */ 286 @Deprecated 287 public Object getOptionObject(final String optionName) { 288 try { 289 return getParsedOptionValue(optionName); 290 } catch (final ParseException pe) { 291 System.err.println("Exception found converting " + optionName + " to desired type: " + pe.getMessage()); 292 return null; 293 } 294 } 295 296 /** 297 * Gets the map of values associated to the option. This is convenient for options specifying Java properties like 298 * <code>-Dparam1=value1 299 * -Dparam2=value2</code>. All odd numbered values are property keys 300 * and even numbered values are property values. If there are an odd number of values 301 * the last value is assumed to be a boolean flag and the value is "true". 302 * 303 * @param option name of the option. 304 * @return The Properties mapped by the option, never {@code null} even if the option doesn't exists. 305 * @since 1.5.0 306 */ 307 public Properties getOptionProperties(final Option option) { 308 final Properties props = new Properties(); 309 options.forEach(processedOption -> { 310 if (processedOption.equals(option)) { 311 processPropertiesFromValues(props, processedOption.getValuesList()); 312 } 313 }); 314 return props; 315 } 316 317 /** 318 * Gets the map of values associated to the option. This is convenient for options specifying Java properties like 319 * <code>-Dparam1=value1 320 * -Dparam2=value2</code>. The first argument of the option is the key, and the 2nd argument is the value. If the option 321 * has only one argument ({@code -Dfoo}) it is considered as a boolean flag and the value is {@code "true"}. 322 * 323 * @param optionName name of the option. 324 * @return The Properties mapped by the option, never {@code null} even if the option doesn't exists. 325 * @since 1.2 326 */ 327 public Properties getOptionProperties(final String optionName) { 328 final Properties props = new Properties(); 329 options.forEach(option -> { 330 if (optionName.equals(option.getOpt()) || optionName.equals(option.getLongOpt())) { 331 processPropertiesFromValues(props, option.getValuesList()); 332 } 333 }); 334 return props; 335 } 336 337 /** 338 * Gets an array of the processed {@link Option}s. 339 * 340 * @return an array of the processed {@link Option}s. 341 */ 342 public Option[] getOptions() { 343 return options.toArray(Option.EMPTY_ARRAY); 344 } 345 346 /** 347 * Gets the first argument, if any, of this option. 348 * 349 * @param optionChar the character name of the option. 350 * @return Value of the argument if option is set, and has an argument, otherwise null. 351 */ 352 public String getOptionValue(final char optionChar) { 353 return getOptionValue(String.valueOf(optionChar)); 354 } 355 356 /** 357 * Gets the argument, if any, of an option. 358 * 359 * @param optionChar character name of the option 360 * @param defaultValue is the default value to be returned if the option is not specified. 361 * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}. 362 */ 363 public String getOptionValue(final char optionChar, final String defaultValue) { 364 return getOptionValue(String.valueOf(optionChar), () -> defaultValue); 365 } 366 367 /** 368 * Gets the argument, if any, of an option. 369 * 370 * @param optionChar character name of the option. 371 * @param defaultValue is a supplier for the default value to be returned if the option is not specified. 372 * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}. 373 * @since 1.7.0 374 */ 375 public String getOptionValue(final char optionChar, final Supplier<String> defaultValue) { 376 return getOptionValue(String.valueOf(optionChar), defaultValue); 377 } 378 379 /** 380 * Gets the first argument, if any, of this option. 381 * 382 * @param option the option. 383 * @return Value of the argument if option is set, and has an argument, otherwise null. 384 * @since 1.5.0 385 */ 386 public String getOptionValue(final Option option) { 387 return first(getOptionValues(option)); 388 } 389 390 /** 391 * Gets the first argument, if any, of an option. 392 * 393 * @param option the option. 394 * @param defaultValue is the default value to be returned if the option is not specified. 395 * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}. 396 * @since 1.5.0 397 */ 398 public String getOptionValue(final Option option, final String defaultValue) { 399 return getOptionValue(option, () -> defaultValue); 400 } 401 402 /** 403 * Gets the first argument, if any, of an option. 404 * 405 * @param option the option. 406 * @param defaultValue is a supplier for the default value to be returned if the option is not specified. 407 * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}. 408 * @since 1.7.0 409 */ 410 public String getOptionValue(final Option option, final Supplier<String> defaultValue) { 411 final String answer = getOptionValue(option); 412 return answer != null ? answer : get(defaultValue); 413 } 414 415 /** 416 * Gets the first argument, if any, of this option group. 417 * 418 * @param optionGroup the option group. 419 * @return Value of the argument if option group is selected, and has an argument, otherwise null. 420 * @since 1.9.0 421 */ 422 public String getOptionValue(final OptionGroup optionGroup) { 423 return first(getOptionValues(optionGroup)); 424 } 425 426 /** 427 * Gets the first argument, if any, of an option group. 428 * 429 * @param optionGroup the option group. 430 * @param defaultValue is the default value to be returned if the option group is not selected. 431 * @return Value of the argument if option group is selected, and has an argument, otherwise {@code defaultValue}. 432 * @since 1.9.0 433 */ 434 public String getOptionValue(final OptionGroup optionGroup, final String defaultValue) { 435 return getOptionValue(optionGroup, () -> defaultValue); 436 } 437 438 /** 439 * Gets the first argument, if any, of an option group. 440 * 441 * @param optionGroup the option group. 442 * @param defaultValue is a supplier for the default value to be returned if the option group is not selected. 443 * @return Value of the argument if option group is selected, and has an argument, otherwise {@code defaultValue}. 444 * @since 1.9.0 445 */ 446 public String getOptionValue(final OptionGroup optionGroup, final Supplier<String> defaultValue) { 447 final String answer = getOptionValue(optionGroup); 448 return answer != null ? answer : get(defaultValue); 449 } 450 451 /** 452 * Gets the first argument, if any, of this option. 453 * 454 * @param optionName the name of the option. 455 * @return Value of the argument if option is set, and has an argument, otherwise null. 456 */ 457 public String getOptionValue(final String optionName) { 458 return getOptionValue(resolveOption(optionName)); 459 } 460 461 /** 462 * Gets the first argument, if any, of an option. 463 * 464 * @param optionName name of the option. 465 * @param defaultValue is the default value to be returned if the option is not specified. 466 * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}. 467 */ 468 public String getOptionValue(final String optionName, final String defaultValue) { 469 return getOptionValue(resolveOption(optionName), () -> defaultValue); 470 } 471 472 /** 473 * Gets the first argument, if any, of an option. 474 * 475 * @param optionName name of the option. 476 * @param defaultValue is a supplier for the default value to be returned if the option is not specified. 477 * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}. 478 * @since 1.7.0 479 */ 480 public String getOptionValue(final String optionName, final Supplier<String> defaultValue) { 481 return getOptionValue(resolveOption(optionName), defaultValue); 482 } 483 484 /** 485 * Gets the array of values, if any, of an option. 486 * 487 * @param optionChar character name of the option. 488 * @return Values of the argument if option is set, and has an argument, otherwise null. 489 */ 490 public String[] getOptionValues(final char optionChar) { 491 return getOptionValues(String.valueOf(optionChar)); 492 } 493 494 /** 495 * Gets the array of values, if any, of an option. 496 * 497 * @param option the option. 498 * @return Values of the argument if option is set, and has an argument, otherwise null. 499 * @since 1.5.0 500 */ 501 public String[] getOptionValues(final Option option) { 502 if (option == null) { 503 return null; 504 } 505 final List<String> values = new ArrayList<>(); 506 options.forEach(processedOption -> { 507 if (processedOption.equals(option)) { 508 if (option.isDeprecated()) { 509 handleDeprecated(option); 510 } 511 values.addAll(processedOption.getValuesList()); 512 } 513 }); 514 return values.isEmpty() ? null : values.toArray(Util.EMPTY_STRING_ARRAY); 515 } 516 517 /** 518 * Gets the array of values, if any, of an option group. 519 * 520 * @param optionGroup the option group. 521 * @return Values of the argument if option group is selected, and has an argument, otherwise null. 522 * @since 1.9.0 523 */ 524 public String[] getOptionValues(final OptionGroup optionGroup) { 525 if (optionGroup == null || !optionGroup.isSelected()) { 526 return null; 527 } 528 return getOptionValues(optionGroup.getSelected()); 529 } 530 531 /** 532 * Gets the array of values, if any, of an option. 533 * 534 * @param optionName string name of the option. 535 * @return Values of the argument if option is set, and has an argument, otherwise null. 536 */ 537 public String[] getOptionValues(final String optionName) { 538 return getOptionValues(resolveOption(optionName)); 539 } 540 541 /** 542 * Gets a version of this {@code Option} converted to a particular type. 543 * 544 * @param optionChar the name of the option. 545 * @param <T> The return type for the method. 546 * @return the value parsed into a particular object or null if the option is not set. 547 * @throws ParseException if there are problems turning the option value into the desired type. 548 * @see PatternOptionBuilder 549 * @since 1.5.0 550 */ 551 public <T> T getParsedOptionValue(final char optionChar) throws ParseException { 552 return getParsedOptionValue(String.valueOf(optionChar)); 553 } 554 555 /** 556 * Gets a version of this {@code Option} converted to a particular type. 557 * 558 * @param optionChar the name of the option. 559 * @param defaultValue the default value to return if opt is not set. 560 * @param <T> The return type for the method. 561 * @return the value parsed into a particular object or the defaultValue if the option is not set. 562 * @throws ParseException if there are problems turning the option value into the desired type. 563 * @see PatternOptionBuilder 564 * @since 1.7.0 565 */ 566 public <T> T getParsedOptionValue(final char optionChar, final Supplier<T> defaultValue) throws ParseException { 567 return getParsedOptionValue(String.valueOf(optionChar), defaultValue); 568 } 569 570 /** 571 * Gets a version of this {@code Option} converted to a particular type. 572 * 573 * @param optionChar the name of the option. 574 * @param defaultValue the default value to return if opt is not set. 575 * @param <T> The return type for the method. 576 * @return the value parsed into a particular object or the defaultValue if the option is not set. 577 * @throws ParseException if there are problems turning the option value into the desired type. 578 * @see PatternOptionBuilder 579 * @since 1.7.0 580 */ 581 public <T> T getParsedOptionValue(final char optionChar, final T defaultValue) throws ParseException { 582 return getParsedOptionValue(String.valueOf(optionChar), defaultValue); 583 } 584 585 /** 586 * Gets a version of this {@code Option} converted to a particular type. 587 * 588 * @param option the option. 589 * @param <T> The return type for the method. 590 * @return the value parsed into a particular object or null if the option is not set. 591 * @throws ParseException if there are problems turning the option value into the desired type. 592 * @see PatternOptionBuilder 593 * @since 1.5.0 594 */ 595 public <T> T getParsedOptionValue(final Option option) throws ParseException { 596 return getParsedOptionValue(option, () -> null); 597 } 598 599 /** 600 * Gets a version of this {@code Option} converted to a particular type. 601 * 602 * @param option the option. 603 * @param defaultValue the default value to return if opt is not set. 604 * @param <T> The return type for the method. 605 * @return the value parsed into a particular object or the defaultValue if the option is not set. 606 * @throws ParseException if there are problems turning the option value into the desired type. 607 * @see PatternOptionBuilder 608 * @since 1.7.0 609 */ 610 @SuppressWarnings("unchecked") 611 public <T> T getParsedOptionValue(final Option option, final Supplier<T> defaultValue) throws ParseException { 612 if (option == null) { 613 return get(defaultValue); 614 } 615 final String res = getOptionValue(option); 616 try { 617 if (res == null) { 618 return get(defaultValue); 619 } 620 return (T) option.getConverter().apply(res); 621 } catch (final Exception e) { 622 throw ParseException.wrap(e); 623 } 624 } 625 626 /** 627 * Gets a version of this {@code Option} converted to a particular type. 628 * 629 * @param option the option. 630 * @param defaultValue the default value to return if opt is not set. 631 * @param <T> The return type for the method. 632 * @return the value parsed into a particular object or the defaultValue if the option is not set. 633 * @throws ParseException if there are problems turning the option value into the desired type. 634 * @see PatternOptionBuilder 635 * @since 1.7.0 636 */ 637 public <T> T getParsedOptionValue(final Option option, final T defaultValue) throws ParseException { 638 return getParsedOptionValue(option, () -> defaultValue); 639 } 640 641 /** 642 * Gets a version of this {@code OptionGroup} converted to a particular type. 643 * 644 * @param optionGroup the option group. 645 * @param <T> The return type for the method. 646 * @return the value parsed into a particular object or null if no option in the OptionGroup is set. 647 * @throws ParseException if there are problems turning the selected option value into the desired type. 648 * @see PatternOptionBuilder 649 * @since 1.9.0 650 */ 651 public <T> T getParsedOptionValue(final OptionGroup optionGroup) throws ParseException { 652 return getParsedOptionValue(optionGroup, () -> null); 653 } 654 655 /** 656 * Gets a version of this {@code OptionGroup} converted to a particular type. 657 * 658 * @param optionGroup the option group. 659 * @param defaultValue the default value to return if opt is not set. 660 * @param <T> The return type for the method. 661 * @return the value parsed into a particular object or the defaultValue if no option in the OptionGroup is set. 662 * @throws ParseException if there are problems turning the selected option value into the desired type. 663 * @see PatternOptionBuilder 664 * @since 1.9.0 665 */ 666 public <T> T getParsedOptionValue(final OptionGroup optionGroup, final Supplier<T> defaultValue) throws ParseException { 667 if (optionGroup == null || !optionGroup.isSelected()) { 668 return get(defaultValue); 669 } 670 return getParsedOptionValue(optionGroup.getSelected(), defaultValue); 671 } 672 673 /** 674 * Gets a version of this {@code OptionGroup} converted to a particular type. 675 * 676 * @param optionGroup the option group. 677 * @param defaultValue the default value to return if an option is not selected. 678 * @param <T> The return type for the method. 679 * @return the value parsed into a particular object or the defaultValue if no option in the OptionGroup is set. 680 * @throws ParseException if there are problems turning the option value into the desired type. 681 * @see PatternOptionBuilder 682 * @since 1.9.0 683 */ 684 public <T> T getParsedOptionValue(final OptionGroup optionGroup, final T defaultValue) throws ParseException { 685 return getParsedOptionValue(optionGroup, () -> defaultValue); 686 } 687 688 /** 689 * Gets a version of this {@code Option} converted to a particular type. 690 * 691 * @param optionName the name of the option. 692 * @param <T> The return type for the method. 693 * @return the value parsed into a particular object or null if the option is not set. 694 * @throws ParseException if there are problems turning the option value into the desired type. 695 * @see PatternOptionBuilder 696 * @since 1.2 697 */ 698 public <T> T getParsedOptionValue(final String optionName) throws ParseException { 699 return getParsedOptionValue(resolveOption(optionName)); 700 } 701 702 /** 703 * Gets a version of this {@code Option} converted to a particular type. 704 * 705 * @param optionName the name of the option. 706 * @param defaultValue the default value to return if opt is not set. 707 * @param <T> The return type for the method. 708 * @return the value parsed into a particular object or the defaultValue if the option is not set. 709 * @throws ParseException if there are problems turning the option value into the desired type. 710 * @see PatternOptionBuilder 711 * @since 1.7.0 712 */ 713 public <T> T getParsedOptionValue(final String optionName, final Supplier<T> defaultValue) throws ParseException { 714 return getParsedOptionValue(resolveOption(optionName), defaultValue); 715 } 716 717 /** 718 * Gets a version of this {@code Option} converted to a particular type. 719 * 720 * @param optionName the name of the option. 721 * @param defaultValue the default value to return if opt is not set. 722 * @param <T> The return type for the method. 723 * @return the value parsed into a particular object or the defaultValue if the option is not set. 724 * @throws ParseException if there are problems turning the option value into the desired type. 725 * @see PatternOptionBuilder 726 * @since 1.7.0 727 */ 728 public <T> T getParsedOptionValue(final String optionName, final T defaultValue) throws ParseException { 729 return getParsedOptionValue(resolveOption(optionName), defaultValue); 730 } 731 732 /** 733 * Gets a version of this {@code Option} converted to an array of a particular type. 734 * 735 * @param optionChar the name of the option. 736 * @param <T> The array type for the return value. 737 * @return the values parsed into an array of objects or null if the option is not set. 738 * @throws ParseException if there are problems turning the option value into the desired type. 739 * @see PatternOptionBuilder 740 * @since 1.10.0 741 */ 742 public <T> T[] getParsedOptionValues(final char optionChar) throws ParseException { 743 return getParsedOptionValues(String.valueOf(optionChar)); 744 } 745 746 /** 747 * Gets a version of this {@code Option} converted to an array of a particular type. 748 * 749 * @param optionChar the name of the option. 750 * @param defaultValue the default value to return if opt is not set. 751 * @param <T> The array type for the return value. 752 * @return the values parsed into an array of objects or the defaultValue if the option is not set. 753 * @throws ParseException if there are problems turning the option value into the desired type. 754 * @see PatternOptionBuilder 755 * @since 1.10.0 756 */ 757 public <T> T[] getParsedOptionValues(final char optionChar, final Supplier<T[]> defaultValue) throws ParseException { 758 return getParsedOptionValues(String.valueOf(optionChar), defaultValue); 759 } 760 761 /** 762 * Gets a version of this {@code Option} converted to an array of a particular type. 763 * 764 * @param optionChar the name of the option. 765 * @param defaultValue the default value to return if opt is not set. 766 * @param <T> The array type for the return value. 767 * @return the values parsed into an array of objects or the defaultValue if the option is not set. 768 * @throws ParseException if there are problems turning the option value into the desired type. 769 * @see PatternOptionBuilder 770 * @since 1.10.0 771 */ 772 public <T> T[] getParsedOptionValues(final char optionChar, final T[] defaultValue) throws ParseException { 773 return getParsedOptionValues(String.valueOf(optionChar), defaultValue); 774 } 775 776 /** 777 * Gets a version of this {@code Option} converted to an array of a particular type. 778 * 779 * @param option the option. 780 * @param <T> The array type for the return value. 781 * @return the values parsed into an array of objects or null if the option is not set. 782 * @throws ParseException if there are problems turning the option value into the desired type. 783 * @see PatternOptionBuilder 784 * @since 1.10.0 785 */ 786 public <T> T[] getParsedOptionValues(final Option option) throws ParseException { 787 return getParsedOptionValues(option, () -> null); 788 } 789 790 /** 791 * Gets a version of this {@code Option} converted to an array of a particular type. 792 * 793 * @param option the option. 794 * @param defaultValue the default value to return if opt is not set. 795 * @param <T> The array type for the return value. 796 * @return the values parsed into an array of objects or the defaultValue if the option is not set. 797 * @throws ParseException if there are problems turning the option value into the desired type. 798 * @see PatternOptionBuilder 799 * @since 1.10.0 800 */ 801 @SuppressWarnings("unchecked") 802 public <T> T[] getParsedOptionValues(final Option option, final Supplier<T[]> defaultValue) throws ParseException { 803 if (option == null) { 804 return get(defaultValue); 805 } 806 final Class<? extends T> clazz = (Class<? extends T>) option.getType(); 807 final String[] values = getOptionValues(option); 808 if (values == null) { 809 return get(defaultValue); 810 } 811 final T[] result = (T[]) Array.newInstance(clazz, values.length); 812 try { 813 for (int i = 0; i < values.length; i++) { 814 result[i] = clazz.cast(option.getConverter().apply(values[i])); 815 } 816 return result; 817 } catch (final Exception t) { 818 throw ParseException.wrap(t); 819 } 820 } 821 822 /** 823 * Gets a version of this {@code Option} converted to an array of a particular type. 824 * 825 * @param option the option. 826 * @param defaultValue the default value to return if opt is not set. 827 * @param <T> The array type for the return value. 828 * @return the values parsed into an array of objects or the defaultValue if the option is not set. 829 * @throws ParseException if there are problems turning the option value into the desired type. 830 * @see PatternOptionBuilder 831 * @since 1.10.0 832 */ 833 public <T> T[] getParsedOptionValues(final Option option, final T[] defaultValue) throws ParseException { 834 return getParsedOptionValues(option, () -> defaultValue); 835 } 836 837 /** 838 * Gets a version of this {@code OptionGroup} converted to an array of a particular type. 839 * 840 * @param optionGroup the option group. 841 * @param <T> The array type for the return value. 842 * @return the values parsed into an array of objects or null if no option in the OptionGroup is set. 843 * @throws ParseException if there are problems turning the selected option value into the desired type. 844 * @see PatternOptionBuilder 845 * @since 1.10.0 846 */ 847 public <T> T[] getParsedOptionValues(final OptionGroup optionGroup) throws ParseException { 848 return getParsedOptionValues(optionGroup, () -> null); 849 } 850 851 /** 852 * Gets a version of this {@code OptionGroup} converted to an array of a particular type. 853 * 854 * @param optionGroup the option group. 855 * @param defaultValue the default value to return if opt is not set. 856 * @param <T> The array type for the return value. 857 * @return the values parsed into an array of objects or null if no option in the OptionGroup is set. 858 * @throws ParseException if there are problems turning the selected option value into the desired type. 859 * @see PatternOptionBuilder 860 * @since 1.10.0 861 */ 862 public <T> T[] getParsedOptionValues(final OptionGroup optionGroup, final Supplier<T[]> defaultValue) throws ParseException { 863 if (optionGroup == null || !optionGroup.isSelected()) { 864 return get(defaultValue); 865 } 866 return getParsedOptionValues(optionGroup.getSelected(), defaultValue); 867 } 868 869 /** 870 * Gets a version of this {@code OptionGroup} converted to an array of a particular type. 871 * 872 * @param optionGroup the option group. 873 * @param defaultValue the default value to return if an option is not selected. 874 * @param <T> The array type for the return value. 875 * @return the values parsed into an array of objects or null if no option in the OptionGroup is set. 876 * @throws ParseException if there are problems turning the option value into the desired type. 877 * @see PatternOptionBuilder 878 * @since 1.10.0 879 */ 880 public <T> T[] getParsedOptionValues(final OptionGroup optionGroup, final T[] defaultValue) throws ParseException { 881 return getParsedOptionValues(optionGroup, () -> defaultValue); 882 } 883 884 /** 885 * Gets a version of this {@code Option} converted to an array of a particular type. 886 * 887 * @param optionName the name of the option. 888 * @param <T> The array type for the return value. 889 * @return the values parsed into an array of objects or null if the option is not set. 890 * @throws ParseException if there are problems turning the option value into the desired type. 891 * @see PatternOptionBuilder 892 * @since 1.10.0 893 */ 894 public <T> T[] getParsedOptionValues(final String optionName) throws ParseException { 895 return getParsedOptionValues(resolveOption(optionName)); 896 } 897 898 /** 899 * Gets a version of this {@code Option} converted to an array of a particular type. 900 * 901 * @param optionName the name of the option. 902 * @param defaultValue the default value to return if opt is not set. 903 * @param <T> The array type for the return value. 904 * @return the values parsed into an array of objects or defaultValues if the option is not set. 905 * @throws ParseException if there are problems turning the option value into the desired type. 906 * @see PatternOptionBuilder 907 * @since 1.10.0 908 */ 909 public <T> T[] getParsedOptionValues(final String optionName, final Supplier<T[]> defaultValue) throws ParseException { 910 return getParsedOptionValues(resolveOption(optionName), defaultValue); 911 } 912 913 /** 914 * Gets a version of this {@code Option} converted to an array of a particular type. 915 * 916 * @param optionName the name of the option. 917 * @param defaultValue the default value to return if opt is not set. 918 * @param <T> The array type for the return value. 919 * @return the values parsed into an array of objects or defaultValues if the option is not set. 920 * @throws ParseException if there are problems turning the option value into the desired type. 921 * @see PatternOptionBuilder 922 * @since 1.10.0 923 */ 924 public <T> T[] getParsedOptionValues(final String optionName, final T[] defaultValue) throws ParseException { 925 return getParsedOptionValues(resolveOption(optionName), defaultValue); 926 } 927 928 /** 929 * Handles deprecated options. 930 * 931 * @param option a deprecated option. 932 */ 933 private void handleDeprecated(final Option option) { 934 if (deprecatedHandler != null) { 935 deprecatedHandler.accept(option); 936 } 937 } 938 939 /** 940 * jkeyes - commented out until it is implemented properly 941 * <p> 942 * Dump state, suitable for debugging. 943 * </p> 944 * 945 * @return Stringified form of this object. 946 */ 947 948 /* 949 * public String toString() { StringBuilder buf = new StringBuilder(); 950 * 951 * buf.append("[ CommandLine: [ options: "); buf.append(options.toString()); buf.append(" ] [ args: "); 952 * buf.append(args.toString()); buf.append(" ] ]"); 953 * 954 * return buf.toString(); } 955 */ 956 957 /** 958 * Tests to see if an option has been set. 959 * 960 * @param optionChar character name of the option. 961 * @return true if set, false if not. 962 */ 963 public boolean hasOption(final char optionChar) { 964 return hasOption(String.valueOf(optionChar)); 965 } 966 967 /** 968 * Tests to see if an option has been set. 969 * 970 * @param option the option to check. 971 * @return true if set, false if not. 972 * @since 1.5.0 973 */ 974 public boolean hasOption(final Option option) { 975 final boolean result = options.contains(option); 976 if (result && option.isDeprecated()) { 977 handleDeprecated(option); 978 } 979 return result; 980 } 981 982 /** 983 * Tests to see if an option has been set. 984 * 985 * @param optionGroup the option group to check. 986 * @return true if set, false if not. 987 * @since 1.9.0 988 */ 989 public boolean hasOption(final OptionGroup optionGroup) { 990 if (optionGroup == null || !optionGroup.isSelected()) { 991 return false; 992 } 993 return hasOption(optionGroup.getSelected()); 994 } 995 996 /** 997 * Tests to see if an option has been set. 998 * 999 * @param optionName Short name of the option. 1000 * @return true if set, false if not. 1001 */ 1002 public boolean hasOption(final String optionName) { 1003 return hasOption(resolveOption(optionName)); 1004 } 1005 1006 /** 1007 * Returns an iterator over the Option members of CommandLine. 1008 * 1009 * @return an {@code Iterator} over the processed {@link Option} members of this {@link CommandLine}. 1010 */ 1011 public Iterator<Option> iterator() { 1012 return options.iterator(); 1013 } 1014 1015 /** 1016 * Parses a list of values as properties. All odd numbered values are property keys 1017 * and even numbered values are property values. If there are an odd number of values 1018 * the last value is assumed to be a boolean with a value of "true". 1019 * 1020 * @param props the properties to update. 1021 * @param values the list of values to parse. 1022 */ 1023 private void processPropertiesFromValues(final Properties props, final List<String> values) { 1024 for (int i = 0; i < values.size(); i += 2) { 1025 props.put(values.get(i), i + 1 < values.size() ? values.get(i + 1) : "true"); 1026 } 1027 } 1028 1029 /** 1030 * Retrieves the option object given the long or short option as a String 1031 * 1032 * @param optionName short or long name of the option, may be null. 1033 * @return Canonicalized option. 1034 */ 1035 private Option resolveOption(final String optionName) { 1036 final String actual = Util.stripLeadingHyphens(optionName); 1037 if (actual != null) { 1038 return options.stream() 1039 .filter(opt -> actual.equals(opt.getOpt()) || actual.equals(opt.getLongOpt())) 1040 .findFirst().orElse(null); 1041 } 1042 return null; 1043 } 1044}