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 private <T> T get(final Supplier<T> supplier) { 203 return supplier == null ? null : supplier.get(); 204 } 205 206 /** 207 * Gets any left-over non-recognized options and arguments 208 * 209 * @return remaining items passed in but not parsed as a {@code List}. 210 */ 211 public List<String> getArgList() { 212 return args; 213 } 214 215 /** 216 * Gets any left-over non-recognized options and arguments 217 * 218 * @return remaining items passed in but not parsed as an array. 219 */ 220 public String[] getArgs() { 221 return args.toArray(Util.EMPTY_STRING_ARRAY); 222 } 223 224 /** 225 * Gets the {@code Object} type of this {@code Option}. 226 * 227 * @deprecated due to System.err message. Instead use getParsedOptionValue(char) 228 * @param optionChar the name of the option. 229 * @return the type of opt. 230 */ 231 @Deprecated 232 public Object getOptionObject(final char optionChar) { 233 return getOptionObject(String.valueOf(optionChar)); 234 } 235 236 /** 237 * Gets the {@code Object} type of this {@code Option}. 238 * 239 * @param optionName the name of the option. 240 * @return the type of this {@code Option}. 241 * @deprecated due to System.err message. Instead use getParsedOptionValue(String) 242 */ 243 @Deprecated 244 public Object getOptionObject(final String optionName) { 245 try { 246 return getParsedOptionValue(optionName); 247 } catch (final ParseException pe) { 248 System.err.println("Exception found converting " + optionName + " to desired type: " + pe.getMessage()); 249 return null; 250 } 251 } 252 253 /** 254 * Gets the map of values associated to the option. This is convenient for options specifying Java properties like 255 * <code>-Dparam1=value1 256 * -Dparam2=value2</code>. All odd numbered values are property keys 257 * and even numbered values are property values. If there are an odd number of values 258 * the last value is assumed to be a boolean flag and the value is "true". 259 * 260 * @param option name of the option. 261 * @return The Properties mapped by the option, never {@code null} even if the option doesn't exists. 262 * @since 1.5.0 263 */ 264 public Properties getOptionProperties(final Option option) { 265 final Properties props = new Properties(); 266 for (final Option processedOption : options) { 267 if (processedOption.equals(option)) { 268 processPropertiesFromValues(props, processedOption.getValuesList()); 269 } 270 } 271 return props; 272 } 273 274 /** 275 * Gets the map of values associated to the option. This is convenient for options specifying Java properties like 276 * <code>-Dparam1=value1 277 * -Dparam2=value2</code>. The first argument of the option is the key, and the 2nd argument is the value. If the option 278 * has only one argument ({@code -Dfoo}) it is considered as a boolean flag and the value is {@code "true"}. 279 * 280 * @param optionName name of the option. 281 * @return The Properties mapped by the option, never {@code null} even if the option doesn't exists. 282 * @since 1.2 283 */ 284 public Properties getOptionProperties(final String optionName) { 285 final Properties props = new Properties(); 286 for (final Option option : options) { 287 if (optionName.equals(option.getOpt()) || optionName.equals(option.getLongOpt())) { 288 processPropertiesFromValues(props, option.getValuesList()); 289 } 290 } 291 return props; 292 } 293 294 /** 295 * Gets an array of the processed {@link Option}s. 296 * 297 * @return an array of the processed {@link Option}s. 298 */ 299 public Option[] getOptions() { 300 return options.toArray(Option.EMPTY_ARRAY); 301 } 302 303 /** 304 * Gets the first argument, if any, of this option. 305 * 306 * @param optionChar the character name of the option. 307 * @return Value of the argument if option is set, and has an argument, otherwise null. 308 */ 309 public String getOptionValue(final char optionChar) { 310 return getOptionValue(String.valueOf(optionChar)); 311 } 312 313 /** 314 * Gets the argument, if any, of an option. 315 * 316 * @param optionChar character name of the option 317 * @param defaultValue is the default value to be returned if the option is not specified. 318 * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}. 319 */ 320 public String getOptionValue(final char optionChar, final String defaultValue) { 321 return getOptionValue(String.valueOf(optionChar), () -> defaultValue); 322 } 323 324 /** 325 * Gets the argument, if any, of an option. 326 * 327 * @param optionChar character name of the option 328 * @param defaultValue is a supplier for the default value to be returned if the option is not specified. 329 * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}. 330 * @since 1.7.0 331 */ 332 public String getOptionValue(final char optionChar, final Supplier<String> defaultValue) { 333 return getOptionValue(String.valueOf(optionChar), defaultValue); 334 } 335 336 /** 337 * Gets the first argument, if any, of this option. 338 * 339 * @param option the option. 340 * @return Value of the argument if option is set, and has an argument, otherwise null. 341 * @since 1.5.0 342 */ 343 public String getOptionValue(final Option option) { 344 final String[] values = getOptionValues(option); 345 return values == null ? null : values[0]; 346 } 347 348 /** 349 * Gets the first argument, if any, of an option. 350 * 351 * @param option the option. 352 * @param defaultValue is the default value to be returned if the option is not specified. 353 * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}. 354 * @since 1.5.0 355 */ 356 public String getOptionValue(final Option option, final String defaultValue) { 357 return getOptionValue(option, () -> defaultValue); 358 } 359 360 /** 361 * Gets the first argument, if any, of an option. 362 * 363 * @param option the option. 364 * @param defaultValue is a supplier for the default value to be returned if the option is not specified. 365 * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}. 366 * @since 1.7.0 367 */ 368 public String getOptionValue(final Option option, final Supplier<String> defaultValue) { 369 final String answer = getOptionValue(option); 370 return answer != null ? answer : get(defaultValue); 371 } 372 373 /** 374 * Gets the first argument, if any, of this option group. 375 * 376 * @param optionGroup the option group. 377 * @return Value of the argument if option group is selected, and has an argument, otherwise null. 378 * @since 1.9.0 379 */ 380 public String getOptionValue(final OptionGroup optionGroup) { 381 final String[] values = getOptionValues(optionGroup); 382 return values == null ? null : values[0]; 383 } 384 385 /** 386 * Gets the first argument, if any, of an option group. 387 * 388 * @param optionGroup the option group. 389 * @param defaultValue is the default value to be returned if the option group is not selected. 390 * @return Value of the argument if option group is selected, and has an argument, otherwise {@code defaultValue}. 391 * @since 1.9.0 392 */ 393 public String getOptionValue(final OptionGroup optionGroup, final String defaultValue) { 394 return getOptionValue(optionGroup, () -> defaultValue); 395 } 396 397 /** 398 * Gets the first argument, if any, of an option group. 399 * 400 * @param optionGroup the option group. 401 * @param defaultValue is a supplier for the default value to be returned if the option group is not selected. 402 * @return Value of the argument if option group is selected, and has an argument, otherwise {@code defaultValue}. 403 * @since 1.9.0 404 */ 405 public String getOptionValue(final OptionGroup optionGroup, final Supplier<String> defaultValue) { 406 final String answer = getOptionValue(optionGroup); 407 return answer != null ? answer : get(defaultValue); 408 } 409 410 /** 411 * Gets the first argument, if any, of this option. 412 * 413 * @param optionName the name of the option. 414 * @return Value of the argument if option is set, and has an argument, otherwise null. 415 */ 416 public String getOptionValue(final String optionName) { 417 return getOptionValue(resolveOption(optionName)); 418 } 419 420 /** 421 * Gets the first argument, if any, of an option. 422 * 423 * @param optionName name of the option. 424 * @param defaultValue is the default value to be returned if the option is not specified. 425 * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}. 426 */ 427 public String getOptionValue(final String optionName, final String defaultValue) { 428 return getOptionValue(resolveOption(optionName), () -> defaultValue); 429 } 430 431 /** 432 * Gets the first argument, if any, of an option. 433 * 434 * @param optionName name of the option. 435 * @param defaultValue is a supplier for the default value to be returned if the option is not specified. 436 * @return Value of the argument if option is set, and has an argument, otherwise {@code defaultValue}. 437 * @since 1.7.0 438 */ 439 public String getOptionValue(final String optionName, final Supplier<String> defaultValue) { 440 return getOptionValue(resolveOption(optionName), defaultValue); 441 } 442 443 /** 444 * Gets the array of values, if any, of an option. 445 * 446 * @param optionChar character name of the option. 447 * @return Values of the argument if option is set, and has an argument, otherwise null. 448 */ 449 public String[] getOptionValues(final char optionChar) { 450 return getOptionValues(String.valueOf(optionChar)); 451 } 452 453 /** 454 * Gets the array of values, if any, of an option. 455 * 456 * @param option the option. 457 * @return Values of the argument if option is set, and has an argument, otherwise null. 458 * @since 1.5.0 459 */ 460 public String[] getOptionValues(final Option option) { 461 if (option == null) { 462 return null; 463 } 464 final List<String> values = new ArrayList<>(); 465 for (final Option processedOption : options) { 466 if (processedOption.equals(option)) { 467 if (option.isDeprecated()) { 468 handleDeprecated(option); 469 } 470 values.addAll(processedOption.getValuesList()); 471 } 472 } 473 return values.isEmpty() ? null : values.toArray(Util.EMPTY_STRING_ARRAY); 474 } 475 476 /** 477 * Gets the array of values, if any, of an option group. 478 * 479 * @param optionGroup the option group. 480 * @return Values of the argument if option group is selected, and has an argument, otherwise null. 481 * @since 1.9.0 482 */ 483 public String[] getOptionValues(final OptionGroup optionGroup) { 484 if (optionGroup == null || !optionGroup.isSelected()) { 485 return null; 486 } 487 return getOptionValues(optionGroup.getSelected()); 488 } 489 490 /** 491 * Gets the array of values, if any, of an option. 492 * 493 * @param optionName string name of the option. 494 * @return Values of the argument if option is set, and has an argument, otherwise null. 495 */ 496 public String[] getOptionValues(final String optionName) { 497 return getOptionValues(resolveOption(optionName)); 498 } 499 500 /** 501 * Gets a version of this {@code Option} converted to a particular type. 502 * 503 * @param optionChar the name of the option. 504 * @param <T> The return type for the method. 505 * @return the value parsed into a particular object or null if the option is not set. 506 * @throws ParseException if there are problems turning the option value into the desired type 507 * @see PatternOptionBuilder 508 * @since 1.5.0 509 */ 510 public <T> T getParsedOptionValue(final char optionChar) throws ParseException { 511 return getParsedOptionValue(String.valueOf(optionChar)); 512 } 513 514 /** 515 * Gets a version of this {@code Option} converted to a particular type. 516 * 517 * @param optionChar the name of the option. 518 * @param defaultValue the default value to return if opt is not set. 519 * @param <T> The return type for the method. 520 * @return the value parsed into a particular object or the defaultValue if the option is not set. 521 * @throws ParseException if there are problems turning the option value into the desired type 522 * @see PatternOptionBuilder 523 * @since 1.7.0 524 */ 525 public <T> T getParsedOptionValue(final char optionChar, final Supplier<T> defaultValue) throws ParseException { 526 return getParsedOptionValue(String.valueOf(optionChar), defaultValue); 527 } 528 529 /** 530 * Gets a version of this {@code Option} converted to a particular type. 531 * 532 * @param optionChar the name of the option. 533 * @param defaultValue the default value to return if opt is not set. 534 * @param <T> The return type for the method. 535 * @return the value parsed into a particular object or the defaultValue if the option is not set. 536 * @throws ParseException if there are problems turning the option value into the desired type 537 * @see PatternOptionBuilder 538 * @since 1.7.0 539 */ 540 public <T> T getParsedOptionValue(final char optionChar, final T defaultValue) throws ParseException { 541 return getParsedOptionValue(String.valueOf(optionChar), defaultValue); 542 } 543 544 /** 545 * Gets a version of this {@code Option} converted to a particular type. 546 * 547 * @param option the option. 548 * @param <T> The return type for the method. 549 * @return the value parsed into a particular object or null if the option is not set. 550 * @throws ParseException if there are problems turning the option value into the desired type 551 * @see PatternOptionBuilder 552 * @since 1.5.0 553 */ 554 public <T> T getParsedOptionValue(final Option option) throws ParseException { 555 return getParsedOptionValue(option, () -> null); 556 } 557 558 /** 559 * Gets a version of this {@code Option} converted to a particular type. 560 * 561 * @param option the option. 562 * @param defaultValue the default value to return if opt is not set. 563 * @param <T> The return type for the method. 564 * @return the value parsed into a particular object or the defaultValue if the option is not set. 565 * @throws ParseException if there are problems turning the option value into the desired type 566 * @see PatternOptionBuilder 567 * @since 1.7.0 568 */ 569 @SuppressWarnings("unchecked") 570 public <T> T getParsedOptionValue(final Option option, final Supplier<T> defaultValue) throws ParseException { 571 if (option == null) { 572 return get(defaultValue); 573 } 574 final String res = getOptionValue(option); 575 try { 576 if (res == null) { 577 return get(defaultValue); 578 } 579 return (T) option.getConverter().apply(res); 580 } catch (final Exception e) { 581 throw ParseException.wrap(e); 582 } 583 } 584 585 /** 586 * Gets a version of this {@code Option} converted to a particular type. 587 * 588 * @param option the option. 589 * @param defaultValue the default value to return if opt is not set. 590 * @param <T> The return type for the method. 591 * @return the value parsed into a particular object or the defaultValue if the option is not set. 592 * @throws ParseException if there are problems turning the option value into the desired type 593 * @see PatternOptionBuilder 594 * @since 1.7.0 595 */ 596 public <T> T getParsedOptionValue(final Option option, final T defaultValue) throws ParseException { 597 return getParsedOptionValue(option, () -> defaultValue); 598 } 599 600 /** 601 * Gets a version of this {@code OptionGroup} converted to a particular type. 602 * 603 * @param optionGroup the option group. 604 * @param <T> The return type for the method. 605 * @return the value parsed into a particular object or null if no option in the OptionGroup is set. 606 * @throws ParseException if there are problems turning the selected option value into the desired type 607 * @see PatternOptionBuilder 608 * @since 1.9.0 609 */ 610 public <T> T getParsedOptionValue(final OptionGroup optionGroup) throws ParseException { 611 return getParsedOptionValue(optionGroup, () -> null); 612 } 613 614 /** 615 * Gets a version of this {@code OptionGroup} converted to a particular type. 616 * 617 * @param optionGroup the option group. 618 * @param defaultValue the default value to return if opt is not set. 619 * @param <T> The return type for the method. 620 * @return the value parsed into a particular object or the defaultValue if no option in the OptionGroup is set. 621 * @throws ParseException if there are problems turning the selected option value into the desired type 622 * @see PatternOptionBuilder 623 * @since 1.9.0 624 */ 625 public <T> T getParsedOptionValue(final OptionGroup optionGroup, final Supplier<T> defaultValue) throws ParseException { 626 if (optionGroup == null || !optionGroup.isSelected()) { 627 return get(defaultValue); 628 } 629 return getParsedOptionValue(optionGroup.getSelected(), defaultValue); 630 } 631 632 /** 633 * Gets a version of this {@code OptionGroup} converted to a particular type. 634 * 635 * @param optionGroup the option group. 636 * @param defaultValue the default value to return if an option is not selected. 637 * @param <T> The return type for the method. 638 * @return the value parsed into a particular object or the defaultValue if no option in the OptionGroup is set. 639 * @throws ParseException if there are problems turning the option value into the desired type 640 * @see PatternOptionBuilder 641 * @since 1.9.0 642 */ 643 public <T> T getParsedOptionValue(final OptionGroup optionGroup, final T defaultValue) throws ParseException { 644 return getParsedOptionValue(optionGroup, () -> defaultValue); 645 } 646 647 /** 648 * Gets a version of this {@code Option} converted to a particular type. 649 * 650 * @param optionName the name of the option. 651 * @param <T> The return type for the method. 652 * @return the value parsed into a particular object or null if the option is not set. 653 * @throws ParseException if there are problems turning the option value into the desired type 654 * @see PatternOptionBuilder 655 * @since 1.2 656 */ 657 public <T> T getParsedOptionValue(final String optionName) throws ParseException { 658 return getParsedOptionValue(resolveOption(optionName)); 659 } 660 661 /** 662 * Gets a version of this {@code Option} converted to a particular type. 663 * 664 * @param optionName the name of the option. 665 * @param defaultValue the default value to return if opt is not set. 666 * @param <T> The return type for the method. 667 * @return the value parsed into a particular object or the defaultValue if the option is not set. 668 * @throws ParseException if there are problems turning the option value into the desired type 669 * @see PatternOptionBuilder 670 * @since 1.7.0 671 */ 672 public <T> T getParsedOptionValue(final String optionName, final Supplier<T> defaultValue) throws ParseException { 673 return getParsedOptionValue(resolveOption(optionName), defaultValue); 674 } 675 676 /** 677 * Gets a version of this {@code Option} converted to a particular type. 678 * 679 * @param optionName the name of the option. 680 * @param defaultValue the default value to return if opt is not set. 681 * @param <T> The return type for the method. 682 * @return the value parsed into a particular object or the defaultValue if the option is not set. 683 * @throws ParseException if there are problems turning the option value into the desired type 684 * @see PatternOptionBuilder 685 * @since 1.7.0 686 */ 687 public <T> T getParsedOptionValue(final String optionName, final T defaultValue) throws ParseException { 688 return getParsedOptionValue(resolveOption(optionName), defaultValue); 689 } 690 691 /** 692 * Gets a version of this {@code Option} converted to an array of a particular type. 693 * 694 * @param optionChar the name of the option. 695 * @param <T> The array type for the return value. 696 * @return the values parsed into an array of objects or null if the option is not set. 697 * @throws ParseException if there are problems turning the option value into the desired type 698 * @see PatternOptionBuilder 699 * @since 1.10.0 700 */ 701 public <T> T[] getParsedOptionValues(final char optionChar) throws ParseException { 702 return getParsedOptionValues(String.valueOf(optionChar)); 703 } 704 705 /** 706 * Gets a version of this {@code Option} converted to an array of a particular type. 707 * 708 * @param optionChar the name of the option. 709 * @param defaultValue the default value to return if opt is not set. 710 * @param <T> The array type for the return value. 711 * @return the values parsed into an array of objects or the defaultValue if the option is not set. 712 * @throws ParseException if there are problems turning the option value into the desired type 713 * @see PatternOptionBuilder 714 * @since 1.10.0 715 */ 716 public <T> T[] getParsedOptionValues(final char optionChar, final Supplier<T[]> defaultValue) throws ParseException { 717 return getParsedOptionValues(String.valueOf(optionChar), defaultValue); 718 } 719 720 /** 721 * Gets a version of this {@code Option} converted to an array of a particular type. 722 * 723 * @param optionChar the name of the option. 724 * @param defaultValue the default value to return if opt is not set. 725 * @param <T> The array type for the return value. 726 * @return the values parsed into an array of objects or the defaultValue if the option is not set. 727 * @throws ParseException if there are problems turning the option value into the desired type 728 * @see PatternOptionBuilder 729 * @since 1.10.0 730 */ 731 public <T> T[] getParsedOptionValues(final char optionChar, final T[] defaultValue) throws ParseException { 732 return getParsedOptionValues(String.valueOf(optionChar), defaultValue); 733 } 734 735 /** 736 * Gets a version of this {@code Option} converted to an array of a particular type. 737 * 738 * @param option the option. 739 * @param <T> The array type for the return value. 740 * @return the values parsed into an array of objects or null if the option is not set. 741 * @throws ParseException if there are problems turning the option value into the desired type 742 * @see PatternOptionBuilder 743 * @since 1.10.0 744 */ 745 public <T> T[] getParsedOptionValues(final Option option) throws ParseException { 746 return getParsedOptionValues(option, () -> null); 747 } 748 749 /** 750 * Gets a version of this {@code Option} converted to an array of a particular type. 751 * 752 * @param option the option. 753 * @param defaultValue the default value to return if opt is not set. 754 * @param <T> The array type for the return value. 755 * @return the values parsed into an array of objects or the defaultValue if the option is not set. 756 * @throws ParseException if there are problems turning the option value into the desired type 757 * @see PatternOptionBuilder 758 * @since 1.10.0 759 */ 760 @SuppressWarnings("unchecked") 761 public <T> T[] getParsedOptionValues(final Option option, final Supplier<T[]> defaultValue) throws ParseException { 762 if (option == null) { 763 return get(defaultValue); 764 } 765 final Class<? extends T> clazz = (Class<? extends T>) option.getType(); 766 final String[] values = getOptionValues(option); 767 if (values == null) { 768 return get(defaultValue); 769 } 770 final T[] result = (T[]) Array.newInstance(clazz, values.length); 771 try { 772 for (int i = 0; i < values.length; i++) { 773 result[i] = clazz.cast(option.getConverter().apply(values[i])); 774 } 775 return result; 776 } catch (final Exception t) { 777 throw ParseException.wrap(t); 778 } 779 } 780 781 /** 782 * Gets a version of this {@code Option} converted to an array of a particular type. 783 * 784 * @param option the option. 785 * @param defaultValue the default value to return if opt is not set. 786 * @param <T> The array type for the return value. 787 * @return the values parsed into an array of objects or the defaultValue if the option is not set. 788 * @throws ParseException if there are problems turning the option value into the desired type 789 * @see PatternOptionBuilder 790 * @since 1.10.0 791 */ 792 public <T> T[] getParsedOptionValues(final Option option, final T[] defaultValue) throws ParseException { 793 return getParsedOptionValues(option, () -> defaultValue); 794 } 795 796 /** 797 * Gets a version of this {@code OptionGroup} converted to an array of a particular type. 798 * 799 * @param optionGroup the option group. 800 * @param <T> The array type for the return value. 801 * @return the values parsed into an array of objects or null if no option in the OptionGroup is set. 802 * @throws ParseException if there are problems turning the selected option value into the desired type 803 * @see PatternOptionBuilder 804 * @since 1.10.0 805 */ 806 public <T> T[] getParsedOptionValues(final OptionGroup optionGroup) throws ParseException { 807 return getParsedOptionValues(optionGroup, () -> null); 808 } 809 810 /** 811 * Gets a version of this {@code OptionGroup} converted to an array of a particular type. 812 * 813 * @param optionGroup the option group. 814 * @param defaultValue the default value to return if opt is not set. 815 * @param <T> The array type for the return value. 816 * @return the values parsed into an array of objects or null if no option in the OptionGroup is set. 817 * @throws ParseException if there are problems turning the selected option value into the desired type 818 * @see PatternOptionBuilder 819 * @since 1.10.0 820 */ 821 public <T> T[] getParsedOptionValues(final OptionGroup optionGroup, final Supplier<T[]> defaultValue) throws ParseException { 822 if (optionGroup == null || !optionGroup.isSelected()) { 823 return get(defaultValue); 824 } 825 return getParsedOptionValues(optionGroup.getSelected(), defaultValue); 826 } 827 828 /** 829 * Gets a version of this {@code OptionGroup} converted to an array of a particular type. 830 * 831 * @param optionGroup the option group. 832 * @param defaultValue the default value to return if an option is not selected. 833 * @param <T> The array type for the return value. 834 * @return the values parsed into an array of objects or null if no option in the OptionGroup is set. 835 * @throws ParseException if there are problems turning the option value into the desired type 836 * @see PatternOptionBuilder 837 * @since 1.10.0 838 */ 839 public <T> T[] getParsedOptionValues(final OptionGroup optionGroup, final T[] defaultValue) throws ParseException { 840 return getParsedOptionValues(optionGroup, () -> defaultValue); 841 } 842 843 /** 844 * Gets a version of this {@code Option} converted to an array of a particular type. 845 * 846 * @param optionName the name of the option. 847 * @param <T> The array type for the return value. 848 * @return the values parsed into an array of objects or null if the option is not set. 849 * @throws ParseException if there are problems turning the option value into the desired type 850 * @see PatternOptionBuilder 851 * @since 1.10.0 852 */ 853 public <T> T[] getParsedOptionValues(final String optionName) throws ParseException { 854 return getParsedOptionValues(resolveOption(optionName)); 855 } 856 857 /** 858 * Gets a version of this {@code Option} converted to an array of a particular type. 859 * 860 * @param optionName the name of the option. 861 * @param defaultValue the default value to return if opt is not set. 862 * @param <T> The array type for the return value. 863 * @return the values parsed into an array of objects or defaultValues if the option is not set. 864 * @throws ParseException if there are problems turning the option value into the desired type 865 * @see PatternOptionBuilder 866 * @since 1.10.0 867 */ 868 public <T> T[] getParsedOptionValues(final String optionName, final Supplier<T[]> defaultValue) throws ParseException { 869 return getParsedOptionValues(resolveOption(optionName), defaultValue); 870 } 871 872 /** 873 * Gets a version of this {@code Option} converted to an array of a particular type. 874 * 875 * @param optionName the name of the option. 876 * @param defaultValue the default value to return if opt is not set. 877 * @param <T> The array type for the return value. 878 * @return the values parsed into an array of objects or defaultValues if the option is not set. 879 * @throws ParseException if there are problems turning the option value into the desired type 880 * @see PatternOptionBuilder 881 * @since 1.10.0 882 */ 883 public <T> T[] getParsedOptionValues(final String optionName, final T[] defaultValue) throws ParseException { 884 return getParsedOptionValues(resolveOption(optionName), defaultValue); 885 } 886 887 /** 888 * Handles deprecated options. 889 * 890 * @param option a deprecated option. 891 */ 892 private void handleDeprecated(final Option option) { 893 if (deprecatedHandler != null) { 894 deprecatedHandler.accept(option); 895 } 896 } 897 898 /** 899 * jkeyes - commented out until it is implemented properly 900 * <p> 901 * Dump state, suitable for debugging. 902 * </p> 903 * 904 * @return Stringified form of this object. 905 */ 906 907 /* 908 * public String toString() { StringBuilder buf = new StringBuilder(); 909 * 910 * buf.append("[ CommandLine: [ options: "); buf.append(options.toString()); buf.append(" ] [ args: "); 911 * buf.append(args.toString()); buf.append(" ] ]"); 912 * 913 * return buf.toString(); } 914 */ 915 916 /** 917 * Tests to see if an option has been set. 918 * 919 * @param optionChar character name of the option. 920 * @return true if set, false if not. 921 */ 922 public boolean hasOption(final char optionChar) { 923 return hasOption(String.valueOf(optionChar)); 924 } 925 926 /** 927 * Tests to see if an option has been set. 928 * 929 * @param option the option to check. 930 * @return true if set, false if not. 931 * @since 1.5.0 932 */ 933 public boolean hasOption(final Option option) { 934 final boolean result = options.contains(option); 935 if (result && option.isDeprecated()) { 936 handleDeprecated(option); 937 } 938 return result; 939 } 940 941 /** 942 * Tests to see if an option has been set. 943 * 944 * @param optionGroup the option group to check. 945 * @return true if set, false if not. 946 * @since 1.9.0 947 */ 948 public boolean hasOption(final OptionGroup optionGroup) { 949 if (optionGroup == null || !optionGroup.isSelected()) { 950 return false; 951 } 952 return hasOption(optionGroup.getSelected()); 953 } 954 955 /** 956 * Tests to see if an option has been set. 957 * 958 * @param optionName Short name of the option. 959 * @return true if set, false if not. 960 */ 961 public boolean hasOption(final String optionName) { 962 return hasOption(resolveOption(optionName)); 963 } 964 965 /** 966 * Returns an iterator over the Option members of CommandLine. 967 * 968 * @return an {@code Iterator} over the processed {@link Option} members of this {@link CommandLine}. 969 */ 970 public Iterator<Option> iterator() { 971 return options.iterator(); 972 } 973 974 /** 975 * Parses a list of values as properties. All odd numbered values are property keys 976 * and even numbered values are property values. If there are an odd number of values 977 * the last value is assumed to be a boolean with a value of "true". 978 * @param props the properties to update. 979 * @param values the list of values to parse. 980 */ 981 private void processPropertiesFromValues(final Properties props, final List<String> values) { 982 for (int i = 0; i < values.size(); i += 2) { 983 if (i + 1 < values.size()) { 984 props.put(values.get(i), values.get(i + 1)); 985 } else { 986 props.put(values.get(i), "true"); 987 } 988 } 989 } 990 991 /** 992 * Retrieves the option object given the long or short option as a String 993 * 994 * @param optionName short or long name of the option, may be null. 995 * @return Canonicalized option. 996 */ 997 private Option resolveOption(final String optionName) { 998 final String actual = Util.stripLeadingHyphens(optionName); 999 if (actual != null) { 1000 for (final Option option : options) { 1001 if (actual.equals(option.getOpt()) || actual.equals(option.getLongOpt())) { 1002 return option; 1003 } 1004 } 1005 } 1006 return null; 1007 } 1008}