@@ -53,7 +53,24 @@ public class DefaultParser implements CommandLineParser
5353
5454 /** The required options and groups expected to be found when parsing the command line. */
5555 protected List expectedOpts ;
56-
56+
57+ /** Flag indicating if partial matching of long options is supported. */
58+ private boolean allowPartialMatching ;
59+
60+ /** Creates a new DefaultParser instance with partial matching enabled. */
61+ public DefaultParser () {
62+ this .allowPartialMatching = true ;
63+ }
64+
65+ /**
66+ * Create a new DefaultParser instance with the specified partial matching policy.
67+ *
68+ * @param allowPartialMatching if partial matching of long options shall be enabled
69+ */
70+ public DefaultParser (final boolean allowPartialMatching ) {
71+ this .allowPartialMatching = allowPartialMatching ;
72+ }
73+
5774 public CommandLine parse (final Options options , final String [] arguments ) throws ParseException
5875 {
5976 return parse (options , arguments , null );
@@ -329,7 +346,7 @@ private boolean isLongOption(final String token)
329346 final int pos = token .indexOf ("=" );
330347 final String t = pos == -1 ? token : token .substring (0 , pos );
331348
332- if (!options . getMatchingOptions (t ).isEmpty ())
349+ if (!getMatchingLongOptions (t ).isEmpty ())
333350 {
334351 // long or partial long options (--L, -L, --L=V, -L=V, --l, --l=V)
335352 return true ;
@@ -400,18 +417,19 @@ private void handleLongOption(final String token) throws ParseException
400417 */
401418 private void handleLongOptionWithoutEqual (final String token ) throws ParseException
402419 {
403- final List <String > matchingOpts = options . getMatchingOptions (token );
420+ final List <String > matchingOpts = getMatchingLongOptions (token );
404421 if (matchingOpts .isEmpty ())
405422 {
406423 handleUnknownToken (currentToken );
407424 }
408- else if (matchingOpts .size () > 1 )
425+ else if (matchingOpts .size () > 1 && ! options . hasLongOption ( token ) )
409426 {
410427 throw new AmbiguousOptionException (token , matchingOpts );
411428 }
412429 else
413430 {
414- handleOption (options .getOption (matchingOpts .get (0 )));
431+ final String key = options .hasLongOption (token ) ? token : matchingOpts .get (0 );
432+ handleOption (options .getOption (key ));
415433 }
416434 }
417435
@@ -433,18 +451,19 @@ private void handleLongOptionWithEqual(final String token) throws ParseException
433451
434452 final String opt = token .substring (0 , pos );
435453
436- final List <String > matchingOpts = options . getMatchingOptions (opt );
454+ final List <String > matchingOpts = getMatchingLongOptions (opt );
437455 if (matchingOpts .isEmpty ())
438456 {
439457 handleUnknownToken (currentToken );
440458 }
441- else if (matchingOpts .size () > 1 )
459+ else if (matchingOpts .size () > 1 && ! options . hasLongOption ( opt ) )
442460 {
443461 throw new AmbiguousOptionException (opt , matchingOpts );
444462 }
445463 else
446464 {
447- final Option option = options .getOption (matchingOpts .get (0 ));
465+ final String key = options .hasLongOption (opt ) ? opt : matchingOpts .get (0 );
466+ final Option option = options .getOption (key );
448467
449468 if (option .acceptsArg ())
450469 {
@@ -503,7 +522,7 @@ else if (pos == -1)
503522 {
504523 handleOption (options .getOption (t ));
505524 }
506- else if (!options . getMatchingOptions (t ).isEmpty ())
525+ else if (!getMatchingLongOptions (t ).isEmpty ())
507526 {
508527 // -L or -l
509528 handleLongOptionWithoutEqual (token );
@@ -652,6 +671,32 @@ private void updateRequiredOptions(final Option option) throws AlreadySelectedEx
652671 }
653672 }
654673
674+ /**
675+ * Returns a list of matching option strings for the given token, depending
676+ * on the selected partial matching policy.
677+ *
678+ * @param token the token (may contain leading dashes)
679+ * @return the list of matching option strings or an empty list if no matching option could be found
680+ */
681+ private List <String > getMatchingLongOptions (final String token )
682+ {
683+ if (allowPartialMatching )
684+ {
685+ return options .getMatchingOptions (token );
686+ }
687+ else
688+ {
689+ List <String > matches = new ArrayList <String >(1 );
690+ if (options .hasLongOption (token ))
691+ {
692+ Option option = options .getOption (token );
693+ matches .add (option .getLongOpt ());
694+ }
695+
696+ return matches ;
697+ }
698+ }
699+
655700 /**
656701 * Breaks <code>token</code> into its constituent parts
657702 * using the following algorithm.
0 commit comments