diff --git a/make/CompileJavaModules.gmk b/make/CompileJavaModules.gmk
index 7a2e397aa5d..058f9a58eb8 100644
--- a/make/CompileJavaModules.gmk
+++ b/make/CompileJavaModules.gmk
@@ -325,6 +325,10 @@ jdk.internal.le_COPY += .properties
################################################################################
+jdk.internal.opt_COPY += .properties
+
+################################################################################
+
jdk.jcmd_COPY += _options
################################################################################
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/AbstractOptionSpec.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/AbstractOptionSpec.java
index 0d39af447f7..f101a2aa19f 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/AbstractOptionSpec.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/AbstractOptionSpec.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -56,7 +56,6 @@
package jdk.internal.joptsimple;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
import static java.util.Collections.*;
@@ -70,22 +69,22 @@ import static jdk.internal.joptsimple.internal.Strings.*;
* @param represents the type of the arguments this option accepts
* @author Paul Holser
*/
-abstract class AbstractOptionSpec implements OptionSpec, OptionDescriptor {
- private final List options = new ArrayList();
+public abstract class AbstractOptionSpec implements OptionSpec, OptionDescriptor {
+ private final List options = new ArrayList<>();
private final String description;
private boolean forHelp;
- protected AbstractOptionSpec( String option ) {
+ AbstractOptionSpec( String option ) {
this( singletonList( option ), EMPTY );
}
- protected AbstractOptionSpec( Collection options, String description ) {
+ AbstractOptionSpec( List options, String description ) {
arrangeOptions( options );
this.description = description;
}
- public final Collection options() {
+ public final List options() {
return unmodifiableList( options );
}
@@ -119,12 +118,8 @@ abstract class AbstractOptionSpec implements OptionSpec, OptionDescriptor
protected V convertWith( ValueConverter converter, String argument ) {
try {
return Reflection.convertWith( converter, argument );
- }
- catch ( ReflectionException ex ) {
- throw new OptionArgumentConversionException( options(), argument, ex );
- }
- catch ( ValueConversionException ex ) {
- throw new OptionArgumentConversionException( options(), argument, ex );
+ } catch ( ReflectionException | ValueConversionException ex ) {
+ throw new OptionArgumentConversionException( this, argument, ex );
}
}
@@ -139,14 +134,14 @@ abstract class AbstractOptionSpec implements OptionSpec, OptionDescriptor
abstract void handleOption( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions,
String detectedArgument );
- private void arrangeOptions( Collection unarranged ) {
+ private void arrangeOptions( List unarranged ) {
if ( unarranged.size() == 1 ) {
options.addAll( unarranged );
return;
}
- List shortOptions = new ArrayList();
- List longOptions = new ArrayList();
+ List shortOptions = new ArrayList<>();
+ List longOptions = new ArrayList<>();
for ( String each : unarranged ) {
if ( each.length() == 1 )
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/AlternativeLongOptionSpec.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/AlternativeLongOptionSpec.java
index 12532c6b3bc..68bcd0ec7ea 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/AlternativeLongOptionSpec.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/AlternativeLongOptionSpec.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -55,26 +55,40 @@
package jdk.internal.joptsimple;
+import jdk.internal.joptsimple.internal.Messages;
+
+import java.util.Locale;
+
import static java.util.Collections.*;
import static jdk.internal.joptsimple.ParserRules.*;
/**
- * Represents the "-W" form of long option specification.
+ * Represents the {@code "-W"} form of long option specification.
*
* @author Paul Holser
*/
class AlternativeLongOptionSpec extends ArgumentAcceptingOptionSpec {
AlternativeLongOptionSpec() {
- super( singletonList( RESERVED_FOR_EXTENSIONS ), true, "Alternative form of long options" );
+ super( singletonList( RESERVED_FOR_EXTENSIONS ),
+ true,
+ Messages.message(
+ Locale.getDefault(),
+ "jdk.internal.joptsimple.HelpFormatterMessages",
+ AlternativeLongOptionSpec.class,
+ "description" ) );
- describedAs( "opt=value" );
+ describedAs( Messages.message(
+ Locale.getDefault(),
+ "jdk.internal.joptsimple.HelpFormatterMessages",
+ AlternativeLongOptionSpec.class,
+ "arg.description" ) );
}
@Override
protected void detectOptionArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions ) {
if ( !arguments.hasMore() )
- throw new OptionMissingRequiredArgumentException( options() );
+ throw new OptionMissingRequiredArgumentException( this );
arguments.treatNextAsLongOption();
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ArgumentAcceptingOptionSpec.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ArgumentAcceptingOptionSpec.java
index ffb083746e9..b3064afe6a0 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ArgumentAcceptingOptionSpec.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ArgumentAcceptingOptionSpec.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -56,13 +56,12 @@
package jdk.internal.joptsimple;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
import java.util.StringTokenizer;
import static java.util.Collections.*;
+import static java.util.Objects.*;
-import static jdk.internal.joptsimple.internal.Objects.*;
import static jdk.internal.joptsimple.internal.Reflection.*;
import static jdk.internal.joptsimple.internal.Strings.*;
@@ -88,12 +87,13 @@ import static jdk.internal.joptsimple.internal.Strings.*;
public abstract class ArgumentAcceptingOptionSpec extends AbstractOptionSpec {
private static final char NIL_VALUE_SEPARATOR = '\u0000';
- private boolean optionRequired;
private final boolean argumentRequired;
+ private final List defaultValues = new ArrayList<>();
+
+ private boolean optionRequired;
private ValueConverter converter;
private String argumentDescription = "";
private String valueSeparator = String.valueOf( NIL_VALUE_SEPARATOR );
- private final List defaultValues = new ArrayList();
ArgumentAcceptingOptionSpec( String option, boolean argumentRequired ) {
super( option );
@@ -101,7 +101,7 @@ public abstract class ArgumentAcceptingOptionSpec extends AbstractOptionSpec<
this.argumentRequired = argumentRequired;
}
- ArgumentAcceptingOptionSpec( Collection options, boolean argumentRequired, String description ) {
+ ArgumentAcceptingOptionSpec( List options, boolean argumentRequired, String description ) {
super( options, description );
this.argumentRequired = argumentRequired;
@@ -182,7 +182,7 @@ public abstract class ArgumentAcceptingOptionSpec extends AbstractOptionSpec<
*
*
*
- * Then {@code options.valuesOf( "z" )} would yield the list {@code [foo, bar, baz, fizz, buzz]}.
+ * Then options.valuesOf( "z" ) would yield the list {@code [foo, bar, baz, fizz, buzz]}.
*
* You cannot use Unicode U+0000 as the separator.
*
@@ -211,7 +211,7 @@ public abstract class ArgumentAcceptingOptionSpec extends AbstractOptionSpec<
*
*
*
- * Then {@code options.valuesOf( "z" )} would yield the list {@code [foo, bar, baz, fizz, buzz]}.
+ * Then options.valuesOf( "z" ) would yield the list {@code [foo, bar, baz, fizz, buzz]}.
*
* You cannot use Unicode U+0000 in the separator.
*
@@ -236,8 +236,9 @@ public abstract class ArgumentAcceptingOptionSpec extends AbstractOptionSpec<
* @throws NullPointerException if {@code value}, {@code values}, or any elements of {@code values} are
* {@code null}
*/
- @SuppressWarnings("unchecked")
- public ArgumentAcceptingOptionSpec defaultsTo( V value, V... values ) {
+ @SafeVarargs
+ @SuppressWarnings("varargs")
+ public final ArgumentAcceptingOptionSpec defaultsTo( V value, V... values ) {
addDefaultValue( value );
defaultsTo( values );
@@ -275,7 +276,7 @@ public abstract class ArgumentAcceptingOptionSpec extends AbstractOptionSpec<
}
private void addDefaultValue( V value ) {
- ensureNotNull( value );
+ requireNonNull( value );
defaultValues.add( value );
}
@@ -283,7 +284,7 @@ public abstract class ArgumentAcceptingOptionSpec extends AbstractOptionSpec<
final void handleOption( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions,
String detectedArgument ) {
- if ( isNullOrEmpty( detectedArgument ) )
+ if ( detectedArgument == null )
detectOptionArgument( parser, arguments, detectedOptions );
else
addArguments( detectedOptions, detectedArgument );
@@ -314,8 +315,7 @@ public abstract class ArgumentAcceptingOptionSpec extends AbstractOptionSpec<
while ( lexer.hasMoreTokens() )
convert( lexer.nextToken() );
return true;
- }
- catch ( OptionException ignored ) {
+ } catch ( OptionException ignored ) {
return false;
}
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ArgumentList.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ArgumentList.java
index e8cf157f99c..04af7965aea 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ArgumentList.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ArgumentList.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/BuiltinHelpFormatter.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/BuiltinHelpFormatter.java
index ba72af36f90..8e7fe5146ad 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/BuiltinHelpFormatter.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/BuiltinHelpFormatter.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -55,14 +55,9 @@
package jdk.internal.joptsimple;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
+import java.util.*;
+import jdk.internal.joptsimple.internal.Messages;
import jdk.internal.joptsimple.internal.Rows;
import jdk.internal.joptsimple.internal.Strings;
@@ -73,10 +68,17 @@ import static jdk.internal.joptsimple.internal.Strings.*;
/**
* A help formatter that allows configuration of overall row width and column separator width.
*
- * The formatter produces a two-column output. The left column is for the options, and the right column for their
+ *
The formatter produces output in two sections: one for the options, and one for non-option arguments.
+ *
+ * The options section has two columns: the left column for the options, and the right column for their
* descriptions. The formatter will allow as much space as possible for the descriptions, by minimizing the option
* column's width, no greater than slightly less than half the overall desired width.
*
+ * The non-option arguments section is one column, occupying as much width as it can.
+ *
+ * Subclasses are free to override bits of this implementation as they see fit. Inspect the code
+ * carefully to understand the flow of control that this implementation guarantees.
+ *
* @author Paul Holser
*/
public class BuiltinHelpFormatter implements HelpFormatter {
@@ -102,7 +104,20 @@ public class BuiltinHelpFormatter implements HelpFormatter {
optionRows = new Rows( desiredOverallWidth, desiredColumnSeparatorWidth );
}
+ /**
+ * {@inheritDoc}
+ *
+ * This implementation:
+ *
+ * - Sorts the given descriptors by their first elements of {@link OptionDescriptor#options()}
+ * - Passes the resulting sorted set to {@link #addRows(java.util.Collection)}
+ * - Returns the result of {@link #formattedHelpOutput()}
+ *
+ */
public String format( Map options ) {
+ optionRows.reset();
+ nonOptionRows.reset();
+
Comparator comparator =
new Comparator() {
public int compare( OptionDescriptor first, OptionDescriptor second ) {
@@ -110,7 +125,7 @@ public class BuiltinHelpFormatter implements HelpFormatter {
}
};
- Set sorted = new TreeSet( comparator );
+ Set sorted = new TreeSet<>( comparator );
sorted.addAll( options.values() );
addRows( sorted );
@@ -118,21 +133,102 @@ public class BuiltinHelpFormatter implements HelpFormatter {
return formattedHelpOutput();
}
- private String formattedHelpOutput() {
+ /**
+ * Adds a row of option help output in the left column, with empty space in the right column.
+ *
+ * @param single text to put in the left column
+ */
+ protected void addOptionRow( String single ) {
+ addOptionRow( single, "" );
+ }
+
+ /**
+ * Adds a row of option help output in the left and right columns.
+ *
+ * @param left text to put in the left column
+ * @param right text to put in the right column
+ */
+ protected void addOptionRow( String left, String right ) {
+ optionRows.add( left, right );
+ }
+
+ /**
+ * Adds a single row of non-option argument help.
+ *
+ * @param single single row of non-option argument help text
+ */
+ protected void addNonOptionRow( String single ) {
+ nonOptionRows.add( single, "" );
+ }
+
+ /**
+ * Resizes the columns of all the rows to be no wider than the widest element in that column.
+ */
+ protected void fitRowsToWidth() {
+ nonOptionRows.fitToWidth();
+ optionRows.fitToWidth();
+ }
+
+ /**
+ * Produces non-option argument help.
+ *
+ * @return non-option argument help
+ */
+ protected String nonOptionOutput() {
+ return nonOptionRows.render();
+ }
+
+ /**
+ * Produces help for options and their descriptions.
+ *
+ * @return option help
+ */
+ protected String optionOutput() {
+ return optionRows.render();
+ }
+
+ /**
+ * Produces help output for an entire set of options and non-option arguments.
+ *
+ * This implementation concatenates:
+ *
+ * - the result of {@link #nonOptionOutput()}
+ * - if there is non-option output, a line separator
+ * - the result of {@link #optionOutput()}
+ *
+ *
+ * @return help output for entire set of options and non-option arguments
+ */
+ protected String formattedHelpOutput() {
StringBuilder formatted = new StringBuilder();
- String nonOptionDisplay = nonOptionRows.render();
+ String nonOptionDisplay = nonOptionOutput();
if ( !Strings.isNullOrEmpty( nonOptionDisplay ) )
formatted.append( nonOptionDisplay ).append( LINE_SEPARATOR );
- formatted.append( optionRows.render() );
+ formatted.append( optionOutput() );
return formatted.toString();
}
- private void addRows( Collection extends OptionDescriptor> options ) {
+ /**
+ * Adds rows of help output for the given options.
+ *
+ * This implementation:
+ *
+ * - Calls {@link #addNonOptionsDescription(java.util.Collection)} with the options as the argument
+ * - If there are no options, calls {@link #addOptionRow(String)} with an argument that indicates
+ * that no options are specified.
+ * - Otherwise, calls {@link #addHeaders(java.util.Collection)} with the options as the argument,
+ * followed by {@link #addOptions(java.util.Collection)} with the options as the argument.
+ * - Calls {@link #fitRowsToWidth()}.
+ *
+ *
+ * @param options descriptors for the configured options of a parser
+ */
+ protected void addRows( Collection extends OptionDescriptor> options ) {
addNonOptionsDescription( options );
if ( options.isEmpty() )
- optionRows.add( "No options specified", "" );
+ addOptionRow( message( "no.options.specified" ) );
else {
addHeaders( options );
addOptions( options );
@@ -141,34 +237,87 @@ public class BuiltinHelpFormatter implements HelpFormatter {
fitRowsToWidth();
}
- private void addNonOptionsDescription( Collection extends OptionDescriptor> options ) {
+ /**
+ * Adds non-option arguments descriptions to the help output.
+ *
+ * This implementation:
+ *
+ * - {@linkplain #findAndRemoveNonOptionsSpec(java.util.Collection) Finds and removes the non-option
+ * arguments descriptor}
+ * - {@linkplain #shouldShowNonOptionArgumentDisplay(OptionDescriptor) Decides whether there is
+ * anything to show for non-option arguments}
+ * - If there is, {@linkplain #addNonOptionRow(String) adds a header row} and
+ * {@linkplain #addNonOptionRow(String) adds a}
+ * {@linkplain #createNonOptionArgumentsDisplay(OptionDescriptor) non-option arguments description}
+ *
+ *
+ * @param options descriptors for the configured options of a parser
+ */
+ protected void addNonOptionsDescription( Collection extends OptionDescriptor> options ) {
OptionDescriptor nonOptions = findAndRemoveNonOptionsSpec( options );
if ( shouldShowNonOptionArgumentDisplay( nonOptions ) ) {
- nonOptionRows.add( "Non-option arguments:", "" );
- nonOptionRows.add(createNonOptionArgumentsDisplay(nonOptions), "");
+ addNonOptionRow( message( "non.option.arguments.header" ) );
+ addNonOptionRow( createNonOptionArgumentsDisplay( nonOptions ) );
}
}
- private boolean shouldShowNonOptionArgumentDisplay( OptionDescriptor nonOptions ) {
- return !Strings.isNullOrEmpty( nonOptions.description() )
- || !Strings.isNullOrEmpty( nonOptions.argumentTypeIndicator() )
- || !Strings.isNullOrEmpty( nonOptions.argumentDescription() );
+ /**
+ * Decides whether or not to show a non-option arguments help.
+ *
+ * This implementation responds with {@code true} if the non-option descriptor has a non-{@code null},
+ * non-empty value for any of {@link OptionDescriptor#description()},
+ * {@link OptionDescriptor#argumentTypeIndicator()}, or {@link OptionDescriptor#argumentDescription()}.
+ *
+ * @param nonOptionDescriptor non-option argument descriptor
+ * @return {@code true} if non-options argument help should be shown
+ */
+ protected boolean shouldShowNonOptionArgumentDisplay( OptionDescriptor nonOptionDescriptor ) {
+ return !Strings.isNullOrEmpty( nonOptionDescriptor.description() )
+ || !Strings.isNullOrEmpty( nonOptionDescriptor.argumentTypeIndicator() )
+ || !Strings.isNullOrEmpty( nonOptionDescriptor.argumentDescription() );
}
- private String createNonOptionArgumentsDisplay(OptionDescriptor nonOptions) {
+ /**
+ * Creates a non-options argument help string.
+ *
+ * This implementation creates an empty string buffer and calls
+ * {@link #maybeAppendOptionInfo(StringBuilder, OptionDescriptor)}
+ * and {@link #maybeAppendNonOptionsDescription(StringBuilder, OptionDescriptor)}, passing them the
+ * buffer and the non-option arguments descriptor.
+ *
+ * @param nonOptionDescriptor non-option argument descriptor
+ * @return help string for non-options
+ */
+ protected String createNonOptionArgumentsDisplay( OptionDescriptor nonOptionDescriptor ) {
StringBuilder buffer = new StringBuilder();
- maybeAppendOptionInfo( buffer, nonOptions );
- maybeAppendNonOptionsDescription( buffer, nonOptions );
+ maybeAppendOptionInfo( buffer, nonOptionDescriptor );
+ maybeAppendNonOptionsDescription( buffer, nonOptionDescriptor );
return buffer.toString();
}
- private void maybeAppendNonOptionsDescription( StringBuilder buffer, OptionDescriptor nonOptions ) {
+ /**
+ * Appends help for the given non-option arguments descriptor to the given buffer.
+ *
+ * This implementation appends {@code " -- "} if the buffer has text in it and the non-option arguments
+ * descriptor has a {@link OptionDescriptor#description()}; followed by the
+ * {@link OptionDescriptor#description()}.
+ *
+ * @param buffer string buffer
+ * @param nonOptions non-option arguments descriptor
+ */
+ protected void maybeAppendNonOptionsDescription( StringBuilder buffer, OptionDescriptor nonOptions ) {
buffer.append( buffer.length() > 0 && !Strings.isNullOrEmpty( nonOptions.description() ) ? " -- " : "" )
.append( nonOptions.description() );
}
- private OptionDescriptor findAndRemoveNonOptionsSpec( Collection extends OptionDescriptor> options ) {
+ /**
+ * Finds the non-option arguments descriptor in the given collection, removes it, and returns it.
+ *
+ * @param options descriptors for the configured options of a parser
+ * @return the non-option arguments descriptor
+ */
+ protected OptionDescriptor findAndRemoveNonOptionsSpec( Collection extends OptionDescriptor> options ) {
for ( Iterator extends OptionDescriptor> it = options.iterator(); it.hasNext(); ) {
OptionDescriptor next = it.next();
if ( next.representsNonOptions() ) {
@@ -180,17 +329,32 @@ public class BuiltinHelpFormatter implements HelpFormatter {
throw new AssertionError( "no non-options argument spec" );
}
- private void addHeaders( Collection extends OptionDescriptor> options ) {
+ /**
+ * Adds help row headers for option help columns.
+ *
+ * This implementation uses the headers {@code "Option"} and {@code "Description"}. If the options contain
+ * a "required" option, the {@code "Option"} header looks like {@code "Option (* = required)}. Both headers
+ * are "underlined" using {@code "-"}.
+ *
+ * @param options descriptors for the configured options of a parser
+ */
+ protected void addHeaders( Collection extends OptionDescriptor> options ) {
if ( hasRequiredOption( options ) ) {
- optionRows.add("Option (* = required)", "Description");
- optionRows.add("---------------------", "-----------");
+ addOptionRow( message( "option.header.with.required.indicator" ), message( "description.header" ) );
+ addOptionRow( message( "option.divider.with.required.indicator" ), message( "description.divider" ) );
} else {
- optionRows.add("Option", "Description");
- optionRows.add("------", "-----------");
+ addOptionRow( message( "option.header" ), message( "description.header" ) );
+ addOptionRow( message( "option.divider" ), message( "description.divider" ) );
}
}
- private boolean hasRequiredOption( Collection extends OptionDescriptor> options ) {
+ /**
+ * Tells whether the given option descriptors contain a "required" option.
+ *
+ * @param options descriptors for the configured options of a parser
+ * @return {@code true} if at least one of the options is "required"
+ */
+ protected final boolean hasRequiredOption( Collection extends OptionDescriptor> options ) {
for ( OptionDescriptor each : options ) {
if ( each.isRequired() )
return true;
@@ -199,19 +363,46 @@ public class BuiltinHelpFormatter implements HelpFormatter {
return false;
}
- private void addOptions( Collection extends OptionDescriptor> options ) {
+ /**
+ * Adds help rows for the given options.
+ *
+ * This implementation loops over the given options, and for each, calls {@link #addOptionRow(String, String)}
+ * using the results of {@link #createOptionDisplay(OptionDescriptor)} and
+ * {@link #createDescriptionDisplay(OptionDescriptor)}, respectively, as arguments.
+ *
+ * @param options descriptors for the configured options of a parser
+ */
+ protected void addOptions( Collection extends OptionDescriptor> options ) {
for ( OptionDescriptor each : options ) {
if ( !each.representsNonOptions() )
- optionRows.add( createOptionDisplay( each ), createDescriptionDisplay( each ) );
+ addOptionRow( createOptionDisplay( each ), createDescriptionDisplay( each ) );
}
}
- private String createOptionDisplay( OptionDescriptor descriptor ) {
+ /**
+ * Creates a string for how the given option descriptor is to be represented in help.
+ *
+ * This implementation gives a string consisting of the concatenation of:
+ *
+ * - {@code "* "} for "required" options, otherwise {@code ""}
+ * - For each of the {@link OptionDescriptor#options()} of the descriptor, separated by {@code ", "}:
+ *
+ * - {@link #optionLeader(String)} of the option
+ * - the option
+ *
+ *
+ * - the result of {@link #maybeAppendOptionInfo(StringBuilder, OptionDescriptor)}
+ *
+ *
+ * @param descriptor a descriptor for a configured option of a parser
+ * @return help string
+ */
+ protected String createOptionDisplay( OptionDescriptor descriptor ) {
StringBuilder buffer = new StringBuilder( descriptor.isRequired() ? "* " : "" );
for ( Iterator i = descriptor.options().iterator(); i.hasNext(); ) {
String option = i.next();
- buffer.append( option.length() > 1 ? DOUBLE_HYPHEN : HYPHEN );
+ buffer.append( optionLeader( option ) );
buffer.append( option );
if ( i.hasNext() )
@@ -223,31 +414,105 @@ public class BuiltinHelpFormatter implements HelpFormatter {
return buffer.toString();
}
- private void maybeAppendOptionInfo( StringBuilder buffer, OptionDescriptor descriptor ) {
- String indicator = extractTypeIndicator( descriptor );
- String description = descriptor.argumentDescription();
- if ( indicator != null || !isNullOrEmpty( description ) )
- appendOptionHelp( buffer, indicator, description, descriptor.requiresArgument() );
+ /**
+ * Gives a string that represents the given option's "option leader" in help.
+ *
+ * This implementation answers with {@code "--"} for options of length greater than one; otherwise answers
+ * with {@code "-"}.
+ *
+ * @param option a string option
+ * @return an "option leader" string
+ */
+ protected String optionLeader( String option ) {
+ return option.length() > 1 ? DOUBLE_HYPHEN : HYPHEN;
}
- private String extractTypeIndicator( OptionDescriptor descriptor ) {
+ /**
+ * Appends additional info about the given option to the given buffer.
+ *
+ * This implementation:
+ *
+ * - calls {@link #extractTypeIndicator(OptionDescriptor)} for the descriptor
+ * - calls {@link jdk.internal.joptsimple.OptionDescriptor#argumentDescription()} for the descriptor
+ * - if either of the above is present, calls
+ * {@link #appendOptionHelp(StringBuilder, String, String, boolean)}
+ *
+ *
+ * @param buffer string buffer
+ * @param descriptor a descriptor for a configured option of a parser
+ */
+ protected void maybeAppendOptionInfo( StringBuilder buffer, OptionDescriptor descriptor ) {
+ String indicator = extractTypeIndicator( descriptor );
+ String description = descriptor.argumentDescription();
+ if ( descriptor.acceptsArguments()
+ || !isNullOrEmpty( description )
+ || descriptor.representsNonOptions() ) {
+
+ appendOptionHelp( buffer, indicator, description, descriptor.requiresArgument() );
+ }
+ }
+
+ /**
+ * Gives an indicator of the type of arguments of the option described by the given descriptor,
+ * for use in help.
+ *
+ * This implementation asks for the {@link OptionDescriptor#argumentTypeIndicator()} of the given
+ * descriptor, and if it is present and not {@code "java.lang.String"}, parses it as a fully qualified
+ * class name and returns the base name of that class; otherwise returns {@code "String"}.
+ *
+ * @param descriptor a descriptor for a configured option of a parser
+ * @return type indicator text
+ */
+ protected String extractTypeIndicator( OptionDescriptor descriptor ) {
String indicator = descriptor.argumentTypeIndicator();
if ( !isNullOrEmpty( indicator ) && !String.class.getName().equals( indicator ) )
return shortNameOf( indicator );
- return null;
+ return "String";
}
- private void appendOptionHelp( StringBuilder buffer, String typeIndicator, String description, boolean required ) {
+ /**
+ * Appends info about an option's argument to the given buffer.
+ *
+ * This implementation calls {@link #appendTypeIndicator(StringBuilder, String, String, char, char)} with
+ * the surrounding characters {@code '<'} and {@code '>'} for options with {@code required} arguments, and
+ * with the surrounding characters {@code '['} and {@code ']'} for options with optional arguments.
+ *
+ * @param buffer string buffer
+ * @param typeIndicator type indicator
+ * @param description type description
+ * @param required indicator of "required"-ness of the argument of the option
+ */
+ protected void appendOptionHelp( StringBuilder buffer, String typeIndicator, String description,
+ boolean required ) {
if ( required )
appendTypeIndicator( buffer, typeIndicator, description, '<', '>' );
else
appendTypeIndicator( buffer, typeIndicator, description, '[', ']' );
}
- private void appendTypeIndicator( StringBuilder buffer, String typeIndicator, String description,
- char start, char end ) {
+ /**
+ * Appends a type indicator for an option's argument to the given buffer.
+ *
+ * This implementation appends, in order:
+ *
+ * - {@code ' '}
+ * - {@code start}
+ * - the type indicator, if not {@code null}
+ * - if the description is present, then {@code ": "} plus the description if the type indicator is
+ * present; otherwise the description only
+ * - {@code end}
+ *
+ *
+ * @param buffer string buffer
+ * @param typeIndicator type indicator
+ * @param description type description
+ * @param start starting character
+ * @param end ending character
+ */
+ protected void appendTypeIndicator( StringBuilder buffer, String typeIndicator, String description,
+ char start, char end ) {
buffer.append( ' ' ).append( start );
if ( typeIndicator != null )
buffer.append( typeIndicator );
@@ -262,21 +527,69 @@ public class BuiltinHelpFormatter implements HelpFormatter {
buffer.append( end );
}
- private String createDescriptionDisplay( OptionDescriptor descriptor ) {
+ /**
+ * Gives a string representing a description of the option with the given descriptor.
+ *
+ * This implementation:
+ *
+ * - Asks for the descriptor's {@link OptionDescriptor#defaultValues()}
+ * - If they're not present, answers the descriptor's {@link OptionDescriptor#description()}.
+ * - If they are present, concatenates and returns:
+ *
+ * - the descriptor's {@link OptionDescriptor#description()}
+ * - {@code ' '}
+ * - {@code "default: "} plus the result of {@link #createDefaultValuesDisplay(java.util.List)},
+ * surrounded by parentheses
+ *
+ *
+ *
+ *
+ * @param descriptor a descriptor for a configured option of a parser
+ * @return display text for the option's description
+ */
+ protected String createDescriptionDisplay( OptionDescriptor descriptor ) {
List> defaultValues = descriptor.defaultValues();
if ( defaultValues.isEmpty() )
return descriptor.description();
String defaultValuesDisplay = createDefaultValuesDisplay( defaultValues );
- return ( descriptor.description() + ' ' + surround( "default: " + defaultValuesDisplay, '(', ')' ) ).trim();
+ return ( descriptor.description()
+ + ' '
+ + surround( message( "default.value.header" ) + ' ' + defaultValuesDisplay, '(', ')' )
+ ).trim();
}
- private String createDefaultValuesDisplay( List> defaultValues ) {
+ /**
+ * Gives a display string for the default values of an option's argument.
+ *
+ * This implementation gives the {@link Object#toString()} of the first value if there is only one value,
+ * otherwise gives the {@link Object#toString()} of the whole list.
+ *
+ * @param defaultValues some default values for a given option's argument
+ * @return a display string for those default values
+ */
+ protected String createDefaultValuesDisplay( List> defaultValues ) {
return defaultValues.size() == 1 ? defaultValues.get( 0 ).toString() : defaultValues.toString();
}
- private void fitRowsToWidth() {
- nonOptionRows.fitToWidth();
- optionRows.fitToWidth();
+ /**
+ * Looks up and gives a resource bundle message.
+ *
+ * This implementation looks in the bundle {@code "jdk.internal.joptsimple.HelpFormatterMessages"} in the default
+ * locale, using a key that is the concatenation of this class's fully qualified name, {@code '.'},
+ * and the given key suffix, formats the corresponding value using the given arguments, and returns
+ * the result.
+ *
+ * @param keySuffix suffix to use when looking up the bundle message
+ * @param args arguments to fill in the message template with
+ * @return a formatted localized message
+ */
+ protected String message( String keySuffix, Object... args ) {
+ return Messages.message(
+ Locale.getDefault(),
+ "jdk.internal.joptsimple.HelpFormatterMessages",
+ BuiltinHelpFormatter.class,
+ keySuffix,
+ args );
}
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ExceptionMessages.properties b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ExceptionMessages.properties
new file mode 100644
index 00000000000..c12fc25bb33
--- /dev/null
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ExceptionMessages.properties
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+jdk.internal.joptsimple.IllegalOptionSpecificationException.message = {0} is not a legal option character
+jdk.internal.joptsimple.MissingRequiredOptionsException.message = Missing required option(s) {0}
+jdk.internal.joptsimple.MultipleArgumentsForOptionException.message = Found multiple arguments for option {0}, but you asked for only one
+jdk.internal.joptsimple.OptionArgumentConversionException.message = Cannot parse argument ''{0}'' of option {1}
+jdk.internal.joptsimple.OptionMissingRequiredArgumentException.message = Option {0} requires an argument
+jdk.internal.joptsimple.UnavailableOptionException.message = Option(s) {0} are unavailable given other options on the command line
+jdk.internal.joptsimple.UnconfiguredOptionException.message = Option(s) {0} not configured on this parser
+jdk.internal.joptsimple.UnrecognizedOptionException.message = {0} is not a recognized option
+jdk.internal.joptsimple.util.DateConverter.without.pattern.message = Value [{0}] does not match date/time pattern
+jdk.internal.joptsimple.util.DateConverter.with.pattern.message = Value [{0}] does not match date/time pattern [{1}]
+jdk.internal.joptsimple.util.RegexMatcher.message = Value [{0}] did not match regex [{1}]
+jdk.internal.joptsimple.util.EnumConverter.message = Value [{0}] is not one of [{1}]
+jdk.internal.joptsimple.util.PathConverter.file.existing.message = File [{0}] does not exist
+jdk.internal.joptsimple.util.PathConverter.directory.existing.message = Directory [{0}] does not exist
+jdk.internal.joptsimple.util.PathConverter.file.not.existing.message = File [{0}] does already exist
+jdk.internal.joptsimple.util.PathConverter.file.overwritable.message = File [{0}] is not overwritable
+jdk.internal.joptsimple.util.PathConverter.file.readable.message = File [{0}] is not readable
+jdk.internal.joptsimple.util.PathConverter.file.writable.message = File [{0}] is not writable
+jdk.internal.joptsimple.util.InetAddressConverter.message = Cannot convert value [{0}] into an InetAddress
\ No newline at end of file
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/HelpFormatter.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/HelpFormatter.java
index e5dd316f1d7..f3e111158e8 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/HelpFormatter.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/HelpFormatter.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/HelpFormatterMessages.properties b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/HelpFormatterMessages.properties
new file mode 100644
index 00000000000..31f060029aa
--- /dev/null
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/HelpFormatterMessages.properties
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+jdk.internal.joptsimple.BuiltinHelpFormatter.no.options.specified = No options specified
+jdk.internal.joptsimple.BuiltinHelpFormatter.non.option.arguments.header = Non-option arguments:
+jdk.internal.joptsimple.BuiltinHelpFormatter.option.header.with.required.indicator = Option (* = required)
+jdk.internal.joptsimple.BuiltinHelpFormatter.option.divider.with.required.indicator = ---------------------
+jdk.internal.joptsimple.BuiltinHelpFormatter.option.header = Option
+jdk.internal.joptsimple.BuiltinHelpFormatter.option.divider = ------
+jdk.internal.joptsimple.BuiltinHelpFormatter.description.header = Description
+jdk.internal.joptsimple.BuiltinHelpFormatter.description.divider = -----------
+jdk.internal.joptsimple.BuiltinHelpFormatter.default.value.header = default:
+jdk.internal.joptsimple.AlternativeLongOptionSpec.description = Alternative form of long options
+jdk.internal.joptsimple.AlternativeLongOptionSpec.arg.description = opt=value
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/IllegalOptionSpecificationException.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/IllegalOptionSpecificationException.java
index 8696bf1a150..acf554cb8c9 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/IllegalOptionSpecificationException.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/IllegalOptionSpecificationException.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -70,7 +70,7 @@ class IllegalOptionSpecificationException extends OptionException {
}
@Override
- public String getMessage() {
- return singleOptionMessage() + " is not a legal option character";
+ Object[] messageArguments() {
+ return new Object[] { singleOptionString() };
}
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/MissingRequiredOptionException.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/MissingRequiredOptionsException.java
similarity index 83%
rename from src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/MissingRequiredOptionException.java
rename to src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/MissingRequiredOptionsException.java
index 2c997e2052c..44a5a2e9453 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/MissingRequiredOptionException.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/MissingRequiredOptionsException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -55,22 +55,22 @@
package jdk.internal.joptsimple;
-import java.util.Collection;
+import java.util.List;
/**
- * Thrown when an option is marked as required, but not specified on the command line.
+ * Thrown when options marked as required are not specified on the command line.
*
* @author Emils Solmanis
*/
-class MissingRequiredOptionException extends OptionException {
+class MissingRequiredOptionsException extends OptionException {
private static final long serialVersionUID = -1L;
- protected MissingRequiredOptionException( Collection options ) {
- super( options );
+ protected MissingRequiredOptionsException( List extends OptionSpec>> missingRequiredOptions ) {
+ super( missingRequiredOptions );
}
@Override
- public String getMessage() {
- return "Missing required option(s) " + multipleOptionMessage();
+ Object[] messageArguments() {
+ return new Object[] { multipleOptionString() };
}
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/MultipleArgumentsForOptionException.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/MultipleArgumentsForOptionException.java
index e96cea33918..39c07fe3201 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/MultipleArgumentsForOptionException.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/MultipleArgumentsForOptionException.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -55,7 +55,7 @@
package jdk.internal.joptsimple;
-import java.util.Collection;
+import static java.util.Collections.*;
/**
* Thrown when asking an {@link OptionSet} for a single argument of an option when many have been specified.
@@ -65,12 +65,12 @@ import java.util.Collection;
class MultipleArgumentsForOptionException extends OptionException {
private static final long serialVersionUID = -1L;
- MultipleArgumentsForOptionException( Collection options ) {
- super( options );
+ MultipleArgumentsForOptionException( OptionSpec> options ) {
+ super( singleton( options ) );
}
@Override
- public String getMessage() {
- return "Found multiple arguments for option " + multipleOptionMessage() + ", but you asked for only one";
+ Object[] messageArguments() {
+ return new Object[] { singleOptionString() };
}
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/NoArgumentOptionSpec.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/NoArgumentOptionSpec.java
index 9647ff1bad2..c2ee67f7536 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/NoArgumentOptionSpec.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/NoArgumentOptionSpec.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -55,7 +55,6 @@
package jdk.internal.joptsimple;
-import java.util.Collection;
import java.util.List;
import static java.util.Collections.*;
@@ -70,7 +69,7 @@ class NoArgumentOptionSpec extends AbstractOptionSpec {
this( singletonList( option ), "" );
}
- NoArgumentOptionSpec( Collection options, String description ) {
+ NoArgumentOptionSpec( List options, String description ) {
super( options, description );
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/NonOptionArgumentSpec.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/NonOptionArgumentSpec.java
index 8124a05e366..5332cf5b781 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/NonOptionArgumentSpec.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/NonOptionArgumentSpec.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -87,7 +87,7 @@ public class NonOptionArgumentSpec extends AbstractOptionSpec {
private String argumentDescription = "";
NonOptionArgumentSpec() {
- this("");
+ this( "" );
}
NonOptionArgumentSpec( String description ) {
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionArgumentConversionException.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionArgumentConversionException.java
index 063b97200f8..84c076efbe6 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionArgumentConversionException.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionArgumentConversionException.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -55,7 +55,7 @@
package jdk.internal.joptsimple;
-import java.util.Collection;
+import static java.util.Collections.*;
/**
* Thrown when a problem occurs converting an argument of an option from {@link String} to another type.
@@ -67,14 +67,14 @@ class OptionArgumentConversionException extends OptionException {
private final String argument;
- OptionArgumentConversionException( Collection options, String argument, Throwable cause ) {
- super( options, cause );
+ OptionArgumentConversionException( OptionSpec> options, String argument, Throwable cause ) {
+ super( singleton( options ), cause );
this.argument = argument;
}
@Override
- public String getMessage() {
- return "Cannot parse argument '" + argument + "' of option " + multipleOptionMessage();
+ Object[] messageArguments() {
+ return new Object[] { argument, singleOptionString() };
}
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionDeclarer.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionDeclarer.java
index 2a85e25901a..35ddac0af86 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionDeclarer.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionDeclarer.java
@@ -25,14 +25,20 @@
package jdk.internal.joptsimple;
-import java.util.Collection;
+import java.util.List;
/**
- * Trains the option parser. This interface aids integration with other code which may expose declaration of options but
- * not actual command-line parsing.
+ * Trains the option parser. This interface aids integration that disposes declaration of options but not actual
+ * command-line parsing.
+ *
+ * Typical use is for another class to implement {@code OptionDeclarer} as a facade, forwarding calls to an
+ * {@code OptionParser} instance.
+ *
+ * Note that although this is an interface, the returned values of calls are concrete jopt-simple classes.
*
* @author Paul Holser
* @see OptionParser
+ * @since 4.6
*/
public interface OptionDeclarer {
/**
@@ -78,12 +84,12 @@ public interface OptionDeclarer {
* @throws OptionException if any of the options contain illegal characters
* @throws NullPointerException if the option list or any of its elements are {@code null}
*/
- OptionSpecBuilder acceptsAll( Collection options );
+ OptionSpecBuilder acceptsAll( List options );
/**
* Tells the parser to recognize the given options, and treat them as synonymous.
*
- * @see #acceptsAll(Collection)
+ * @see #acceptsAll(List)
* @param options the options to recognize and treat as synonymous
* @param description a string that describes the purpose of the option. This is used when generating help
* information about the parser.
@@ -92,7 +98,7 @@ public interface OptionDeclarer {
* @throws NullPointerException if the option list or any of its elements are {@code null}
* @throws IllegalArgumentException if the option list is empty
*/
- OptionSpecBuilder acceptsAll( Collection options, String description );
+ OptionSpecBuilder acceptsAll( List options, String description );
/**
* Gives an object that represents an access point for non-option arguments on a command line.
@@ -127,7 +133,7 @@ public interface OptionDeclarer {
void allowsUnrecognizedOptions();
/**
- * Tells the parser either to recognize or ignore "-W"-style long options.
+ * Tells the parser either to recognize or ignore {@code -W}-style long options.
*
* @param recognize {@code true} if the parser is to recognize the special style of long options
*/
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionDescriptor.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionDescriptor.java
index 4a6694814f3..4707df23f23 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionDescriptor.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionDescriptor.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -55,7 +55,6 @@
package jdk.internal.joptsimple;
-import java.util.Collection;
import java.util.List;
/**
@@ -70,7 +69,7 @@ public interface OptionDescriptor {
*
* @return synonymous options
*/
- Collection options();
+ List options();
/**
* Description of this option's purpose.
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionException.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionException.java
index 15977b63801..96cc928ad6b 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionException.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionException.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -58,11 +58,15 @@ package jdk.internal.joptsimple;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+import jdk.internal.joptsimple.internal.Strings;
import static java.util.Collections.*;
-
-import static jdk.internal.joptsimple.internal.Strings.*;
+import static jdk.internal.joptsimple.internal.Messages.*;
/**
* Thrown when a problem occurs during option parsing.
@@ -72,16 +76,30 @@ import static jdk.internal.joptsimple.internal.Strings.*;
public abstract class OptionException extends RuntimeException {
private static final long serialVersionUID = -1L;
- private final List options = new ArrayList();
+ private final List options = new ArrayList<>();
- protected OptionException( Collection options ) {
+ protected OptionException( List options ) {
this.options.addAll( options );
}
- protected OptionException( Collection options, Throwable cause ) {
- super( cause );
+ protected OptionException( Collection extends OptionSpec>> options ) {
+ this.options.addAll( specsToStrings( options ) );
+ }
- this.options.addAll( options );
+ protected OptionException( Collection extends OptionSpec>> options, Throwable cause ) {
+ super( cause );
+ this.options.addAll( specsToStrings( options ) );
+ }
+
+ private List specsToStrings( Collection extends OptionSpec>> options ) {
+ List strings = new ArrayList<>();
+ for ( OptionSpec> each : options )
+ strings.add( specToString( each ) );
+ return strings;
+ }
+
+ private String specToString( OptionSpec> option ) {
+ return Strings.join( new ArrayList<>( option.options() ), "/" );
}
/**
@@ -89,23 +107,24 @@ public abstract class OptionException extends RuntimeException {
*
* @return the option being considered when the exception was created
*/
- public Collection options() {
- return unmodifiableCollection( options );
+ public List options() {
+ return unmodifiableList( options );
}
- protected final String singleOptionMessage() {
- return singleOptionMessage( options.get( 0 ) );
+ protected final String singleOptionString() {
+ return singleOptionString( options.get( 0 ) );
}
- protected final String singleOptionMessage( String option ) {
- return SINGLE_QUOTE + option + SINGLE_QUOTE;
+ protected final String singleOptionString( String option ) {
+ return option;
}
- protected final String multipleOptionMessage() {
+ protected final String multipleOptionString() {
StringBuilder buffer = new StringBuilder( "[" );
- for ( Iterator iter = options.iterator(); iter.hasNext(); ) {
- buffer.append( singleOptionMessage( iter.next() ) );
+ Set asSet = new LinkedHashSet( options );
+ for ( Iterator iter = asSet.iterator(); iter.hasNext(); ) {
+ buffer.append( singleOptionString(iter.next()) );
if ( iter.hasNext() )
buffer.append( ", " );
}
@@ -118,4 +137,19 @@ public abstract class OptionException extends RuntimeException {
static OptionException unrecognizedOption( String option ) {
return new UnrecognizedOptionException( option );
}
+
+ @Override
+ public final String getMessage() {
+ return localizedMessage( Locale.getDefault() );
+ }
+
+ final String localizedMessage( Locale locale ) {
+ return formattedMessage( locale );
+ }
+
+ private String formattedMessage( Locale locale ) {
+ return message( locale, "jdk.internal.joptsimple.ExceptionMessages", getClass(), "message", messageArguments() );
+ }
+
+ abstract Object[] messageArguments();
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionMissingRequiredArgumentException.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionMissingRequiredArgumentException.java
index f667b446527..f0fa6b3d24d 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionMissingRequiredArgumentException.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionMissingRequiredArgumentException.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -55,22 +55,22 @@
package jdk.internal.joptsimple;
-import java.util.Collection;
+import static java.util.Arrays.*;
/**
- * Thrown when the option parser discovers an option that requires an argument, but that argument is missing.
+ * Thrown when the option parser discovers options that require an argument, but are missing an argument.
*
* @author Paul Holser
*/
class OptionMissingRequiredArgumentException extends OptionException {
private static final long serialVersionUID = -1L;
- OptionMissingRequiredArgumentException( Collection options ) {
- super( options );
+ OptionMissingRequiredArgumentException( OptionSpec> option ) {
+ super( asList( option ) );
}
@Override
- public String getMessage() {
- return "Option " + multipleOptionMessage() + " requires an argument";
+ Object[] messageArguments() {
+ return new Object[] { singleOptionString() };
}
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionParser.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionParser.java
index c6c319a329a..403a63927cf 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionParser.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionParser.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -55,18 +55,16 @@
package jdk.internal.joptsimple;
-import jdk.internal.joptsimple.internal.AbbreviationMap;
-import jdk.internal.joptsimple.util.KeyValuePair;
-
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
+
+import jdk.internal.joptsimple.internal.AbbreviationMap;
+import jdk.internal.joptsimple.internal.SimpleOptionNameMap;
+import jdk.internal.joptsimple.internal.OptionNameMap;
+import jdk.internal.joptsimple.util.KeyValuePair;
import static java.util.Collections.*;
import static jdk.internal.joptsimple.OptionException.*;
@@ -80,57 +78,58 @@ import static jdk.internal.joptsimple.ParserRules.*;
* This parser supports short options and long options.
*
*
- * - Short options begin with a single hyphen ("-") followed by a single letter or digit,
- * or question mark ("?"), or dot (".").
+ * - Short options begin with a single hyphen ("{@code -}") followed by a single letter or digit,
+ * or question mark ("{@code ?}"), or dot ("{@code .}"), or underscore ("{@code _}").
*
* - Short options can accept single arguments. The argument can be made required or optional. The option's
* argument can occur:
*
- * - in the slot after the option, as in -d /tmp
- * - right up against the option, as in -d/tmp
- * - right up against the option separated by an equals sign ("="), as in -d=/tmp
+ * - in the slot after the option, as in {@code -d /tmp}
+ * - right up against the option, as in {@code -d/tmp}
+ * - right up against the option separated by an equals sign ({@code "="}), as in {@code -d=/tmp}
*
* To specify n arguments for an option, specify the option n times, once for each argument,
- * as in -d /tmp -d /var -d /opt; or, when using the
+ * as in {@code -d /tmp -d /var -d /opt}; or, when using the
* {@linkplain ArgumentAcceptingOptionSpec#withValuesSeparatedBy(char) "separated values"} clause of the "fluent
* interface" (see below), give multiple values separated by a given character as a single argument to the
* option.
*
- * - Short options can be clustered, so that -abc is treated as -a -b -c. If a short option
+ *
- Short options can be clustered, so that {@code -abc} is treated as {@code -a -b -c}. If a short option
* in the cluster can accept an argument, the remaining characters are interpreted as the argument for that
* option.
*
- * - An argument consisting only of two hyphens ("--") signals that the remaining arguments are to be
+ *
- An argument consisting only of two hyphens ({@code "--"}) signals that the remaining arguments are to be
* treated as non-options.
*
* - An argument consisting only of a single hyphen is considered a non-option argument (though it can be an
* argument of an option). Many Unix programs treat single hyphens as stand-ins for the standard input or standard
* output streams.
*
- * - Long options begin with two hyphens ("--"), followed by multiple letters, digits,
+ *
- Long options begin with two hyphens ({@code "--"}), followed by multiple letters, digits,
* hyphens, question marks, or dots. A hyphen cannot be the first character of a long option specification when
* configuring the parser.
*
- * - You can abbreviate long options, so long as the abbreviation is unique.
+ * - You can abbreviate long options, so long as the abbreviation is unique. Suppress this behavior if
+ * you wish using {@linkplain OptionParser#OptionParser(boolean) this constructor}.
*
* - Long options can accept single arguments. The argument can be made required or optional. The option's
* argument can occur:
*
- * - in the slot after the option, as in --directory /tmp
- * - right up against the option separated by an equals sign ("="), as in
- * --directory=/tmp
+ *
- in the slot after the option, as in {@code --directory /tmp}
+ * - right up against the option separated by an equals sign ({@code "="}), as in
+ * {@code --directory=/tmp}
*
* Specify multiple arguments for a long option in the same manner as for short options (see above).
*
- * - You can use a single hyphen ("-") instead of a double hyphen ("--") for a long
+ *
- You can use a single hyphen ({@code "-"}) instead of a double hyphen ({@code "--"}) for a long
* option.
*
- * - The option -W is reserved. If you tell the parser to {@linkplain
+ *
- The option {@code -W} is reserved. If you tell the parser to {@linkplain
* #recognizeAlternativeLongOptions(boolean) recognize alternative long options}, then it will treat, for example,
- * -W foo=bar as the long option foo with argument bar, as though you had written
- * --foo=bar.
+ * {@code -W foo=bar} as the long option {@code foo} with argument {@code bar}, as though you had written
+ * {@code --foo=bar}.
*
- * - You can specify -W as a valid short option, or use it as an abbreviation for a long option, but
+ *
- You can specify {@code -W} as a valid short option, or use it as an abbreviation for a long option, but
* {@linkplain #recognizeAlternativeLongOptions(boolean) recognizing alternative long options} will always supersede
* this behavior.
*
@@ -148,15 +147,15 @@ import static jdk.internal.joptsimple.ParserRules.*;
* parser.accepts( "2" );
* OptionSet options = parser.parse( "-a", "-2" );
*
- * In this case, the option set contains "a" with argument -2, not both "a" and
- * "2". Swapping the elements in the args array gives the latter.
+ * In this case, the option set contains {@code "a"} with argument {@code -2}, not both {@code "a"} and
+ * {@code "2"}. Swapping the elements in the args array gives the latter.
*
*
* There are two ways to tell the parser what options to recognize:
*
*
* - A "fluent interface"-style API for specifying options, available since version 2. Sentences in this fluent
- * interface language begin with a call to {@link #accepts(String) accepts} or {@link #acceptsAll(Collection)
+ * interface language begin with a call to {@link #accepts(String) accepts} or {@link #acceptsAll(List)
* acceptsAll} methods; calls on the ensuing chain of objects describe whether the options can take an argument,
* whether the argument is required or optional, to what type arguments of the options should be converted if any,
* etc. Since version 3, these calls return an instance of {@link OptionSpec}, which can subsequently be used to
@@ -169,28 +168,28 @@ import static jdk.internal.joptsimple.ParserRules.*;
*
* - Any letter or digit is treated as an option character.
*
- * - An option character can be immediately followed by an asterisk (*) to indicate that the option is a
- * "help" option.
+ * - An option character can be immediately followed by an asterisk ({@code *)} to indicate that
+ * the option is a "help" option.
*
- * - If an option character (with possible trailing asterisk) is followed by a single colon (":"),
+ *
- If an option character (with possible trailing asterisk) is followed by a single colon ({@code ":"}),
* then the option requires an argument.
*
- * - If an option character (with possible trailing asterisk) is followed by two colons ("::"),
+ *
- If an option character (with possible trailing asterisk) is followed by two colons ({@code "::"}),
* then the option accepts an optional argument.
*
* - Otherwise, the option character accepts no argument.
*
- * - If the option specification string begins with a plus sign ("+"), the parser will behave
+ *
- If the option specification string begins with a plus sign ({@code "+" }), the parser will behave
* "POSIX-ly correct".
*
- * - If the option specification string contains the sequence "W;" (capital W followed by a
+ *
- If the option specification string contains the sequence {@code "W;"} (capital W followed by a
* semicolon), the parser will recognize the alternative form of long options.
*
*
*
*
- * Each of the options in a list of options given to {@link #acceptsAll(Collection) acceptsAll} is treated as a
- * synonym of the others. For example:
+ *
Each of the options in a list of options given to {@link #acceptsAll(List) acceptsAll} is treated as a
+ * synonym of the others. For example:
*
*
* OptionParser parser = new OptionParser();
@@ -198,14 +197,14 @@ import static jdk.internal.joptsimple.ParserRules.*;
* OptionSet options = parser.parse( "-w" );
*
*
- * In this case, options.{@link OptionSet#has(String) has} would answer {@code true} when given arguments
- * "w", "interactive", and "confirmation". The {@link OptionSet} would give the same
+ * In this case, options.{@link OptionSet#has(String) has} would answer {@code true} when given arguments
+ * {@code "w"}, {@code "interactive"}, and {@code "confirmation"}. The {@link OptionSet} would give the same
* responses to these arguments for its other methods as well.
*
* By default, as with GNU {@code getopt()}, the parser allows intermixing of options and non-options. If, however,
* the parser has been created to be "POSIX-ly correct", then the first argument that does not look lexically like an
* option, and is not a required argument of a preceding option, signals the end of options. You can still bind
- * optional arguments to their options using the abutting (for short options) or = syntax.
+ * optional arguments to their options using the abutting (for short options) or {@code =} syntax.
*
* Unlike GNU {@code getopt()}, this parser does not honor the environment variable {@code POSIXLY_CORRECT}.
* "POSIX-ly correct" parsers are configured by either:
@@ -214,16 +213,20 @@ import static jdk.internal.joptsimple.ParserRules.*;
* using the method {@link #posixlyCorrect(boolean)}, or
*
* using the {@linkplain #OptionParser(String) constructor} with an argument whose first character is a plus sign
- * ("+")
+ * ({@code "+"})
*
*
* @author Paul Holser
* @see The GNU C Library
*/
public class OptionParser implements OptionDeclarer {
- private final AbbreviationMap> recognizedOptions;
- private final Map, Set>> requiredIf;
- private final Map, Set>> requiredUnless;
+ private final OptionNameMap> recognizedOptions;
+ private final ArrayList> trainingOrder;
+ private final Map, Set>> requiredIf;
+ private final Map, Set>> requiredUnless;
+ private final Map, Set>> availableIf;
+ private final Map, Set>> availableUnless;
+
private OptionParserState state;
private boolean posixlyCorrect;
private boolean allowsUnrecognizedOptions;
@@ -234,11 +237,28 @@ public class OptionParser implements OptionDeclarer {
* behavior.
*/
public OptionParser() {
- recognizedOptions = new AbbreviationMap>();
- requiredIf = new HashMap, Set>>();
- requiredUnless = new HashMap, Set>>();
+ this(true);
+ }
+
+ /**
+ * Creates an option parser that initially recognizes no options, and does not exhibit "POSIX-ly correct"
+ * behavior.
+ *
+ * @param allowAbbreviations whether unambiguous abbreviations of long options should be recognized
+ * by the parser
+ */
+ public OptionParser( boolean allowAbbreviations ) {
+ trainingOrder = new ArrayList<>();
+ requiredIf = new HashMap<>();
+ requiredUnless = new HashMap<>();
+ availableIf = new HashMap<>();
+ availableUnless = new HashMap<>();
state = moreOptions( false );
+ recognizedOptions = allowAbbreviations
+ ? new AbbreviationMap>()
+ : new SimpleOptionNameMap>();
+
recognize( new NonOptionArgumentSpec() );
}
@@ -266,11 +286,11 @@ public class OptionParser implements OptionDeclarer {
return acceptsAll( singletonList( option ), description );
}
- public OptionSpecBuilder acceptsAll( Collection options ) {
+ public OptionSpecBuilder acceptsAll( List options ) {
return acceptsAll( options, "" );
}
- public OptionSpecBuilder acceptsAll( Collection options, String description ) {
+ public OptionSpecBuilder acceptsAll( List options, String description ) {
if ( options.isEmpty() )
throw new IllegalArgumentException( "need at least one option" );
@@ -280,7 +300,7 @@ public class OptionParser implements OptionDeclarer {
}
public NonOptionArgumentSpec nonOptions() {
- NonOptionArgumentSpec spec = new NonOptionArgumentSpec();
+ NonOptionArgumentSpec spec = new NonOptionArgumentSpec<>();
recognize( spec );
@@ -288,7 +308,7 @@ public class OptionParser implements OptionDeclarer {
}
public NonOptionArgumentSpec nonOptions( String description ) {
- NonOptionArgumentSpec spec = new NonOptionArgumentSpec( description );
+ NonOptionArgumentSpec spec = new NonOptionArgumentSpec<>( description );
recognize( spec );
@@ -321,6 +341,7 @@ public class OptionParser implements OptionDeclarer {
void recognize( AbstractOptionSpec> spec ) {
recognizedOptions.putAll( spec.options(), spec );
+ trainingOrder.add( spec );
}
/**
@@ -348,7 +369,7 @@ public class OptionParser implements OptionDeclarer {
* @see #printHelpOn(OutputStream)
*/
public void printHelpOn( Writer sink ) throws IOException {
- sink.write( helpFormatter.format( recognizedOptions.toJavaUtilMap() ) );
+ sink.write( helpFormatter.format( _recognizedOptions() ) );
sink.flush();
}
@@ -366,15 +387,29 @@ public class OptionParser implements OptionDeclarer {
}
/**
- * Retrieves all the options which have been configured for the parser.
+ * Retrieves all options-spec pairings which have been configured for the parser in the same order as declared
+ * during training. Option flags for specs are alphabetized by {@link OptionSpec#options()}; only the order of the
+ * specs is preserved.
*
- * @return a {@link Map} containing all the configured options and their corresponding {@link OptionSpec}
+ * (Note: prior to 4.7 the order was alphabetical across all options regardless of spec.)
+ *
+ * @return a map containing all the configured options and their corresponding {@link OptionSpec}
+ * @since 4.6
*/
public Map> recognizedOptions() {
- return new HashMap>( recognizedOptions.toJavaUtilMap() );
+ return new LinkedHashMap>( _recognizedOptions() );
}
- /**
+ private Map> _recognizedOptions() {
+ Map> options = new LinkedHashMap<>();
+ for ( AbstractOptionSpec> spec : trainingOrder ) {
+ for ( String option : spec.options() )
+ options.put( option, spec );
+ }
+ return options;
+ }
+
+ /**
* Parses the given command line arguments according to the option specifications given to the parser.
*
* @param arguments arguments to parse
@@ -393,45 +428,89 @@ public class OptionParser implements OptionDeclarer {
reset();
ensureRequiredOptions( detected );
+ ensureAllowedOptions( detected );
return detected;
}
+ /**
+ * Mandates mutual exclusiveness for the options built by the specified builders.
+ *
+ * @param specs descriptors for options that should be mutually exclusive on a command line.
+ * @throws NullPointerException if {@code specs} is {@code null}
+ */
+ public void mutuallyExclusive( OptionSpecBuilder... specs ) {
+ for ( int i = 0; i < specs.length; i++ ) {
+ for ( int j = 0; j < specs.length; j++ ) {
+ if ( i != j )
+ specs[i].availableUnless( specs[j] );
+ }
+ }
+ }
+
private void ensureRequiredOptions( OptionSet options ) {
- Collection missingRequiredOptions = missingRequiredOptions( options );
+ List> missingRequiredOptions = missingRequiredOptions(options);
boolean helpOptionPresent = isHelpOptionPresent( options );
if ( !missingRequiredOptions.isEmpty() && !helpOptionPresent )
- throw new MissingRequiredOptionException( missingRequiredOptions );
+ throw new MissingRequiredOptionsException( missingRequiredOptions );
}
- private Collection missingRequiredOptions( OptionSet options ) {
- Collection missingRequiredOptions = new HashSet();
+ private void ensureAllowedOptions( OptionSet options ) {
+ List> forbiddenOptions = unavailableOptions( options );
+ boolean helpOptionPresent = isHelpOptionPresent( options );
+
+ if ( !forbiddenOptions.isEmpty() && !helpOptionPresent )
+ throw new UnavailableOptionException( forbiddenOptions );
+ }
+
+ private List> missingRequiredOptions( OptionSet options ) {
+ List> missingRequiredOptions = new ArrayList<>();
for ( AbstractOptionSpec> each : recognizedOptions.toJavaUtilMap().values() ) {
if ( each.isRequired() && !options.has( each ) )
- missingRequiredOptions.addAll( each.options() );
+ missingRequiredOptions.add(each);
}
- for ( Map.Entry, Set>> eachEntry : requiredIf.entrySet() ) {
- AbstractOptionSpec> required = specFor( eachEntry.getKey().iterator().next() );
+ for ( Map.Entry, Set>> each : requiredIf.entrySet() ) {
+ AbstractOptionSpec> required = specFor( each.getKey().iterator().next() );
- if ( optionsHasAnyOf( options, eachEntry.getValue() ) && !options.has( required ) ) {
- missingRequiredOptions.addAll( required.options() );
- }
+ if ( optionsHasAnyOf( options, each.getValue() ) && !options.has( required ) )
+ missingRequiredOptions.add( required );
}
- for ( Map.Entry, Set>> eachEntry : requiredUnless.entrySet() ) {
- AbstractOptionSpec> required = specFor( eachEntry.getKey().iterator().next() );
+ for ( Map.Entry, Set>> each : requiredUnless.entrySet() ) {
+ AbstractOptionSpec> required = specFor(each.getKey().iterator().next());
- if ( !optionsHasAnyOf( options, eachEntry.getValue() ) && !options.has( required ) ) {
- missingRequiredOptions.addAll( required.options() );
- }
+ if ( !optionsHasAnyOf( options, each.getValue() ) && !options.has( required ) )
+ missingRequiredOptions.add( required );
}
return missingRequiredOptions;
}
+ private List> unavailableOptions(OptionSet options) {
+ List> unavailableOptions = new ArrayList<>();
+
+ for ( Map.Entry, Set>> eachEntry : availableIf.entrySet() ) {
+ AbstractOptionSpec> forbidden = specFor( eachEntry.getKey().iterator().next() );
+
+ if ( !optionsHasAnyOf( options, eachEntry.getValue() ) && options.has( forbidden ) ) {
+ unavailableOptions.add(forbidden);
+ }
+ }
+
+ for ( Map.Entry, Set>> eachEntry : availableUnless.entrySet() ) {
+ AbstractOptionSpec> forbidden = specFor( eachEntry.getKey().iterator().next() );
+
+ if ( optionsHasAnyOf( options, eachEntry.getValue() ) && options.has( forbidden ) ) {
+ unavailableOptions.add(forbidden);
+ }
+ }
+
+ return unavailableOptions;
+ }
+
private boolean optionsHasAnyOf( OptionSet options, Collection> specs ) {
for ( OptionSpec> each : specs ) {
if ( options.has( each ) )
@@ -443,12 +522,14 @@ public class OptionParser implements OptionDeclarer {
private boolean isHelpOptionPresent( OptionSet options ) {
boolean helpOptionPresent = false;
+
for ( AbstractOptionSpec> each : recognizedOptions.toJavaUtilMap().values() ) {
if ( each.isForHelp() && options.has( each ) ) {
helpOptionPresent = true;
break;
}
}
+
return helpOptionPresent;
}
@@ -505,24 +586,40 @@ public class OptionParser implements OptionDeclarer {
return recognizedOptions.contains( option );
}
- void requiredIf( Collection precedentSynonyms, String required ) {
+ void requiredIf( List precedentSynonyms, String required ) {
requiredIf( precedentSynonyms, specFor( required ) );
}
- void requiredIf( Collection precedentSynonyms, OptionSpec> required ) {
- putRequiredOption( precedentSynonyms, required, requiredIf );
+ void requiredIf( List precedentSynonyms, OptionSpec> required ) {
+ putDependentOption( precedentSynonyms, required, requiredIf );
}
- void requiredUnless( Collection precedentSynonyms, String required ) {
+ void requiredUnless( List precedentSynonyms, String required ) {
requiredUnless( precedentSynonyms, specFor( required ) );
}
- void requiredUnless( Collection precedentSynonyms, OptionSpec> required ) {
- putRequiredOption( precedentSynonyms, required, requiredUnless );
+ void requiredUnless( List precedentSynonyms, OptionSpec> required ) {
+ putDependentOption( precedentSynonyms, required, requiredUnless );
}
- private void putRequiredOption( Collection precedentSynonyms, OptionSpec> required,
- Map, Set>> target ) {
+ void availableIf( List precedentSynonyms, String available ) {
+ availableIf( precedentSynonyms, specFor( available ) );
+ }
+
+ void availableIf( List precedentSynonyms, OptionSpec> available) {
+ putDependentOption( precedentSynonyms, available, availableIf );
+ }
+
+ void availableUnless( List precedentSynonyms, String available ) {
+ availableUnless( precedentSynonyms, specFor( available ) );
+ }
+
+ void availableUnless( List precedentSynonyms, OptionSpec> available ) {
+ putDependentOption( precedentSynonyms, available, availableUnless );
+ }
+
+ private void putDependentOption( List precedentSynonyms, OptionSpec> required,
+ Map, Set>> target ) {
for ( String each : precedentSynonyms ) {
AbstractOptionSpec> spec = specFor( each );
@@ -532,7 +629,7 @@ public class OptionParser implements OptionDeclarer {
Set> associated = target.get( precedentSynonyms );
if ( associated == null ) {
- associated = new HashSet>();
+ associated = new HashSet<>();
target.put( precedentSynonyms, associated );
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionParserState.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionParserState.java
index 7fdbcbf3618..d2affe8e48d 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionParserState.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionParserState.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSet.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSet.java
index 71061156fa0..ef781f2d223 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSet.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSet.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -55,11 +55,14 @@
package jdk.internal.joptsimple;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
import static java.util.Collections.*;
-
-import static jdk.internal.joptsimple.internal.Objects.*;
+import static java.util.Objects.*;
/**
* Representation of a group of detected command line options, their arguments, and non-option arguments.
@@ -77,9 +80,9 @@ public class OptionSet {
* Package-private because clients don't create these.
*/
OptionSet( Map> recognizedSpecs ) {
- detectedSpecs = new ArrayList>();
- detectedOptions = new HashMap>();
- optionsToArguments = new IdentityHashMap, List>();
+ detectedSpecs = new ArrayList<>();
+ detectedOptions = new HashMap<>();
+ optionsToArguments = new IdentityHashMap<>();
defaultValues = defaultValues( recognizedSpecs );
this.recognizedSpecs = recognizedSpecs;
}
@@ -90,7 +93,7 @@ public class OptionSet {
* @return {@code true} if any options were detected
*/
public boolean hasOptions() {
- return !detectedOptions.isEmpty();
+ return !( detectedOptions.size() == 1 && detectedOptions.values().iterator().next().representsNonOptions() );
}
/**
@@ -148,7 +151,7 @@ public class OptionSet {
* @see #hasArgument(String)
*/
public boolean hasArgument( OptionSpec> option ) {
- ensureNotNull( option );
+ requireNonNull( option );
List values = optionsToArguments.get( option );
return values != null && !values.isEmpty();
@@ -169,7 +172,7 @@ public class OptionSet {
* @throws OptionException if more than one argument was detected for the option
*/
public Object valueOf( String option ) {
- ensureNotNull( option );
+ requireNonNull( option );
AbstractOptionSpec> spec = detectedOptions.get( option );
if ( spec == null ) {
@@ -194,7 +197,7 @@ public class OptionSet {
* @throws ClassCastException if the arguments of this option are not of the expected type
*/
public V valueOf( OptionSpec option ) {
- ensureNotNull( option );
+ requireNonNull( option );
List values = valuesOf( option );
switch ( values.size() ) {
@@ -203,7 +206,7 @@ public class OptionSet {
case 1:
return values.get( 0 );
default:
- throw new MultipleArgumentsForOptionException( option.options() );
+ throw new MultipleArgumentsForOptionException( option );
}
}
@@ -217,7 +220,7 @@ public class OptionSet {
* @throws NullPointerException if {@code option} is {@code null}
*/
public List> valuesOf( String option ) {
- ensureNotNull( option );
+ requireNonNull( option );
AbstractOptionSpec> spec = detectedOptions.get( option );
return spec == null ? defaultValuesFor( option ) : valuesOf( spec );
@@ -238,14 +241,14 @@ public class OptionSet {
* example, if the type does not implement a correct conversion constructor or method
*/
public List valuesOf( OptionSpec option ) {
- ensureNotNull( option );
+ requireNonNull( option );
List values = optionsToArguments.get( option );
if ( values == null || values.isEmpty() )
return defaultValueFor( option );
AbstractOptionSpec spec = (AbstractOptionSpec) option;
- List convertedValues = new ArrayList();
+ List convertedValues = new ArrayList<>();
for ( String each : values )
convertedValues.add( spec.convert( each ) );
@@ -260,7 +263,7 @@ public class OptionSet {
*/
public List> specs() {
List> specs = detectedSpecs;
- specs.remove( detectedOptions.get( NonOptionArgumentSpec.NAME ) );
+ specs.removeAll( singletonList( detectedOptions.get( NonOptionArgumentSpec.NAME ) ) );
return unmodifiableList( specs );
}
@@ -271,10 +274,13 @@ public class OptionSet {
* @return the declared options as a map
*/
public Map, List>> asMap() {
- Map, List>> map = new HashMap, List>>();
- for ( AbstractOptionSpec> spec : recognizedSpecs.values() )
+ Map, List>> map = new HashMap<>();
+
+ for ( AbstractOptionSpec> spec : recognizedSpecs.values() ) {
if ( !spec.representsNonOptions() )
map.put( spec, valuesOf( spec ) );
+ }
+
return unmodifiableMap( map );
}
@@ -282,7 +288,8 @@ public class OptionSet {
* @return the detected non-option arguments
*/
public List> nonOptionArguments() {
- return unmodifiableList( valuesOf( detectedOptions.get( NonOptionArgumentSpec.NAME ) ) );
+ AbstractOptionSpec> spec = detectedOptions.get( NonOptionArgumentSpec.NAME );
+ return valuesOf( spec );
}
void add( AbstractOptionSpec> spec ) {
@@ -298,7 +305,7 @@ public class OptionSet {
List optionArguments = optionsToArguments.get( spec );
if ( optionArguments == null ) {
- optionArguments = new ArrayList();
+ optionArguments = new ArrayList<>();
optionsToArguments.put( spec, optionArguments );
}
@@ -315,25 +322,22 @@ public class OptionSet {
return false;
OptionSet other = (OptionSet) that;
- Map, List> thisOptionsToArguments =
- new HashMap, List>( optionsToArguments );
- Map, List> otherOptionsToArguments =
- new HashMap, List>( other.optionsToArguments );
+ Map, List> thisOptionsToArguments = new HashMap<>( optionsToArguments );
+ Map, List> otherOptionsToArguments = new HashMap<>( other.optionsToArguments );
return detectedOptions.equals( other.detectedOptions )
&& thisOptionsToArguments.equals( otherOptionsToArguments );
}
@Override
public int hashCode() {
- Map, List> thisOptionsToArguments =
- new HashMap, List>( optionsToArguments );
+ Map, List> thisOptionsToArguments = new HashMap<>( optionsToArguments );
return detectedOptions.hashCode() ^ thisOptionsToArguments.hashCode();
}
@SuppressWarnings( "unchecked" )
private List defaultValuesFor( String option ) {
if ( defaultValues.containsKey( option ) )
- return (List) defaultValues.get( option );
+ return unmodifiableList( (List) defaultValues.get( option ) );
return emptyList();
}
@@ -343,7 +347,7 @@ public class OptionSet {
}
private static Map> defaultValues( Map> recognizedSpecs ) {
- Map> defaults = new HashMap>();
+ Map> defaults = new HashMap<>();
for ( Map.Entry> each : recognizedSpecs.entrySet() )
defaults.put( each.getKey(), each.getValue().defaultValues() );
return defaults;
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpec.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpec.java
index 666230b05d4..030e6f7a5a0 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpec.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpec.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -55,7 +55,6 @@
package jdk.internal.joptsimple;
-import java.util.Collection;
import java.util.List;
/**
@@ -116,7 +115,7 @@ public interface OptionSpec {
/**
* @return the string representations of this option
*/
- Collection options();
+ List options();
/**
* Tells whether this option is designated as a "help" option. The presence of a "help" option on a command line
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpecBuilder.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpecBuilder.java
index 4f171091ec0..d7d02f00a87 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpecBuilder.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpecBuilder.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -56,7 +56,6 @@
package jdk.internal.joptsimple;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -90,7 +89,7 @@ import java.util.List;
public class OptionSpecBuilder extends NoArgumentOptionSpec {
private final OptionParser parser;
- OptionSpecBuilder( OptionParser parser, Collection options, String description ) {
+ OptionSpecBuilder( OptionParser parser, List options, String description ) {
super( options, description );
this.parser = parser;
@@ -107,8 +106,7 @@ public class OptionSpecBuilder extends NoArgumentOptionSpec {
* @return a specification for the option
*/
public ArgumentAcceptingOptionSpec withRequiredArg() {
- ArgumentAcceptingOptionSpec newSpec =
- new RequiredArgumentOptionSpec( options(), description() );
+ ArgumentAcceptingOptionSpec newSpec = new RequiredArgumentOptionSpec<>( options(), description() );
parser.recognize( newSpec );
return newSpec;
@@ -121,7 +119,7 @@ public class OptionSpecBuilder extends NoArgumentOptionSpec {
*/
public ArgumentAcceptingOptionSpec withOptionalArg() {
ArgumentAcceptingOptionSpec newSpec =
- new OptionalArgumentOptionSpec( options(), description() );
+ new OptionalArgumentOptionSpec<>( options(), description() );
parser.recognize( newSpec );
return newSpec;
@@ -141,9 +139,8 @@ public class OptionSpecBuilder extends NoArgumentOptionSpec {
*/
public OptionSpecBuilder requiredIf( String dependent, String... otherDependents ) {
List dependents = validatedDependents( dependent, otherDependents );
- for ( String each : dependents ) {
+ for ( String each : dependents )
parser.requiredIf( options(), each );
- }
return this;
}
@@ -210,8 +207,91 @@ public class OptionSpecBuilder extends NoArgumentOptionSpec {
return this;
}
+ /**
+ * Informs an option parser that this builder's option is allowed if the given option is present on the command
+ * line.
+ *
+ * For a given option, you should not mix this with {@link #availableUnless(String, String...)
+ * availableUnless} to avoid conflicts.
+ *
+ * @param dependent an option whose presence on a command line makes this builder's option allowed
+ * @param otherDependents other options whose presence on a command line makes this builder's option allowed
+ * @return self, so that the caller can add clauses to the fluent interface sentence
+ * @throws OptionException if any of the dependent options haven't been configured in the parser yet
+ */
+ public OptionSpecBuilder availableIf( String dependent, String... otherDependents ) {
+ List dependents = validatedDependents( dependent, otherDependents );
+ for ( String each : dependents )
+ parser.availableIf( options(), each );
+
+ return this;
+ }
+
+ /**
+ * Informs an option parser that this builder's option is allowed if the given option is present on the command
+ * line.
+ *
+ * For a given option, you should not mix this with {@link #availableUnless(OptionSpec, OptionSpec[])
+ * requiredUnless} to avoid conflicts.
+ *
+ * This method recognizes only instances of options returned from the fluent interface methods.
+ *
+ * @param dependent the option whose presence on a command line makes this builder's option allowed
+ * @param otherDependents other options whose presence on a command line makes this builder's option allowed
+ * @return self, so that the caller can add clauses to the fluent interface sentence
+ */
+ public OptionSpecBuilder availableIf( OptionSpec> dependent, OptionSpec>... otherDependents ) {
+ parser.availableIf( options(), dependent );
+
+ for ( OptionSpec> each : otherDependents )
+ parser.availableIf( options(), each );
+
+ return this;
+ }
+
+ /**
+ * Informs an option parser that this builder's option is allowed if the given option is absent on the command
+ * line.
+ *
+ * For a given option, you should not mix this with {@link #availableIf(OptionSpec, OptionSpec[])
+ * requiredIf} to avoid conflicts.
+ *
+ * @param dependent an option whose absence on a command line makes this builder's option allowed
+ * @param otherDependents other options whose absence on a command line makes this builder's option allowed
+ * @return self, so that the caller can add clauses to the fluent interface sentence
+ * @throws OptionException if any of the dependent options haven't been configured in the parser yet
+ */
+ public OptionSpecBuilder availableUnless( String dependent, String... otherDependents ) {
+ List dependents = validatedDependents( dependent, otherDependents );
+ for ( String each : dependents )
+ parser.availableUnless( options(), each );
+
+ return this;
+ }
+
+ /**
+ * Informs an option parser that this builder's option is allowed if the given option is absent on the command
+ * line.
+ *
+ * For a given option, you should not mix this with {@link #availableIf(OptionSpec, OptionSpec[])
+ * requiredIf} to avoid conflicts.
+ *
+ * This method recognizes only instances of options returned from the fluent interface methods.
+ *
+ * @param dependent the option whose absence on a command line makes this builder's option allowed
+ * @param otherDependents other options whose absence on a command line makes this builder's option allowed
+ * @return self, so that the caller can add clauses to the fluent interface sentence
+ */
+ public OptionSpecBuilder availableUnless( OptionSpec> dependent, OptionSpec>... otherDependents ) {
+ parser.availableUnless( options(), dependent );
+ for ( OptionSpec> each : otherDependents )
+ parser.availableUnless(options(), each);
+
+ return this;
+ }
+
private List validatedDependents( String dependent, String... otherDependents ) {
- List dependents = new ArrayList();
+ List dependents = new ArrayList<>();
dependents.add( dependent );
Collections.addAll( dependents, otherDependents );
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpecTokenizer.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpecTokenizer.java
index d878daba6eb..9b45354f621 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpecTokenizer.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpecTokenizer.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionalArgumentOptionSpec.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionalArgumentOptionSpec.java
index 894e00e3a29..7e20779b962 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionalArgumentOptionSpec.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionalArgumentOptionSpec.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -55,7 +55,7 @@
package jdk.internal.joptsimple;
-import java.util.Collection;
+import java.util.List;
/**
* Specification of an option that accepts an optional argument.
@@ -68,7 +68,7 @@ class OptionalArgumentOptionSpec extends ArgumentAcceptingOptionSpec {
super( option, false );
}
- OptionalArgumentOptionSpec( Collection options, String description ) {
+ OptionalArgumentOptionSpec( List options, String description ) {
super( options, false, description );
}
@@ -77,7 +77,7 @@ class OptionalArgumentOptionSpec extends ArgumentAcceptingOptionSpec {
if ( arguments.hasMore() ) {
String nextArgument = arguments.peek();
- if ( !parser.looksLikeAnOption( nextArgument ) )
+ if ( !parser.looksLikeAnOption( nextArgument ) && canConvertArgument( nextArgument ) )
handleOptionArgument( parser, detectedOptions, arguments );
else if ( isArgumentOfNumberType() && canConvertArgument( nextArgument ) )
addArguments( detectedOptions, arguments.next() );
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ParserRules.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ParserRules.java
index e981d878adc..dae98e3b008 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ParserRules.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ParserRules.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -55,7 +55,7 @@
package jdk.internal.joptsimple;
-import java.util.Collection;
+import java.util.List;
import static java.lang.Character.*;
@@ -97,7 +97,7 @@ final class ParserRules {
ensureLegalOptionCharacter( option.charAt( i ) );
}
- static void ensureLegalOptions( Collection options ) {
+ static void ensureLegalOptions( List options ) {
for ( String each : options )
ensureLegalOption( each );
}
@@ -108,7 +108,7 @@ final class ParserRules {
}
private static boolean isAllowedPunctuation( char option ) {
- String allowedPunctuation = "?." + HYPHEN_CHAR;
+ String allowedPunctuation = "?._" + HYPHEN_CHAR;
return allowedPunctuation.indexOf( option ) != -1;
}
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/README b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/README
index ad0d0f64db5..fccb4f62f52 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/README
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/README
@@ -1,3 +1,3 @@
-JOpt Simple, Version 4.6
+JOpt Simple, Version 5.0.4
https://pholser.github.io/jopt-simple/
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/RequiredArgumentOptionSpec.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/RequiredArgumentOptionSpec.java
index 9972f8d1cff..26608a827c7 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/RequiredArgumentOptionSpec.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/RequiredArgumentOptionSpec.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -55,7 +55,7 @@
package jdk.internal.joptsimple;
-import java.util.Collection;
+import java.util.List;
/**
* Specification of an option that accepts a required argument.
@@ -68,14 +68,14 @@ class RequiredArgumentOptionSpec extends ArgumentAcceptingOptionSpec {
super( option, true );
}
- RequiredArgumentOptionSpec( Collection options, String description ) {
+ RequiredArgumentOptionSpec( List options, String description ) {
super( options, true, description );
}
@Override
protected void detectOptionArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions ) {
if ( !arguments.hasMore() )
- throw new OptionMissingRequiredArgumentException( options() );
+ throw new OptionMissingRequiredArgumentException( this );
addArguments( detectedOptions, arguments.next() );
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnacceptableNumberOfNonOptionsException.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnavailableOptionException.java
similarity index 74%
rename from src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnacceptableNumberOfNonOptionsException.java
rename to src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnavailableOptionException.java
index c5775fb3458..d4d0655ebe6 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnacceptableNumberOfNonOptionsException.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnavailableOptionException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -55,30 +55,21 @@
package jdk.internal.joptsimple;
-import static java.util.Collections.*;
+import java.util.List;
/**
- * Thrown when the option parser detects an unacceptable number of {@code linkplain NonOptionArgumentSpec
- * non-option arguments}.
- *
- * @author Paul Holser
+ * Thrown when options marked as allowed are specified on the command line, but the options they depend upon are
+ * present/not present.
*/
-class UnacceptableNumberOfNonOptionsException extends OptionException {
+class UnavailableOptionException extends OptionException {
private static final long serialVersionUID = -1L;
- private final int minimum;
- private final int maximum;
- private final int actual;
- UnacceptableNumberOfNonOptionsException( int minimum, int maximum, int actual ) {
- super( singletonList( NonOptionArgumentSpec.NAME ) );
-
- this.minimum = minimum;
- this.maximum = maximum;
- this.actual = actual;
+ UnavailableOptionException( List extends OptionSpec>> forbiddenOptions ) {
+ super( forbiddenOptions );
}
@Override
- public String getMessage() {
- return String.format( "actual = %d, minimum = %d, maximum = %d", actual, minimum, maximum );
+ Object[] messageArguments() {
+ return new Object[] { multipleOptionString() };
}
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnconfiguredOptionException.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnconfiguredOptionException.java
index 0783b7a684b..6f66ee8bccb 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnconfiguredOptionException.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnconfiguredOptionException.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -55,7 +55,7 @@
package jdk.internal.joptsimple;
-import java.util.Collection;
+import java.util.List;
import static java.util.Collections.*;
@@ -71,12 +71,12 @@ class UnconfiguredOptionException extends OptionException {
this( singletonList( option ) );
}
- UnconfiguredOptionException( Collection options ) {
+ UnconfiguredOptionException( List options ) {
super( options );
}
@Override
- public String getMessage() {
- return "Option " + multipleOptionMessage() + " has not been configured on this parser";
+ Object[] messageArguments() {
+ return new Object[] { multipleOptionString() };
}
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnrecognizedOptionException.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnrecognizedOptionException.java
index b9ec16abb0a..cbf93943aa4 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnrecognizedOptionException.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnrecognizedOptionException.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -70,7 +70,7 @@ class UnrecognizedOptionException extends OptionException {
}
@Override
- public String getMessage() {
- return singleOptionMessage() + " is not a recognized option";
+ Object[] messageArguments() {
+ return new Object[] { singleOptionString() };
}
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ValueConversionException.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ValueConversionException.java
index 3ea4938d21c..767b994fd8e 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ValueConversionException.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ValueConversionException.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ValueConverter.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ValueConverter.java
index db08b2550d1..2a761262c27 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ValueConverter.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ValueConverter.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -76,7 +76,7 @@ public interface ValueConverter {
*
* @return the target class for conversion
*/
- Class valueType();
+ Class extends V> valueType();
/**
* Gives a string that describes the pattern of the values this converter expects, if any. For example, a date
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/AbbreviationMap.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/AbbreviationMap.java
index 2646b7372b7..8df4556b02e 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/AbbreviationMap.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/AbbreviationMap.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -84,37 +84,41 @@ import java.util.TreeMap;
*
* @param a constraint on the types of the values in the map
* @author Paul Holser
- * @see Perl's Text::Abbrev module
+ * @see Perl's Text::Abbrev module
+ * @see Radix tree
*/
-public class AbbreviationMap {
+public class AbbreviationMap implements OptionNameMap {
+ private final Map> children = new TreeMap<>();
+
private String key;
private V value;
- private final Map> children = new TreeMap>();
private int keysBeyond;
/**
* Tells whether the given key is in the map, or whether the given key is a unique
* abbreviation of a key that is in the map.
*
- * @param aKey key to look up
+ * @param key key to look up
* @return {@code true} if {@code key} is present in the map
* @throws NullPointerException if {@code key} is {@code null}
*/
- public boolean contains( String aKey ) {
- return get( aKey ) != null;
+ @Override
+ public boolean contains(String key) {
+ return get(key) != null;
}
/**
* Answers the value associated with the given key. The key can be a unique
* abbreviation of a key that is in the map.
*
- * @param aKey key to look up
+ * @param key key to look up
* @return the value associated with {@code aKey}; or {@code null} if there is no
* such value or {@code aKey} is not a unique abbreviation of a key in the map
* @throws NullPointerException if {@code aKey} is {@code null}
*/
- public V get( String aKey ) {
- char[] chars = charsOf( aKey );
+ @Override
+ public V get( String key ) {
+ char[] chars = charsOf( key );
AbbreviationMap child = this;
for ( char each : chars ) {
@@ -130,18 +134,19 @@ public class AbbreviationMap {
* Associates a given value with a given key. If there was a previous
* association, the old value is replaced with the new one.
*
- * @param aKey key to create in the map
+ * @param key key to create in the map
* @param newValue value to associate with the key
* @throws NullPointerException if {@code aKey} or {@code newValue} is {@code null}
* @throws IllegalArgumentException if {@code aKey} is a zero-length string
*/
- public void put( String aKey, V newValue ) {
+ @Override
+ public void put( String key, V newValue ) {
if ( newValue == null )
throw new NullPointerException();
- if ( aKey.length() == 0 )
+ if ( key.length() == 0 )
throw new IllegalArgumentException();
- char[] chars = charsOf( aKey );
+ char[] chars = charsOf(key);
add( chars, newValue, 0, chars.length );
}
@@ -154,6 +159,7 @@ public class AbbreviationMap {
* @throws NullPointerException if {@code keys} or {@code newValue} is {@code null}
* @throws IllegalArgumentException if any of {@code keys} is a zero-length string
*/
+ @Override
public void putAll( Iterable keys, V newValue ) {
for ( String each : keys )
put( each, newValue );
@@ -170,7 +176,7 @@ public class AbbreviationMap {
char nextChar = chars[ offset ];
AbbreviationMap child = children.get( nextChar );
if ( child == null ) {
- child = new AbbreviationMap();
+ child = new AbbreviationMap<>();
children.put( nextChar, child );
}
@@ -188,15 +194,16 @@ public class AbbreviationMap {
/**
* If the map contains the given key, dissociates the key from its value.
*
- * @param aKey key to remove
+ * @param key key to remove
* @throws NullPointerException if {@code aKey} is {@code null}
* @throws IllegalArgumentException if {@code aKey} is a zero-length string
*/
- public void remove( String aKey ) {
- if ( aKey.length() == 0 )
+ @Override
+ public void remove( String key ) {
+ if ( key.length() == 0 )
throw new IllegalArgumentException();
- char[] keyChars = charsOf( aKey );
+ char[] keyChars = charsOf(key);
remove( keyChars, 0, keyChars.length );
}
@@ -242,8 +249,9 @@ public class AbbreviationMap {
*
* @return a Java map corresponding to this abbreviation map
*/
+ @Override
public Map toJavaUtilMap() {
- Map mappings = new TreeMap();
+ Map mappings = new TreeMap<>();
addToMappings( mappings );
return mappings;
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Classes.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Classes.java
index f75025ccd19..e5e47469789 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Classes.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Classes.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -62,7 +62,7 @@ import java.util.Map;
* @author Paul Holser
*/
public final class Classes {
- private static final Map, Class>> WRAPPERS = new HashMap, Class>>( 13 );
+ private static final Map, Class>> WRAPPERS = new HashMap<>( 13 );
static {
WRAPPERS.put( boolean.class, Boolean.class );
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Columns.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Columns.java
index a3859f7d1cf..283f102e0d4 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Columns.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Columns.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -58,7 +58,6 @@ package jdk.internal.joptsimple.internal;
import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.List;
-import java.util.Locale;
import static java.text.BreakIterator.*;
@@ -82,7 +81,7 @@ class Columns {
List options = piecesOf( row.option, optionWidth );
List descriptions = piecesOf( row.description, descriptionWidth );
- List rows = new ArrayList();
+ List rows = new ArrayList<>();
for ( int i = 0; i < Math.max( options.size(), descriptions.size() ); ++i )
rows.add( new Row( itemOrEmpty( options, i ), itemOrEmpty( descriptions, i ) ) );
@@ -94,7 +93,7 @@ class Columns {
}
private List piecesOf( String raw, int width ) {
- List pieces = new ArrayList();
+ List pieces = new ArrayList<>();
for ( String each : raw.trim().split( LINE_SEPARATOR ) )
pieces.addAll( piecesOfEmbeddedLine( each, width ) );
@@ -103,9 +102,9 @@ class Columns {
}
private List piecesOfEmbeddedLine( String line, int width ) {
- List pieces = new ArrayList();
+ List pieces = new ArrayList<>();
- BreakIterator words = BreakIterator.getLineInstance( Locale.US );
+ BreakIterator words = BreakIterator.getLineInstance();
words.setText( line );
StringBuilder nextPiece = new StringBuilder();
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/ConstructorInvokingValueConverter.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/ConstructorInvokingValueConverter.java
index 720c6e4b8c2..5ff8f7ce55d 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/ConstructorInvokingValueConverter.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/ConstructorInvokingValueConverter.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Messages.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Messages.java
new file mode 100644
index 00000000000..05c593e1ac9
--- /dev/null
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Messages.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package jdk.internal.joptsimple.internal;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+/**
+ * @author Paul Holser
+ */
+public class Messages {
+ private Messages() {
+ throw new UnsupportedOperationException();
+ }
+
+ public static String message( Locale locale, String bundleName, Class> type, String key, Object... args ) {
+ ResourceBundle bundle = ResourceBundle.getBundle( bundleName, locale );
+ String template = bundle.getString( type.getName() + '.' + key );
+ MessageFormat format = new MessageFormat( template );
+ format.setLocale( locale );
+ return format.format( args );
+ }
+}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/MethodInvokingValueConverter.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/MethodInvokingValueConverter.java
index 599728bb67b..1546110f7fb 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/MethodInvokingValueConverter.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/MethodInvokingValueConverter.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Objects.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/OptionNameMap.java
similarity index 80%
rename from src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Objects.java
rename to src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/OptionNameMap.java
index 2c2b696cd0a..606f5111454 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Objects.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/OptionNameMap.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -55,22 +55,23 @@
package jdk.internal.joptsimple.internal;
-/**
- * @author Paul Holser
- */
-public final class Objects {
- private Objects() {
- throw new UnsupportedOperationException();
- }
+import java.util.Map;
- /**
- * Rejects {@code null} references.
- *
- * @param target reference to check
- * @throws NullPointerException if {@code target} is {@code null}
- */
- public static void ensureNotNull( Object target ) {
- if ( target == null )
- throw new NullPointerException();
- }
+/**
+ * Map-like interface for storing String-value pairs.
+ *
+ * @param type of values stored in the map
+ */
+public interface OptionNameMap {
+ boolean contains( String key );
+
+ V get( String key );
+
+ void put( String key, V newValue );
+
+ void putAll( Iterable keys, V newValue );
+
+ void remove( String key );
+
+ Map toJavaUtilMap();
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Reflection.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Reflection.java
index 240ad24394c..16237447e37 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Reflection.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Reflection.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -98,22 +98,20 @@ public final class Reflection {
private static ValueConverter valueOfConverter( Class clazz ) {
try {
- Method valueOf = clazz.getDeclaredMethod( "valueOf", String.class );
+ Method valueOf = clazz.getMethod( "valueOf", String.class );
if ( meetsConverterRequirements( valueOf, clazz ) )
- return new MethodInvokingValueConverter( valueOf, clazz );
+ return new MethodInvokingValueConverter<>( valueOf, clazz );
return null;
- }
- catch ( NoSuchMethodException ignored ) {
+ } catch ( NoSuchMethodException ignored ) {
return null;
}
}
private static ValueConverter constructorConverter( Class clazz ) {
try {
- return new ConstructorInvokingValueConverter( clazz.getConstructor( String.class ) );
- }
- catch ( NoSuchMethodException ignored ) {
+ return new ConstructorInvokingValueConverter<>( clazz.getConstructor( String.class ) );
+ } catch ( NoSuchMethodException ignored ) {
return null;
}
}
@@ -130,8 +128,7 @@ public final class Reflection {
public static T instantiate( Constructor constructor, Object... args ) {
try {
return constructor.newInstance( args );
- }
- catch ( Exception ex ) {
+ } catch ( Exception ex ) {
throw reflectionException( ex );
}
}
@@ -147,8 +144,7 @@ public final class Reflection {
public static Object invoke( Method method, Object... args ) {
try {
return method.invoke( null, args );
- }
- catch ( Exception ex ) {
+ } catch ( Exception ex ) {
throw reflectionException( ex );
}
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/ReflectionException.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/ReflectionException.java
index 3e98d8f244c..5a62a18e235 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/ReflectionException.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/ReflectionException.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Row.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Row.java
index 0ce8bcf0cc9..dfce9b70d22 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Row.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Row.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Rows.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Rows.java
index 0d0e4c2d0e0..a6552e6d63c 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Rows.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Rows.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -55,8 +55,8 @@
package jdk.internal.joptsimple.internal;
-import java.util.LinkedHashSet;
-import java.util.Set;
+import java.util.ArrayList;
+import java.util.List;
import static java.lang.Math.*;
@@ -68,7 +68,8 @@ import static jdk.internal.joptsimple.internal.Strings.*;
public class Rows {
private final int overallWidth;
private final int columnSeparatorWidth;
- private final Set rows = new LinkedHashSet();
+ private final List rows = new ArrayList<>();
+
private int widthOfWidestOption;
private int widthOfWidestDescription;
@@ -87,7 +88,7 @@ public class Rows {
widthOfWidestDescription = max( widthOfWidestDescription, row.description.length() );
}
- private void reset() {
+ public void reset() {
rows.clear();
widthOfWidestOption = 0;
widthOfWidestDescription = 0;
@@ -96,7 +97,7 @@ public class Rows {
public void fitToWidth() {
Columns columns = new Columns( optionWidth(), descriptionWidth() );
- Set fitted = new LinkedHashSet();
+ List fitted = new ArrayList<>();
for ( Row each : rows )
fitted.addAll( columns.fit( each ) );
@@ -122,7 +123,7 @@ public class Rows {
}
private int descriptionWidth() {
- return min( ( overallWidth - columnSeparatorWidth ) / 2, widthOfWidestDescription );
+ return min( overallWidth - optionWidth() - columnSeparatorWidth, widthOfWidestDescription );
}
private StringBuilder pad( StringBuilder buffer, String s, int length ) {
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/SimpleOptionNameMap.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/SimpleOptionNameMap.java
new file mode 100644
index 00000000000..860937794d0
--- /dev/null
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/SimpleOptionNameMap.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package jdk.internal.joptsimple.internal;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * An {@code OptionNameMap} which wraps and behaves like {@code HashMap}.
+ */
+public class SimpleOptionNameMap implements OptionNameMap {
+ private final Map map = new HashMap<>();
+
+ @Override
+ public boolean contains( String key ) {
+ return map.containsKey( key );
+ }
+
+ @Override
+ public V get( String key ) {
+ return map.get( key );
+ }
+
+ @Override
+ public void put( String key, V newValue ) {
+ map.put( key, newValue );
+ }
+
+ @Override
+ public void putAll( Iterable keys, V newValue ) {
+ for ( String each : keys )
+ map.put( each, newValue );
+ }
+
+ @Override
+ public void remove( String key ) {
+ map.remove( key );
+ }
+
+ @Override
+ public Map toJavaUtilMap() {
+ return new HashMap<>( map );
+ }
+}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Strings.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Strings.java
index 038b3f0ce6b..e989e0cd5da 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Strings.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Strings.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -56,7 +56,6 @@
package jdk.internal.joptsimple.internal;
import java.util.Iterator;
-import java.util.List;
import static java.lang.System.*;
import static java.util.Arrays.*;
@@ -66,7 +65,6 @@ import static java.util.Arrays.*;
*/
public final class Strings {
public static final String EMPTY = "";
- public static final String SINGLE_QUOTE = "'";
public static final String LINE_SEPARATOR = getProperty( "line.separator" );
private Strings() {
@@ -96,7 +94,7 @@ public final class Strings {
* @return {@code true} if the target string is null or empty
*/
public static boolean isNullOrEmpty( String target ) {
- return target == null || EMPTY.equals( target );
+ return target == null || target.isEmpty();
}
@@ -132,7 +130,7 @@ public final class Strings {
* @param separator the separator
* @return the joined string
*/
- public static String join( List pieces, String separator ) {
+ public static String join( Iterable pieces, String separator ) {
StringBuilder buffer = new StringBuilder();
for ( Iterator iter = pieces.iterator(); iter.hasNext(); ) {
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/DateConverter.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/DateConverter.java
index f90585300d1..0f3cabed5f5 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/DateConverter.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/DateConverter.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -59,9 +59,11 @@ import java.text.DateFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.Locale;
import jdk.internal.joptsimple.ValueConversionException;
import jdk.internal.joptsimple.ValueConverter;
+import jdk.internal.joptsimple.internal.Messages;
/**
* Converts values to {@link Date}s using a {@link DateFormat} object.
@@ -121,10 +123,22 @@ public class DateConverter implements ValueConverter {
}
private String message( String value ) {
- String message = "Value [" + value + "] does not match date/time pattern";
- if ( formatter instanceof SimpleDateFormat )
- message += " [" + ( (SimpleDateFormat) formatter ).toPattern() + ']';
+ String key;
+ Object[] arguments;
- return message;
+ if ( formatter instanceof SimpleDateFormat ) {
+ key = "with.pattern.message";
+ arguments = new Object[] { value, ( (SimpleDateFormat) formatter ).toPattern() };
+ } else {
+ key = "without.pattern.message";
+ arguments = new Object[] { value };
+ }
+
+ return Messages.message(
+ Locale.getDefault(),
+ "jdk.internal.joptsimple.ExceptionMessages",
+ DateConverter.class,
+ key,
+ arguments );
}
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/EnumConverter.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/EnumConverter.java
new file mode 100644
index 00000000000..7d2a2388a68
--- /dev/null
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/EnumConverter.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package jdk.internal.joptsimple.util;
+
+import java.text.MessageFormat;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.ResourceBundle;
+
+import jdk.internal.joptsimple.ValueConversionException;
+import jdk.internal.joptsimple.ValueConverter;
+
+/**
+ * Converts values to {@link java.lang.Enum}s.
+ *
+ * @author Christian Ohr
+ */
+public abstract class EnumConverter> implements ValueConverter {
+ private final Class clazz;
+
+ private String delimiters = "[,]";
+
+ /**
+ * This constructor must be called by subclasses, providing the enum class as the parameter.
+ *
+ * @param clazz enum class
+ */
+ protected EnumConverter( Class clazz ) {
+ this.clazz = clazz;
+ }
+
+ @Override
+ public E convert( String value ) {
+ for ( E each : valueType().getEnumConstants() ) {
+ if ( each.name().equalsIgnoreCase( value ) ) {
+ return each;
+ }
+ }
+
+ throw new ValueConversionException( message( value ) );
+ }
+
+ @Override
+ public Class valueType() {
+ return clazz;
+ }
+
+ /**
+ * Sets the delimiters for the message string. Must be a 3-letter string,
+ * where the first character is the prefix, the second character is the
+ * delimiter between the values, and the 3rd character is the suffix.
+ *
+ * @param delimiters delimiters for message string. Default is [,]
+ */
+ public void setDelimiters( String delimiters ) {
+ this.delimiters = delimiters;
+ }
+
+ @Override
+ public String valuePattern() {
+ EnumSet values = EnumSet.allOf( valueType() );
+
+ StringBuilder builder = new StringBuilder();
+ builder.append( delimiters.charAt(0) );
+ for ( Iterator i = values.iterator(); i.hasNext(); ) {
+ builder.append( i.next().toString() );
+ if ( i.hasNext() )
+ builder.append( delimiters.charAt( 1 ) );
+ }
+ builder.append( delimiters.charAt( 2 ) );
+
+ return builder.toString();
+ }
+
+ private String message( String value ) {
+ ResourceBundle bundle = ResourceBundle.getBundle( "jdk.internal.joptsimple.ExceptionMessages" );
+ Object[] arguments = new Object[] { value, valuePattern() };
+ String template = bundle.getString( EnumConverter.class.getName() + ".message" );
+ return new MessageFormat( template ).format( arguments );
+ }
+}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/InetAddressConverter.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/InetAddressConverter.java
index c6c7366509c..6d7056cd616 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/InetAddressConverter.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/InetAddressConverter.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -57,9 +57,11 @@ package jdk.internal.joptsimple.util;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.util.Locale;
import jdk.internal.joptsimple.ValueConversionException;
import jdk.internal.joptsimple.ValueConverter;
+import jdk.internal.joptsimple.internal.Messages;
/**
* Converts values to {@link java.net.InetAddress} using {@link InetAddress#getByName(String) getByName}.
@@ -70,8 +72,9 @@ public class InetAddressConverter implements ValueConverter {
public InetAddress convert( String value ) {
try {
return InetAddress.getByName( value );
- } catch ( UnknownHostException e ) {
- throw new ValueConversionException( "Cannot convert value [" + value + " into an InetAddress", e );
+ }
+ catch ( UnknownHostException e ) {
+ throw new ValueConversionException( message( value ) );
}
}
@@ -82,4 +85,13 @@ public class InetAddressConverter implements ValueConverter {
public String valuePattern() {
return null;
}
+
+ private String message( String value ) {
+ return Messages.message(
+ Locale.getDefault(),
+ "jdk.internal.joptsimple.ExceptionMessages",
+ InetAddressConverter.class,
+ "message",
+ value );
+ }
}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/KeyValuePair.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/KeyValuePair.java
index 430e0c89b75..47603adfca4 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/KeyValuePair.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/KeyValuePair.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -60,7 +60,7 @@ import static jdk.internal.joptsimple.internal.Strings.*;
/**
* A simple string key/string value pair.
*
- * This is useful as an argument type for options whose values take on the form key=value, such as JVM
+ *
This is useful as an argument type for options whose values take on the form {@code key=value}, such as JVM
* command line system properties.
*
* @author Paul Holser
@@ -75,7 +75,7 @@ public final class KeyValuePair {
}
/**
- * Parses a string assumed to be of the form key=value into its parts.
+ * Parses a string assumed to be of the form {@code key=value} into its parts.
*
* @param asString key-value string
* @return a key-value pair
@@ -84,7 +84,7 @@ public final class KeyValuePair {
public static KeyValuePair valueOf( String asString ) {
int equalsIndex = asString.indexOf( '=' );
if ( equalsIndex == -1 )
- return new KeyValuePair( asString, EMPTY );
+ return new KeyValuePair( asString, null );
String aKey = asString.substring( 0, equalsIndex );
String aValue = equalsIndex == asString.length() - 1 ? EMPTY : asString.substring( equalsIndex + 1 );
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/PathConverter.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/PathConverter.java
new file mode 100644
index 00000000000..f542e8e0a65
--- /dev/null
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/PathConverter.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.joptsimple.util;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.text.MessageFormat;
+import java.util.ResourceBundle;
+
+import jdk.internal.joptsimple.ValueConversionException;
+import jdk.internal.joptsimple.ValueConverter;
+
+/**
+ * Converts command line options to {@link Path} objects and checks the status of the underlying file.
+ */
+public class PathConverter implements ValueConverter {
+ private final PathProperties[] pathProperties;
+
+ public PathConverter( PathProperties... pathProperties ) {
+ this.pathProperties = pathProperties;
+ }
+
+ @Override
+ public Path convert( String value ) {
+ Path path = Paths.get(value);
+
+ if ( pathProperties != null ) {
+ for ( PathProperties each : pathProperties ) {
+ if ( !each.accept( path ) )
+ throw new ValueConversionException( message( each.getMessageKey(), path.toString() ) );
+ }
+ }
+
+ return path;
+ }
+
+ @Override
+ public Class valueType() {
+ return Path.class;
+ }
+
+ @Override
+ public String valuePattern() {
+ return null;
+ }
+
+ private String message( String errorKey, String value ) {
+ ResourceBundle bundle = ResourceBundle.getBundle( "jdk.internal.joptsimple.ExceptionMessages" );
+ Object[] arguments = new Object[] { value, valuePattern() };
+ String template = bundle.getString( PathConverter.class.getName() + "." + errorKey + ".message" );
+ return new MessageFormat( template ).format( arguments );
+ }
+}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/PathProperties.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/PathProperties.java
new file mode 100644
index 00000000000..22066da2bc2
--- /dev/null
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/PathProperties.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.joptsimple.util;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+/**
+ * Enum for checking common conditions of files and directories.
+ *
+ * @see jdk.internal.joptsimple.util.PathConverter
+ */
+public enum PathProperties {
+ FILE_EXISTING( "file.existing" ) {
+ @Override
+ boolean accept( Path path ) {
+ return Files.isRegularFile( path );
+ }
+ },
+ DIRECTORY_EXISTING( "directory.existing" ) {
+ @Override
+ boolean accept( Path path ) {
+ return Files.isDirectory( path );
+ }
+ },
+ NOT_EXISTING( "file.not.existing" ) {
+ @Override
+ boolean accept( Path path ) {
+ return Files.notExists( path );
+ }
+ },
+ FILE_OVERWRITABLE( "file.overwritable" ) {
+ @Override
+ boolean accept( Path path ) {
+ return FILE_EXISTING.accept( path ) && WRITABLE.accept( path );
+ }
+ },
+ READABLE( "file.readable" ) {
+ @Override
+ boolean accept( Path path ) {
+ return Files.isReadable( path );
+ }
+ },
+ WRITABLE( "file.writable" ) {
+ @Override
+ boolean accept( Path path ) {
+ return Files.isWritable( path );
+ }
+ };
+
+ private final String messageKey;
+
+ private PathProperties( String messageKey ) {
+ this.messageKey = messageKey;
+ }
+
+ abstract boolean accept( Path path );
+
+ String getMessageKey() {
+ return messageKey;
+ }
+}
diff --git a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/RegexMatcher.java b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/RegexMatcher.java
index b6ceee5557e..f51b375d86f 100644
--- a/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/RegexMatcher.java
+++ b/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/RegexMatcher.java
@@ -31,7 +31,7 @@
*
* The MIT License
*
- * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ * Copyright (c) 2004-2015 Paul R. Holser, Jr.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -55,9 +55,11 @@
package jdk.internal.joptsimple.util;
+import java.util.Locale;
import java.util.regex.Pattern;
import static java.util.regex.Pattern.*;
+import static jdk.internal.joptsimple.internal.Messages.message;
import jdk.internal.joptsimple.ValueConversionException;
import jdk.internal.joptsimple.ValueConverter;
@@ -96,8 +98,7 @@ public class RegexMatcher implements ValueConverter {
public String convert( String value ) {
if ( !pattern.matcher( value ).matches() ) {
- throw new ValueConversionException(
- "Value [" + value + "] did not match regex [" + pattern.pattern() + ']' );
+ raiseValueConversionFailure( value );
}
return value;
@@ -110,4 +111,15 @@ public class RegexMatcher implements ValueConverter {
public String valuePattern() {
return pattern.pattern();
}
+
+ private void raiseValueConversionFailure( String value ) {
+ String message = message(
+ Locale.getDefault(),
+ "jdk.internal.joptsimple.ExceptionMessages",
+ RegexMatcher.class,
+ "message",
+ value,
+ pattern.pattern() );
+ throw new ValueConversionException( message );
+ }
}
diff --git a/src/jdk.internal.opt/share/legal/jopt-simple.md b/src/jdk.internal.opt/share/legal/jopt-simple.md
index 0d40507edaf..c08b3b4b94c 100644
--- a/src/jdk.internal.opt/share/legal/jopt-simple.md
+++ b/src/jdk.internal.opt/share/legal/jopt-simple.md
@@ -1,4 +1,4 @@
-## jopt-simple v4.6
+## jopt-simple v5.0.4
### MIT License
diff --git a/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java b/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java
index eca78e675a2..0f6b488bf5e 100644
--- a/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java
+++ b/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java
@@ -1224,7 +1224,7 @@ public class JmodTask {
all.put(CMD_FILENAME, new OptionDescriptor() {
@Override
- public Collection options() {
+ public List options() {
List