# HG changeset patch # User chegar # Date 1453799931 0 # Node ID 462f93ab37f2a9b7086ed3b28547b1416c001096 # Parent 4a652e4ca9523422149958673033e0ac740d5e1e 8148154: Integrate JOpt Simple for internal usage by JDK tools Reviewed-by: alanb, redestad, rriggs diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/AbstractOptionSpec.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/AbstractOptionSpec.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import static java.util.Collections.*; + +import jdk.internal.joptsimple.internal.Reflection; +import jdk.internal.joptsimple.internal.ReflectionException; + +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(); + private final String description; + private boolean forHelp; + + protected AbstractOptionSpec( String option ) { + this( singletonList( option ), EMPTY ); + } + + protected AbstractOptionSpec( Collection options, String description ) { + arrangeOptions( options ); + + this.description = description; + } + + public final Collection options() { + return unmodifiableList( options ); + } + + public final List values( OptionSet detectedOptions ) { + return detectedOptions.valuesOf( this ); + } + + public final V value( OptionSet detectedOptions ) { + return detectedOptions.valueOf( this ); + } + + public String description() { + return description; + } + + public final AbstractOptionSpec forHelp() { + forHelp = true; + return this; + } + + public final boolean isForHelp() { + return forHelp; + } + + public boolean representsNonOptions() { + return false; + } + + protected abstract V convert( String argument ); + + 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 ); + } + } + + protected String argumentTypeIndicatorFrom( ValueConverter converter ) { + if ( converter == null ) + return null; + + String pattern = converter.valuePattern(); + return pattern == null ? converter.valueType().getName() : pattern; + } + + abstract void handleOption( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions, + String detectedArgument ); + + private void arrangeOptions( Collection unarranged ) { + if ( unarranged.size() == 1 ) { + options.addAll( unarranged ); + return; + } + + List shortOptions = new ArrayList(); + List longOptions = new ArrayList(); + + for ( String each : unarranged ) { + if ( each.length() == 1 ) + shortOptions.add( each ); + else + longOptions.add( each ); + } + + sort( shortOptions ); + sort( longOptions ); + + options.addAll( shortOptions ); + options.addAll( longOptions ); + } + + @Override + public boolean equals( Object that ) { + if ( !( that instanceof AbstractOptionSpec ) ) + return false; + + AbstractOptionSpec other = (AbstractOptionSpec) that; + return options.equals( other.options ); + } + + @Override + public int hashCode() { + return options.hashCode(); + } + + @Override + public String toString() { + return options.toString(); + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/AlternativeLongOptionSpec.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/AlternativeLongOptionSpec.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import static java.util.Collections.*; + +import static jdk.internal.joptsimple.ParserRules.*; + +/** + * Represents the "-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" ); + + describedAs( "opt=value" ); + } + + @Override + protected void detectOptionArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions ) { + if ( !arguments.hasMore() ) + throw new OptionMissingRequiredArgumentException( options() ); + + arguments.treatNextAsLongOption(); + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ArgumentAcceptingOptionSpec.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ArgumentAcceptingOptionSpec.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.StringTokenizer; + +import static java.util.Collections.*; + +import static jdk.internal.joptsimple.internal.Objects.*; +import static jdk.internal.joptsimple.internal.Reflection.*; +import static jdk.internal.joptsimple.internal.Strings.*; + +/** + *

Specification of an option that accepts an argument.

+ * + *

Instances are returned from {@link OptionSpecBuilder} methods to allow the formation of parser directives as + * sentences in a "fluent interface" language. For example:

+ * + *
+ *   
+ *   OptionParser parser = new OptionParser();
+ *   parser.accepts( "c" ).withRequiredArg().ofType( Integer.class );
+ *   
+ * 
+ * + *

If no methods are invoked on an instance of this class, then that instance's option will treat its argument as + * a {@link String}.

+ * + * @param represents the type of the arguments this option accepts + * @author Paul Holser + */ +public abstract class ArgumentAcceptingOptionSpec extends AbstractOptionSpec { + private static final char NIL_VALUE_SEPARATOR = '\u0000'; + + private boolean optionRequired; + private final boolean argumentRequired; + 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 ); + + this.argumentRequired = argumentRequired; + } + + ArgumentAcceptingOptionSpec( Collection options, boolean argumentRequired, String description ) { + super( options, description ); + + this.argumentRequired = argumentRequired; + } + + /** + *

Specifies a type to which arguments of this spec's option are to be converted.

+ * + *

JOpt Simple accepts types that have either:

+ * + *
    + *
  1. a public static method called {@code valueOf} which accepts a single argument of type {@link String} + * and whose return type is the same as the class on which the method is declared. The {@code java.lang} + * primitive wrapper classes have such methods.
  2. + * + *
  3. a public constructor which accepts a single argument of type {@link String}.
  4. + *
+ * + *

This class converts arguments using those methods in that order; that is, {@code valueOf} would be invoked + * before a one-{@link String}-arg constructor would.

+ * + *

Invoking this method will trump any previous calls to this method or to + * {@link #withValuesConvertedBy(ValueConverter)}.

+ * + * @param represents the runtime class of the desired option argument type + * @param argumentType desired type of arguments to this spec's option + * @return self, so that the caller can add clauses to the fluent interface sentence + * @throws NullPointerException if the type is {@code null} + * @throws IllegalArgumentException if the type does not have the standard conversion methods + */ + public final ArgumentAcceptingOptionSpec ofType( Class argumentType ) { + return withValuesConvertedBy( findConverter( argumentType ) ); + } + + /** + *

Specifies a converter to use to translate arguments of this spec's option into Java objects. This is useful + * when converting to types that do not have the requisite factory method or constructor for + * {@link #ofType(Class)}.

+ * + *

Invoking this method will trump any previous calls to this method or to {@link #ofType(Class)}. + * + * @param represents the runtime class of the desired option argument type + * @param aConverter the converter to use + * @return self, so that the caller can add clauses to the fluent interface sentence + * @throws NullPointerException if the converter is {@code null} + */ + @SuppressWarnings( "unchecked" ) + public final ArgumentAcceptingOptionSpec withValuesConvertedBy( ValueConverter aConverter ) { + if ( aConverter == null ) + throw new NullPointerException( "illegal null converter" ); + + converter = (ValueConverter) aConverter; + return (ArgumentAcceptingOptionSpec) this; + } + + /** + *

Specifies a description for the argument of the option that this spec represents. This description is used + * when generating help information about the parser.

+ * + * @param description describes the nature of the argument of this spec's option + * @return self, so that the caller can add clauses to the fluent interface sentence + */ + public final ArgumentAcceptingOptionSpec describedAs( String description ) { + argumentDescription = description; + return this; + } + + /** + *

Specifies a value separator for the argument of the option that this spec represents. This allows a single + * option argument to represent multiple values for the option. For example:

+ * + *
+     *   
+     *   parser.accepts( "z" ).withRequiredArg()
+     *       .withValuesSeparatedBy( ',' );
+     *   OptionSet options = parser.parse( new String[] { "-z", "foo,bar,baz", "-z",
+     *       "fizz", "-z", "buzz" } );
+     *   
+     * 
+ * + *

Then {@code options.valuesOf( "z" )} would yield the list {@code [foo, bar, baz, fizz, buzz]}.

+ * + *

You cannot use Unicode U+0000 as the separator.

+ * + * @param separator a character separator + * @return self, so that the caller can add clauses to the fluent interface sentence + * @throws IllegalArgumentException if the separator is Unicode U+0000 + */ + public final ArgumentAcceptingOptionSpec withValuesSeparatedBy( char separator ) { + if ( separator == NIL_VALUE_SEPARATOR ) + throw new IllegalArgumentException( "cannot use U+0000 as separator" ); + + valueSeparator = String.valueOf( separator ); + return this; + } + + /** + *

Specifies a value separator for the argument of the option that this spec represents. This allows a single + * option argument to represent multiple values for the option. For example:

+ * + *
+     *   
+     *   parser.accepts( "z" ).withRequiredArg()
+     *       .withValuesSeparatedBy( ":::" );
+     *   OptionSet options = parser.parse( new String[] { "-z", "foo:::bar:::baz", "-z",
+     *       "fizz", "-z", "buzz" } );
+     *   
+     * 
+ * + *

Then {@code options.valuesOf( "z" )} would yield the list {@code [foo, bar, baz, fizz, buzz]}.

+ * + *

You cannot use Unicode U+0000 in the separator.

+ * + * @param separator a string separator + * @return self, so that the caller can add clauses to the fluent interface sentence + * @throws IllegalArgumentException if the separator contains Unicode U+0000 + */ + public final ArgumentAcceptingOptionSpec withValuesSeparatedBy( String separator ) { + if ( separator.indexOf( NIL_VALUE_SEPARATOR ) != -1 ) + throw new IllegalArgumentException( "cannot use U+0000 in separator" ); + + valueSeparator = separator; + return this; + } + + /** + * Specifies a set of default values for the argument of the option that this spec represents. + * + * @param value the first in the set of default argument values for this spec's option + * @param values the (optional) remainder of the set of default argument values for this spec's option + * @return self, so that the caller can add clauses to the fluent interface sentence + * @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 ) { + addDefaultValue( value ); + defaultsTo( values ); + + return this; + } + + /** + * Specifies a set of default values for the argument of the option that this spec represents. + * + * @param values the set of default argument values for this spec's option + * @return self, so that the caller can add clauses to the fluent interface sentence + * @throws NullPointerException if {@code values} or any elements of {@code values} are {@code null} + */ + public ArgumentAcceptingOptionSpec defaultsTo( V[] values ) { + for ( V each : values ) + addDefaultValue( each ); + + return this; + } + + /** + * Marks this option as required. An {@link OptionException} will be thrown when + * {@link OptionParser#parse(java.lang.String...)} is called, if an option is marked as required and not specified + * on the command line. + * + * @return self, so that the caller can add clauses to the fluent interface sentence + */ + public ArgumentAcceptingOptionSpec required() { + optionRequired = true; + return this; + } + + public boolean isRequired() { + return optionRequired; + } + + private void addDefaultValue( V value ) { + ensureNotNull( value ); + defaultValues.add( value ); + } + + @Override + final void handleOption( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions, + String detectedArgument ) { + + if ( isNullOrEmpty( detectedArgument ) ) + detectOptionArgument( parser, arguments, detectedOptions ); + else + addArguments( detectedOptions, detectedArgument ); + } + + protected void addArguments( OptionSet detectedOptions, String detectedArgument ) { + StringTokenizer lexer = new StringTokenizer( detectedArgument, valueSeparator ); + if ( !lexer.hasMoreTokens() ) + detectedOptions.addWithArgument( this, detectedArgument ); + else { + while ( lexer.hasMoreTokens() ) + detectedOptions.addWithArgument( this, lexer.nextToken() ); + } + } + + protected abstract void detectOptionArgument( OptionParser parser, ArgumentList arguments, + OptionSet detectedOptions ); + + @Override + protected final V convert( String argument ) { + return convertWith( converter, argument ); + } + + protected boolean canConvertArgument( String argument ) { + StringTokenizer lexer = new StringTokenizer( argument, valueSeparator ); + + try { + while ( lexer.hasMoreTokens() ) + convert( lexer.nextToken() ); + return true; + } + catch ( OptionException ignored ) { + return false; + } + } + + protected boolean isArgumentOfNumberType() { + return converter != null && Number.class.isAssignableFrom( converter.valueType() ); + } + + public boolean acceptsArguments() { + return true; + } + + public boolean requiresArgument() { + return argumentRequired; + } + + public String argumentDescription() { + return argumentDescription; + } + + public String argumentTypeIndicator() { + return argumentTypeIndicatorFrom( converter ); + } + + public List defaultValues() { + return unmodifiableList( defaultValues ); + } + + @Override + public boolean equals( Object that ) { + if ( !super.equals( that ) ) + return false; + + ArgumentAcceptingOptionSpec other = (ArgumentAcceptingOptionSpec) that; + return requiresArgument() == other.requiresArgument(); + } + + @Override + public int hashCode() { + return super.hashCode() ^ ( argumentRequired ? 0 : 1 ); + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ArgumentList.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ArgumentList.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import static jdk.internal.joptsimple.ParserRules.*; + +/** + *

Wrapper for an array of command line arguments.

+ * + * @author Paul Holser + */ +class ArgumentList { + private final String[] arguments; + private int currentIndex; + + ArgumentList( String... arguments ) { + this.arguments = arguments.clone(); + } + + boolean hasMore() { + return currentIndex < arguments.length; + } + + String next() { + return arguments[ currentIndex++ ]; + } + + String peek() { + return arguments[ currentIndex ]; + } + + void treatNextAsLongOption() { + if ( HYPHEN_CHAR != arguments[ currentIndex ].charAt( 0 ) ) + arguments[ currentIndex ] = DOUBLE_HYPHEN + arguments[ currentIndex ]; + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/BuiltinHelpFormatter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/BuiltinHelpFormatter.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2009, 2015, 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; + +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 jdk.internal.joptsimple.internal.Rows; +import jdk.internal.joptsimple.internal.Strings; + +import static jdk.internal.joptsimple.ParserRules.*; +import static jdk.internal.joptsimple.internal.Classes.*; +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 + * 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.

+ * + * @author Paul Holser + */ +public class BuiltinHelpFormatter implements HelpFormatter { + private final Rows nonOptionRows; + private final Rows optionRows; + + /** + * Makes a formatter with a pre-configured overall row width and column separator width. + */ + BuiltinHelpFormatter() { + this( 80, 2 ); + } + + /** + * Makes a formatter with a given overall row width and column separator width. + * + * @param desiredOverallWidth how many characters wide to make the overall help display + * @param desiredColumnSeparatorWidth how many characters wide to make the separation between option column and + * description column + */ + public BuiltinHelpFormatter( int desiredOverallWidth, int desiredColumnSeparatorWidth ) { + nonOptionRows = new Rows( desiredOverallWidth * 2, 0 ); + optionRows = new Rows( desiredOverallWidth, desiredColumnSeparatorWidth ); + } + + public String format( Map options ) { + Comparator comparator = + new Comparator() { + public int compare( OptionDescriptor first, OptionDescriptor second ) { + return first.options().iterator().next().compareTo( second.options().iterator().next() ); + } + }; + + Set sorted = new TreeSet( comparator ); + sorted.addAll( options.values() ); + + addRows( sorted ); + + return formattedHelpOutput(); + } + + private String formattedHelpOutput() { + StringBuilder formatted = new StringBuilder(); + String nonOptionDisplay = nonOptionRows.render(); + if ( !Strings.isNullOrEmpty( nonOptionDisplay ) ) + formatted.append( nonOptionDisplay ).append( LINE_SEPARATOR ); + formatted.append( optionRows.render() ); + + return formatted.toString(); + } + + private void addRows( Collection options ) { + addNonOptionsDescription( options ); + + if ( options.isEmpty() ) + optionRows.add( "No options specified", "" ); + else { + addHeaders( options ); + addOptions( options ); + } + + fitRowsToWidth(); + } + + private void addNonOptionsDescription( Collection options ) { + OptionDescriptor nonOptions = findAndRemoveNonOptionsSpec( options ); + if ( shouldShowNonOptionArgumentDisplay( nonOptions ) ) { + nonOptionRows.add( "Non-option arguments:", "" ); + nonOptionRows.add(createNonOptionArgumentsDisplay(nonOptions), ""); + } + } + + private boolean shouldShowNonOptionArgumentDisplay( OptionDescriptor nonOptions ) { + return !Strings.isNullOrEmpty( nonOptions.description() ) + || !Strings.isNullOrEmpty( nonOptions.argumentTypeIndicator() ) + || !Strings.isNullOrEmpty( nonOptions.argumentDescription() ); + } + + private String createNonOptionArgumentsDisplay(OptionDescriptor nonOptions) { + StringBuilder buffer = new StringBuilder(); + maybeAppendOptionInfo( buffer, nonOptions ); + maybeAppendNonOptionsDescription( buffer, nonOptions ); + + return buffer.toString(); + } + + private void maybeAppendNonOptionsDescription( StringBuilder buffer, OptionDescriptor nonOptions ) { + buffer.append( buffer.length() > 0 && !Strings.isNullOrEmpty( nonOptions.description() ) ? " -- " : "" ) + .append( nonOptions.description() ); + } + + private OptionDescriptor findAndRemoveNonOptionsSpec( Collection options ) { + for ( Iterator it = options.iterator(); it.hasNext(); ) { + OptionDescriptor next = it.next(); + if ( next.representsNonOptions() ) { + it.remove(); + return next; + } + } + + throw new AssertionError( "no non-options argument spec" ); + } + + private void addHeaders( Collection options ) { + if ( hasRequiredOption( options ) ) { + optionRows.add("Option (* = required)", "Description"); + optionRows.add("---------------------", "-----------"); + } else { + optionRows.add("Option", "Description"); + optionRows.add("------", "-----------"); + } + } + + private boolean hasRequiredOption( Collection options ) { + for ( OptionDescriptor each : options ) { + if ( each.isRequired() ) + return true; + } + + return false; + } + + private void addOptions( Collection options ) { + for ( OptionDescriptor each : options ) { + if ( !each.representsNonOptions() ) + optionRows.add( createOptionDisplay( each ), createDescriptionDisplay( each ) ); + } + } + + private 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( option ); + + if ( i.hasNext() ) + buffer.append( ", " ); + } + + maybeAppendOptionInfo( buffer, descriptor ); + + 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() ); + } + + private String extractTypeIndicator( OptionDescriptor descriptor ) { + String indicator = descriptor.argumentTypeIndicator(); + + if ( !isNullOrEmpty( indicator ) && !String.class.getName().equals( indicator ) ) + return shortNameOf( indicator ); + + return null; + } + + private 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 ) { + buffer.append( ' ' ).append( start ); + if ( typeIndicator != null ) + buffer.append( typeIndicator ); + + if ( !Strings.isNullOrEmpty( description ) ) { + if ( typeIndicator != null ) + buffer.append( ": " ); + + buffer.append( description ); + } + + buffer.append( end ); + } + + private 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(); + } + + private String createDefaultValuesDisplay( List defaultValues ) { + return defaultValues.size() == 1 ? defaultValues.get( 0 ).toString() : defaultValues.toString(); + } + + private void fitRowsToWidth() { + nonOptionRows.fitToWidth(); + optionRows.fitToWidth(); + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/HelpFormatter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/HelpFormatter.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.Map; + +/** + *

Represents objects charged with taking a set of option descriptions and producing some help text from them.

+ * + * @author Paul Holser + */ +public interface HelpFormatter { + /** + * Produces help text, given a set of option descriptors. + * + * @param options descriptors for the configured options of a parser + * @return text to be used as help + * @see OptionParser#printHelpOn(java.io.Writer) + * @see OptionParser#formatHelpWith(HelpFormatter) + */ + String format( Map options ); +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/IllegalOptionSpecificationException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/IllegalOptionSpecificationException.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import static java.util.Collections.*; + +/** + * Thrown when the option parser is asked to recognize an option with illegal characters in it. + * + * @author Paul Holser + */ +class IllegalOptionSpecificationException extends OptionException { + private static final long serialVersionUID = -1L; + + IllegalOptionSpecificationException( String option ) { + super( singletonList( option ) ); + } + + @Override + public String getMessage() { + return singleOptionMessage() + " is not a legal option character"; + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/MissingRequiredOptionException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/MissingRequiredOptionException.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.Collection; + +/** + * Thrown when an option is marked as required, but not specified on the command line. + * + * @author Emils Solmanis + */ +class MissingRequiredOptionException extends OptionException { + private static final long serialVersionUID = -1L; + + protected MissingRequiredOptionException( Collection options ) { + super( options ); + } + + @Override + public String getMessage() { + return "Missing required option(s) " + multipleOptionMessage(); + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/MultipleArgumentsForOptionException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/MultipleArgumentsForOptionException.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.Collection; + +/** + * Thrown when asking an {@link OptionSet} for a single argument of an option when many have been specified. + * + * @author Paul Holser + */ +class MultipleArgumentsForOptionException extends OptionException { + private static final long serialVersionUID = -1L; + + MultipleArgumentsForOptionException( Collection options ) { + super( options ); + } + + @Override + public String getMessage() { + return "Found multiple arguments for option " + multipleOptionMessage() + ", but you asked for only one"; + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/NoArgumentOptionSpec.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/NoArgumentOptionSpec.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.Collection; +import java.util.List; + +import static java.util.Collections.*; + +/** + * A specification for an option that does not accept arguments. + * + * @author Paul Holser + */ +class NoArgumentOptionSpec extends AbstractOptionSpec { + NoArgumentOptionSpec( String option ) { + this( singletonList( option ), "" ); + } + + NoArgumentOptionSpec( Collection options, String description ) { + super( options, description ); + } + + @Override + void handleOption( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions, + String detectedArgument ) { + + detectedOptions.add( this ); + } + + public boolean acceptsArguments() { + return false; + } + + public boolean requiresArgument() { + return false; + } + + public boolean isRequired() { + return false; + } + + public String argumentDescription() { + return ""; + } + + public String argumentTypeIndicator() { + return ""; + } + + @Override + protected Void convert( String argument ) { + return null; + } + + public List defaultValues() { + return emptyList(); + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/NonOptionArgumentSpec.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/NonOptionArgumentSpec.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.List; + +import static java.util.Arrays.*; +import static java.util.Collections.*; +import static jdk.internal.joptsimple.internal.Reflection.*; + +/** + *

Specification of a command line's non-option arguments.

+ * + *

Instances are returned from {@link OptionParser} methods to allow the formation of parser directives as + * sentences in a "fluent interface" language. For example:

+ * + *
+ *   
+ *   OptionParser parser = new OptionParser();
+ *   parser.nonOptions( "files to be processed" ).ofType( File.class );
+ *   
+ * 
+ * + *

If no methods are invoked on an instance of this class, then that instance's option will treat the non-option + * arguments as {@link String}s.

+ * + * @param represents the type of the non-option arguments + * @author Paul Holser + */ +public class NonOptionArgumentSpec extends AbstractOptionSpec { + static final String NAME = "[arguments]"; + + private ValueConverter converter; + private String argumentDescription = ""; + + NonOptionArgumentSpec() { + this(""); + } + + NonOptionArgumentSpec( String description ) { + super( asList( NAME ), description ); + } + + /** + *

Specifies a type to which the non-option arguments are to be converted.

+ * + *

JOpt Simple accepts types that have either:

+ * + *
    + *
  1. a public static method called {@code valueOf} which accepts a single argument of type {@link String} + * and whose return type is the same as the class on which the method is declared. The {@code java.lang} + * primitive wrapper classes have such methods.
  2. + * + *
  3. a public constructor which accepts a single argument of type {@link String}.
  4. + *
+ * + *

This class converts arguments using those methods in that order; that is, {@code valueOf} would be invoked + * before a one-{@link String}-arg constructor would.

+ * + *

Invoking this method will trump any previous calls to this method or to + * {@link #withValuesConvertedBy(ValueConverter)}.

+ * + * @param represents the runtime class of the desired option argument type + * @param argumentType desired type of arguments to this spec's option + * @return self, so that the caller can add clauses to the fluent interface sentence + * @throws NullPointerException if the type is {@code null} + * @throws IllegalArgumentException if the type does not have the standard conversion methods + */ + @SuppressWarnings( "unchecked" ) + public NonOptionArgumentSpec ofType( Class argumentType ) { + converter = (ValueConverter) findConverter( argumentType ); + return (NonOptionArgumentSpec) this; + } + + /** + *

Specifies a converter to use to translate non-option arguments into Java objects. This is useful + * when converting to types that do not have the requisite factory method or constructor for + * {@link #ofType(Class)}.

+ * + *

Invoking this method will trump any previous calls to this method or to {@link #ofType(Class)}. + * + * @param represents the runtime class of the desired non-option argument type + * @param aConverter the converter to use + * @return self, so that the caller can add clauses to the fluent interface sentence + * @throws NullPointerException if the converter is {@code null} + */ + @SuppressWarnings( "unchecked" ) + public final NonOptionArgumentSpec withValuesConvertedBy( ValueConverter aConverter ) { + if ( aConverter == null ) + throw new NullPointerException( "illegal null converter" ); + + converter = (ValueConverter) aConverter; + return (NonOptionArgumentSpec) this; + } + + /** + *

Specifies a description for the non-option arguments that this spec represents. This description is used + * when generating help information about the parser.

+ * + * @param description describes the nature of the argument of this spec's option + * @return self, so that the caller can add clauses to the fluent interface sentence + */ + public NonOptionArgumentSpec describedAs( String description ) { + argumentDescription = description; + return this; + } + + @Override + protected final V convert( String argument ) { + return convertWith( converter, argument ); + } + + @Override + void handleOption( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions, + String detectedArgument ) { + + detectedOptions.addWithArgument( this, detectedArgument ); + } + + public List defaultValues() { + return emptyList(); + } + + public boolean isRequired() { + return false; + } + + public boolean acceptsArguments() { + return false; + } + + public boolean requiresArgument() { + return false; + } + + public String argumentDescription() { + return argumentDescription; + } + + public String argumentTypeIndicator() { + return argumentTypeIndicatorFrom( converter ); + } + + public boolean representsNonOptions() { + return true; + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionArgumentConversionException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionArgumentConversionException.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.Collection; + +/** + * Thrown when a problem occurs converting an argument of an option from {@link String} to another type. + * + * @author Paul Holser + */ +class OptionArgumentConversionException extends OptionException { + private static final long serialVersionUID = -1L; + + private final String argument; + + OptionArgumentConversionException( Collection options, String argument, Throwable cause ) { + super( options, cause ); + + this.argument = argument; + } + + @Override + public String getMessage() { + return "Cannot parse argument '" + argument + "' of option " + multipleOptionMessage(); + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionDeclarer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionDeclarer.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.Collection; + +/** + * Trains the option parser. This interface aids integration with other code which may expose declaration of options but + * not actual command-line parsing. + * + * @author Paul Holser + * @see OptionParser + */ +public interface OptionDeclarer { + /** + * Tells the parser to recognize the given option. + * + *

This method returns an instance of {@link OptionSpecBuilder} to allow the formation of parser directives + * as sentences in a fluent interface language. For example:

+ * + *

+     *   OptionDeclarer parser = new OptionParser();
+     *   parser.accepts( "c" ).withRequiredArg().ofType( Integer.class );
+     * 
+ * + *

If no methods are invoked on the returned {@link OptionSpecBuilder}, then the parser treats the option as + * accepting no argument.

+ * + * @param option the option to recognize + * @return an object that can be used to flesh out more detail about the option + * @throws OptionException if the option contains illegal characters + * @throws NullPointerException if the option is {@code null} + */ + OptionSpecBuilder accepts( String option ); + + /** + * Tells the parser to recognize the given option. + * + * @see #accepts(String) + * @param option the option to recognize + * @param description a string that describes the purpose of the option. This is used when generating help + * information about the parser. + * @return an object that can be used to flesh out more detail about the option + * @throws OptionException if the option contains illegal characters + * @throws NullPointerException if the option is {@code null} + */ + OptionSpecBuilder accepts( String option, String description ); + + /** + * Tells the parser to recognize the given options, and treat them as synonymous. + * + * @see #accepts(String) + * @param options the options to recognize and treat as synonymous + * @return an object that can be used to flesh out more detail about the options + * @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 ); + + /** + * Tells the parser to recognize the given options, and treat them as synonymous. + * + * @see #acceptsAll(Collection) + * @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. + * @return an object that can be used to flesh out more detail about the options + * @throws OptionException if any of the options contain illegal characters + * @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 ); + + /** + * Gives an object that represents an access point for non-option arguments on a command line. + * + * @return an object that can be used to flesh out more detail about the non-option arguments + */ + NonOptionArgumentSpec nonOptions(); + + /** + * Gives an object that represents an access point for non-option arguments on a command line. + * + * @see #nonOptions() + * @param description a string that describes the purpose of the non-option arguments. This is used when generating + * help information about the parser. + * @return an object that can be used to flesh out more detail about the non-option arguments + */ + NonOptionArgumentSpec nonOptions( String description ); + + /** + * Tells the parser whether or not to behave "POSIX-ly correct"-ly. + * + * @param setting {@code true} if the parser should behave "POSIX-ly correct"-ly + */ + void posixlyCorrect( boolean setting ); + + /** + *

Tells the parser to treat unrecognized options as non-option arguments.

+ * + *

If not called, then the parser raises an {@link OptionException} when it encounters an unrecognized + * option.

+ */ + void allowsUnrecognizedOptions(); + + /** + * Tells the parser either to recognize or ignore "-W"-style long options. + * + * @param recognize {@code true} if the parser is to recognize the special style of long options + */ + void recognizeAlternativeLongOptions( boolean recognize ); +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionDescriptor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionDescriptor.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.Collection; +import java.util.List; + +/** + * Describes options that an option parser recognizes, in ways that might be useful to {@linkplain HelpFormatter + * help screens}. + * + * @author Paul Holser + */ +public interface OptionDescriptor { + /** + * A set of options that are mutually synonymous. + * + * @return synonymous options + */ + Collection options(); + + /** + * Description of this option's purpose. + * + * @return a description for the option + */ + String description(); + + /** + * What values will the option take if none are specified on the command line? + * + * @return any default values for the option + */ + List defaultValues(); + + /** + * Is this option {@linkplain ArgumentAcceptingOptionSpec#required() required} on a command line? + * + * @return whether the option is required + */ + boolean isRequired(); + + /** + * Does this option {@linkplain ArgumentAcceptingOptionSpec accept arguments}? + * + * @return whether the option accepts arguments + */ + boolean acceptsArguments(); + + /** + * Does this option {@linkplain OptionSpecBuilder#withRequiredArg() require an argument}? + * + * @return whether the option requires an argument + */ + boolean requiresArgument(); + + /** + * Gives a short {@linkplain ArgumentAcceptingOptionSpec#describedAs(String) description} of the option's argument. + * + * @return a description for the option's argument + */ + String argumentDescription(); + + /** + * Gives an indication of the {@linkplain ArgumentAcceptingOptionSpec#ofType(Class) expected type} of the option's + * argument. + * + * @return a description for the option's argument type + */ + String argumentTypeIndicator(); + + /** + * Tells whether this object represents the non-option arguments of a command line. + * + * @return {@code true} if this represents non-option arguments + */ + boolean representsNonOptions(); +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionException.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import static java.util.Collections.*; + +import static jdk.internal.joptsimple.internal.Strings.*; + +/** + * Thrown when a problem occurs during option parsing. + * + * @author Paul Holser + */ +public abstract class OptionException extends RuntimeException { + private static final long serialVersionUID = -1L; + + private final List options = new ArrayList(); + + protected OptionException( Collection options ) { + this.options.addAll( options ); + } + + protected OptionException( Collection options, Throwable cause ) { + super( cause ); + + this.options.addAll( options ); + } + + /** + * Gives the option being considered when the exception was created. + * + * @return the option being considered when the exception was created + */ + public Collection options() { + return unmodifiableCollection( options ); + } + + protected final String singleOptionMessage() { + return singleOptionMessage( options.get( 0 ) ); + } + + protected final String singleOptionMessage( String option ) { + return SINGLE_QUOTE + option + SINGLE_QUOTE; + } + + protected final String multipleOptionMessage() { + StringBuilder buffer = new StringBuilder( "[" ); + + for ( Iterator iter = options.iterator(); iter.hasNext(); ) { + buffer.append( singleOptionMessage( iter.next() ) ); + if ( iter.hasNext() ) + buffer.append( ", " ); + } + + buffer.append( ']' ); + + return buffer.toString(); + } + + static OptionException unrecognizedOption( String option ) { + return new UnrecognizedOptionException( option ); + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionMissingRequiredArgumentException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionMissingRequiredArgumentException.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.Collection; + +/** + * Thrown when the option parser discovers an option that requires an argument, but that argument is missing. + * + * @author Paul Holser + */ +class OptionMissingRequiredArgumentException extends OptionException { + private static final long serialVersionUID = -1L; + + OptionMissingRequiredArgumentException( Collection options ) { + super( options ); + } + + @Override + public String getMessage() { + return "Option " + multipleOptionMessage() + " requires an argument"; + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionParser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionParser.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,580 @@ +/* + * Copyright (c) 2009, 2015, 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; + +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 static java.util.Collections.*; +import static jdk.internal.joptsimple.OptionException.*; +import static jdk.internal.joptsimple.OptionParserState.*; +import static jdk.internal.joptsimple.ParserRules.*; + +/** + *

Parses command line arguments, using a syntax that attempts to take from the best of POSIX {@code getopt()} + * and GNU {@code getopt_long()}.

+ * + *

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 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
    • + *
    + * 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 + * {@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 + * 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 + * 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, + * 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.
  • + * + *
  • 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 + *
    + * 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 + * option.
  • + * + *
  • The option -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.
  • + * + *
  • You can specify -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.
  • + * + *
  • You can specify a given short or long option multiple times on a single command line. The parser collects + * any arguments specified for those options as a list.
  • + * + *
  • If the parser detects an option whose argument is optional, and the next argument "looks like" an option, + * that argument is not treated as the argument to the option, but as a potentially valid option. If, on the other + * hand, the optional argument is typed as a derivative of {@link Number}, then that argument is treated as the + * negative number argument of the option, even if the parser recognizes the corresponding numeric option. + * For example: + *
    
    + *     OptionParser parser = new OptionParser();
    + *     parser.accepts( "a" ).withOptionalArg().ofType( Integer.class );
    + *     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.
  • + *
+ * + *

There are two ways to tell the parser what options to recognize:

+ * + *
    + *
  1. 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) + * 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 + * retrieve the arguments of the associated option in a type-safe manner.
  2. + * + *
  3. Since version 1, a more concise way of specifying short options has been to use the special {@linkplain + * #OptionParser(String) constructor}. Arguments of options specified in this manner will be of type {@link String}. + * Here are the rules for the format of the specification strings this constructor accepts: + * + *
      + *
    • 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.
    • + * + *
    • If an option character (with possible trailing asterisk) is followed by a single colon (":"), + * then the option requires an argument.
    • + * + *
    • If an option character (with possible trailing asterisk) is followed by two colons ("::"), + * 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 + * "POSIX-ly correct".
    • + * + *
    • If the option specification string contains the sequence "W;" (capital W followed by a + * semicolon), the parser will recognize the alternative form of long options.
    • + *
    + *
  4. + *
+ * + *

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: + *

+ *     
+ *     OptionParser parser = new OptionParser();
+ *     parser.acceptsAll( asList( "w", "interactive", "confirmation" ) );
+ *     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 + * 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.

+ * + *

Unlike GNU {@code getopt()}, this parser does not honor the environment variable {@code POSIXLY_CORRECT}. + * "POSIX-ly correct" parsers are configured by either:

+ * + *
    + *
  1. using the method {@link #posixlyCorrect(boolean)}, or
  2. + * + *
  3. using the {@linkplain #OptionParser(String) constructor} with an argument whose first character is a plus sign + * ("+")
  4. + *
+ * + * @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 OptionParserState state; + private boolean posixlyCorrect; + private boolean allowsUnrecognizedOptions; + private HelpFormatter helpFormatter = new BuiltinHelpFormatter(); + + /** + * Creates an option parser that initially recognizes no options, and does not exhibit "POSIX-ly correct" + * behavior. + */ + public OptionParser() { + recognizedOptions = new AbbreviationMap>(); + requiredIf = new HashMap, Set>>(); + requiredUnless = new HashMap, Set>>(); + state = moreOptions( false ); + + recognize( new NonOptionArgumentSpec() ); + } + + /** + * Creates an option parser and configures it to recognize the short options specified in the given string. + * + * Arguments of options specified this way will be of type {@link String}. + * + * @param optionSpecification an option specification + * @throws NullPointerException if {@code optionSpecification} is {@code null} + * @throws OptionException if the option specification contains illegal characters or otherwise cannot be + * recognized + */ + public OptionParser( String optionSpecification ) { + this(); + + new OptionSpecTokenizer( optionSpecification ).configure( this ); + } + + public OptionSpecBuilder accepts( String option ) { + return acceptsAll( singletonList( option ) ); + } + + public OptionSpecBuilder accepts( String option, String description ) { + return acceptsAll( singletonList( option ), description ); + } + + public OptionSpecBuilder acceptsAll( Collection options ) { + return acceptsAll( options, "" ); + } + + public OptionSpecBuilder acceptsAll( Collection options, String description ) { + if ( options.isEmpty() ) + throw new IllegalArgumentException( "need at least one option" ); + + ensureLegalOptions( options ); + + return new OptionSpecBuilder( this, options, description ); + } + + public NonOptionArgumentSpec nonOptions() { + NonOptionArgumentSpec spec = new NonOptionArgumentSpec(); + + recognize( spec ); + + return spec; + } + + public NonOptionArgumentSpec nonOptions( String description ) { + NonOptionArgumentSpec spec = new NonOptionArgumentSpec( description ); + + recognize( spec ); + + return spec; + } + + public void posixlyCorrect( boolean setting ) { + posixlyCorrect = setting; + state = moreOptions( setting ); + } + + boolean posixlyCorrect() { + return posixlyCorrect; + } + + public void allowsUnrecognizedOptions() { + allowsUnrecognizedOptions = true; + } + + boolean doesAllowsUnrecognizedOptions() { + return allowsUnrecognizedOptions; + } + + public void recognizeAlternativeLongOptions( boolean recognize ) { + if ( recognize ) + recognize( new AlternativeLongOptionSpec() ); + else + recognizedOptions.remove( String.valueOf( RESERVED_FOR_EXTENSIONS ) ); + } + + void recognize( AbstractOptionSpec spec ) { + recognizedOptions.putAll( spec.options(), spec ); + } + + /** + * Writes information about the options this parser recognizes to the given output sink. + * + * The output sink is flushed, but not closed. + * + * @param sink the sink to write information to + * @throws IOException if there is a problem writing to the sink + * @throws NullPointerException if {@code sink} is {@code null} + * @see #printHelpOn(Writer) + */ + public void printHelpOn( OutputStream sink ) throws IOException { + printHelpOn( new OutputStreamWriter( sink ) ); + } + + /** + * Writes information about the options this parser recognizes to the given output sink. + * + * The output sink is flushed, but not closed. + * + * @param sink the sink to write information to + * @throws IOException if there is a problem writing to the sink + * @throws NullPointerException if {@code sink} is {@code null} + * @see #printHelpOn(OutputStream) + */ + public void printHelpOn( Writer sink ) throws IOException { + sink.write( helpFormatter.format( recognizedOptions.toJavaUtilMap() ) ); + sink.flush(); + } + + /** + * Tells the parser to use the given formatter when asked to {@linkplain #printHelpOn(java.io.Writer) print help}. + * + * @param formatter the formatter to use for printing help + * @throws NullPointerException if the formatter is {@code null} + */ + public void formatHelpWith( HelpFormatter formatter ) { + if ( formatter == null ) + throw new NullPointerException(); + + helpFormatter = formatter; + } + + /** + * Retrieves all the options which have been configured for the parser. + * + * @return a {@link Map} containing all the configured options and their corresponding {@link OptionSpec} + */ + public Map> recognizedOptions() { + return new HashMap>( recognizedOptions.toJavaUtilMap() ); + } + + /** + * Parses the given command line arguments according to the option specifications given to the parser. + * + * @param arguments arguments to parse + * @return an {@link OptionSet} describing the parsed options, their arguments, and any non-option arguments found + * @throws OptionException if problems are detected while parsing + * @throws NullPointerException if the argument list is {@code null} + */ + public OptionSet parse( String... arguments ) { + ArgumentList argumentList = new ArgumentList( arguments ); + OptionSet detected = new OptionSet( recognizedOptions.toJavaUtilMap() ); + detected.add( recognizedOptions.get( NonOptionArgumentSpec.NAME ) ); + + while ( argumentList.hasMore() ) + state.handleArgument( this, argumentList, detected ); + + reset(); + + ensureRequiredOptions( detected ); + + return detected; + } + + private void ensureRequiredOptions( OptionSet options ) { + Collection missingRequiredOptions = missingRequiredOptions( options ); + boolean helpOptionPresent = isHelpOptionPresent( options ); + + if ( !missingRequiredOptions.isEmpty() && !helpOptionPresent ) + throw new MissingRequiredOptionException( missingRequiredOptions ); + } + + private Collection missingRequiredOptions( OptionSet options ) { + Collection missingRequiredOptions = new HashSet(); + + for ( AbstractOptionSpec each : recognizedOptions.toJavaUtilMap().values() ) { + if ( each.isRequired() && !options.has( each ) ) + missingRequiredOptions.addAll( each.options() ); + } + + for ( Map.Entry, Set>> eachEntry : requiredIf.entrySet() ) { + AbstractOptionSpec required = specFor( eachEntry.getKey().iterator().next() ); + + if ( optionsHasAnyOf( options, eachEntry.getValue() ) && !options.has( required ) ) { + missingRequiredOptions.addAll( required.options() ); + } + } + + for ( Map.Entry, Set>> eachEntry : requiredUnless.entrySet() ) { + AbstractOptionSpec required = specFor( eachEntry.getKey().iterator().next() ); + + if ( !optionsHasAnyOf( options, eachEntry.getValue() ) && !options.has( required ) ) { + missingRequiredOptions.addAll( required.options() ); + } + } + + return missingRequiredOptions; + } + + private boolean optionsHasAnyOf( OptionSet options, Collection> specs ) { + for ( OptionSpec each : specs ) { + if ( options.has( each ) ) + return true; + } + + return false; + } + + 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; + } + + void handleLongOptionToken( String candidate, ArgumentList arguments, OptionSet detected ) { + KeyValuePair optionAndArgument = parseLongOptionWithArgument( candidate ); + + if ( !isRecognized( optionAndArgument.key ) ) + throw unrecognizedOption( optionAndArgument.key ); + + AbstractOptionSpec optionSpec = specFor( optionAndArgument.key ); + optionSpec.handleOption( this, arguments, detected, optionAndArgument.value ); + } + + void handleShortOptionToken( String candidate, ArgumentList arguments, OptionSet detected ) { + KeyValuePair optionAndArgument = parseShortOptionWithArgument( candidate ); + + if ( isRecognized( optionAndArgument.key ) ) { + specFor( optionAndArgument.key ).handleOption( this, arguments, detected, optionAndArgument.value ); + } + else + handleShortOptionCluster( candidate, arguments, detected ); + } + + private void handleShortOptionCluster( String candidate, ArgumentList arguments, OptionSet detected ) { + char[] options = extractShortOptionsFrom( candidate ); + validateOptionCharacters( options ); + + for ( int i = 0; i < options.length; i++ ) { + AbstractOptionSpec optionSpec = specFor( options[ i ] ); + + if ( optionSpec.acceptsArguments() && options.length > i + 1 ) { + String detectedArgument = String.valueOf( options, i + 1, options.length - 1 - i ); + optionSpec.handleOption( this, arguments, detected, detectedArgument ); + break; + } + + optionSpec.handleOption( this, arguments, detected, null ); + } + } + + void handleNonOptionArgument( String candidate, ArgumentList arguments, OptionSet detectedOptions ) { + specFor( NonOptionArgumentSpec.NAME ).handleOption( this, arguments, detectedOptions, candidate ); + } + + void noMoreOptions() { + state = OptionParserState.noMoreOptions(); + } + + boolean looksLikeAnOption( String argument ) { + return isShortOptionToken( argument ) || isLongOptionToken( argument ); + } + + boolean isRecognized( String option ) { + return recognizedOptions.contains( option ); + } + + void requiredIf( Collection precedentSynonyms, String required ) { + requiredIf( precedentSynonyms, specFor( required ) ); + } + + void requiredIf( Collection precedentSynonyms, OptionSpec required ) { + putRequiredOption( precedentSynonyms, required, requiredIf ); + } + + void requiredUnless( Collection precedentSynonyms, String required ) { + requiredUnless( precedentSynonyms, specFor( required ) ); + } + + void requiredUnless( Collection precedentSynonyms, OptionSpec required ) { + putRequiredOption( precedentSynonyms, required, requiredUnless ); + } + + private void putRequiredOption( Collection precedentSynonyms, OptionSpec required, + Map, Set>> target ) { + + for ( String each : precedentSynonyms ) { + AbstractOptionSpec spec = specFor( each ); + if ( spec == null ) + throw new UnconfiguredOptionException( precedentSynonyms ); + } + + Set> associated = target.get( precedentSynonyms ); + if ( associated == null ) { + associated = new HashSet>(); + target.put( precedentSynonyms, associated ); + } + + associated.add( required ); + } + + private AbstractOptionSpec specFor( char option ) { + return specFor( String.valueOf( option ) ); + } + + private AbstractOptionSpec specFor( String option ) { + return recognizedOptions.get( option ); + } + + private void reset() { + state = moreOptions( posixlyCorrect ); + } + + private static char[] extractShortOptionsFrom( String argument ) { + char[] options = new char[ argument.length() - 1 ]; + argument.getChars( 1, argument.length(), options, 0 ); + + return options; + } + + private void validateOptionCharacters( char[] options ) { + for ( char each : options ) { + String option = String.valueOf( each ); + + if ( !isRecognized( option ) ) + throw unrecognizedOption( option ); + + if ( specFor( option ).acceptsArguments() ) + return; + } + } + + private static KeyValuePair parseLongOptionWithArgument( String argument ) { + return KeyValuePair.valueOf( argument.substring( 2 ) ); + } + + private static KeyValuePair parseShortOptionWithArgument( String argument ) { + return KeyValuePair.valueOf( argument.substring( 1 ) ); + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionParserState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionParserState.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import static jdk.internal.joptsimple.ParserRules.*; + +/** + * Abstraction of parser state; mostly serves to model how a parser behaves depending on whether end-of-options + * has been detected. + * + * @author Paul Holser + */ +abstract class OptionParserState { + static OptionParserState noMoreOptions() { + return new OptionParserState() { + @Override + protected void handleArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions ) { + parser.handleNonOptionArgument( arguments.next(), arguments, detectedOptions ); + } + }; + } + + static OptionParserState moreOptions( final boolean posixlyCorrect ) { + return new OptionParserState() { + @Override + protected void handleArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions ) { + String candidate = arguments.next(); + try { + if ( isOptionTerminator( candidate ) ) { + parser.noMoreOptions(); + return; + } else if ( isLongOptionToken( candidate ) ) { + parser.handleLongOptionToken( candidate, arguments, detectedOptions ); + return; + } else if ( isShortOptionToken( candidate ) ) { + parser.handleShortOptionToken( candidate, arguments, detectedOptions ); + return; + } + } catch ( UnrecognizedOptionException e ) { + if ( !parser.doesAllowsUnrecognizedOptions() ) + throw e; + } + + if ( posixlyCorrect ) + parser.noMoreOptions(); + + parser.handleNonOptionArgument( candidate, arguments, detectedOptions ); + } + }; + } + + protected abstract void handleArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions ); +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSet.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.*; + +import static java.util.Collections.*; + +import static jdk.internal.joptsimple.internal.Objects.*; + +/** + * Representation of a group of detected command line options, their arguments, and non-option arguments. + * + * @author Paul Holser + */ +public class OptionSet { + private final List> detectedSpecs; + private final Map> detectedOptions; + private final Map, List> optionsToArguments; + private final Map> recognizedSpecs; + private final Map> defaultValues; + + /* + * Package-private because clients don't create these. + */ + OptionSet( Map> recognizedSpecs ) { + detectedSpecs = new ArrayList>(); + detectedOptions = new HashMap>(); + optionsToArguments = new IdentityHashMap, List>(); + defaultValues = defaultValues( recognizedSpecs ); + this.recognizedSpecs = recognizedSpecs; + } + + /** + * Tells whether any options were detected. + * + * @return {@code true} if any options were detected + */ + public boolean hasOptions() { + return !detectedOptions.isEmpty(); + } + + /** + * Tells whether the given option was detected. + * + * @param option the option to search for + * @return {@code true} if the option was detected + * @see #has(OptionSpec) + */ + public boolean has( String option ) { + return detectedOptions.containsKey( option ); + } + + /** + * Tells whether the given option was detected. + * + *

This method recognizes only instances of options returned from the fluent interface methods.

+ * + *

Specifying a {@linkplain ArgumentAcceptingOptionSpec#defaultsTo(Object, Object[])} default argument value} + * for an option does not cause this method to return {@code true} if the option was not detected on the command + * line.

+ * + * @param option the option to search for + * @return {@code true} if the option was detected + * @see #has(String) + */ + public boolean has( OptionSpec option ) { + return optionsToArguments.containsKey( option ); + } + + /** + * Tells whether there are any arguments associated with the given option. + * + * @param option the option to search for + * @return {@code true} if the option was detected and at least one argument was detected for the option + * @see #hasArgument(OptionSpec) + */ + public boolean hasArgument( String option ) { + AbstractOptionSpec spec = detectedOptions.get( option ); + return spec != null && hasArgument( spec ); + } + + /** + * Tells whether there are any arguments associated with the given option. + * + *

This method recognizes only instances of options returned from the fluent interface methods.

+ * + *

Specifying a {@linkplain ArgumentAcceptingOptionSpec#defaultsTo(Object, Object[]) default argument value} + * for an option does not cause this method to return {@code true} if the option was not detected on the command + * line, or if the option can take an optional argument but did not have one on the command line.

+ * + * @param option the option to search for + * @return {@code true} if the option was detected and at least one argument was detected for the option + * @throws NullPointerException if {@code option} is {@code null} + * @see #hasArgument(String) + */ + public boolean hasArgument( OptionSpec option ) { + ensureNotNull( option ); + + List values = optionsToArguments.get( option ); + return values != null && !values.isEmpty(); + } + + /** + * Gives the argument associated with the given option. If the option was given an argument type, the argument + * will take on that type; otherwise, it will be a {@link String}. + * + *

Specifying a {@linkplain ArgumentAcceptingOptionSpec#defaultsTo(Object, Object[]) default argument value} + * for an option will cause this method to return that default value even if the option was not detected on the + * command line, or if the option can take an optional argument but did not have one on the command line.

+ * + * @param option the option to search for + * @return the argument of the given option; {@code null} if no argument is present, or that option was not + * detected + * @throws NullPointerException if {@code option} is {@code null} + * @throws OptionException if more than one argument was detected for the option + */ + public Object valueOf( String option ) { + ensureNotNull( option ); + + AbstractOptionSpec spec = detectedOptions.get( option ); + if ( spec == null ) { + List defaults = defaultValuesFor( option ); + return defaults.isEmpty() ? null : defaults.get( 0 ); + } + + return valueOf( spec ); + } + + /** + * Gives the argument associated with the given option. + * + *

This method recognizes only instances of options returned from the fluent interface methods.

+ * + * @param represents the type of the arguments the given option accepts + * @param option the option to search for + * @return the argument of the given option; {@code null} if no argument is present, or that option was not + * detected + * @throws OptionException if more than one argument was detected for the option + * @throws NullPointerException if {@code option} is {@code null} + * @throws ClassCastException if the arguments of this option are not of the expected type + */ + public V valueOf( OptionSpec option ) { + ensureNotNull( option ); + + List values = valuesOf( option ); + switch ( values.size() ) { + case 0: + return null; + case 1: + return values.get( 0 ); + default: + throw new MultipleArgumentsForOptionException( option.options() ); + } + } + + /** + *

Gives any arguments associated with the given option. If the option was given an argument type, the + * arguments will take on that type; otherwise, they will be {@link String}s.

+ * + * @param option the option to search for + * @return the arguments associated with the option, as a list of objects of the type given to the arguments; an + * empty list if no such arguments are present, or if the option was not detected + * @throws NullPointerException if {@code option} is {@code null} + */ + public List valuesOf( String option ) { + ensureNotNull( option ); + + AbstractOptionSpec spec = detectedOptions.get( option ); + return spec == null ? defaultValuesFor( option ) : valuesOf( spec ); + } + + /** + *

Gives any arguments associated with the given option. If the option was given an argument type, the + * arguments will take on that type; otherwise, they will be {@link String}s.

+ * + *

This method recognizes only instances of options returned from the fluent interface methods.

+ * + * @param represents the type of the arguments the given option accepts + * @param option the option to search for + * @return the arguments associated with the option; an empty list if no such arguments are present, or if the + * option was not detected + * @throws NullPointerException if {@code option} is {@code null} + * @throws OptionException if there is a problem converting the option's arguments to the desired type; for + * example, if the type does not implement a correct conversion constructor or method + */ + public List valuesOf( OptionSpec option ) { + ensureNotNull( option ); + + List values = optionsToArguments.get( option ); + if ( values == null || values.isEmpty() ) + return defaultValueFor( option ); + + AbstractOptionSpec spec = (AbstractOptionSpec) option; + List convertedValues = new ArrayList(); + for ( String each : values ) + convertedValues.add( spec.convert( each ) ); + + return unmodifiableList( convertedValues ); + } + + /** + * Gives the set of options that were detected, in the form of {@linkplain OptionSpec}s, in the order in which the + * options were found on the command line. + * + * @return the set of detected command line options + */ + public List> specs() { + List> specs = detectedSpecs; + specs.remove( detectedOptions.get( NonOptionArgumentSpec.NAME ) ); + + return unmodifiableList( specs ); + } + + /** + * Gives all declared options as a map of string to {@linkplain OptionSpec}. + * + * @return the declared options as a map + */ + public Map, List> asMap() { + Map, List> map = new HashMap, List>(); + for ( AbstractOptionSpec spec : recognizedSpecs.values() ) + if ( !spec.representsNonOptions() ) + map.put( spec, valuesOf( spec ) ); + return unmodifiableMap( map ); + } + + /** + * @return the detected non-option arguments + */ + public List nonOptionArguments() { + return unmodifiableList( valuesOf( detectedOptions.get( NonOptionArgumentSpec.NAME ) ) ); + } + + void add( AbstractOptionSpec spec ) { + addWithArgument( spec, null ); + } + + void addWithArgument( AbstractOptionSpec spec, String argument ) { + detectedSpecs.add( spec ); + + for ( String each : spec.options() ) + detectedOptions.put( each, spec ); + + List optionArguments = optionsToArguments.get( spec ); + + if ( optionArguments == null ) { + optionArguments = new ArrayList(); + optionsToArguments.put( spec, optionArguments ); + } + + if ( argument != null ) + optionArguments.add( argument ); + } + + @Override + public boolean equals( Object that ) { + if ( this == that ) + return true; + + if ( that == null || !getClass().equals( that.getClass() ) ) + return false; + + OptionSet other = (OptionSet) that; + Map, List> thisOptionsToArguments = + new HashMap, List>( optionsToArguments ); + Map, List> otherOptionsToArguments = + new HashMap, List>( other.optionsToArguments ); + return detectedOptions.equals( other.detectedOptions ) + && thisOptionsToArguments.equals( otherOptionsToArguments ); + } + + @Override + public int hashCode() { + Map, List> thisOptionsToArguments = + new HashMap, List>( optionsToArguments ); + return detectedOptions.hashCode() ^ thisOptionsToArguments.hashCode(); + } + + @SuppressWarnings( "unchecked" ) + private List defaultValuesFor( String option ) { + if ( defaultValues.containsKey( option ) ) + return (List) defaultValues.get( option ); + + return emptyList(); + } + + private List defaultValueFor( OptionSpec option ) { + return defaultValuesFor( option.options().iterator().next() ); + } + + private static Map> defaultValues( Map> recognizedSpecs ) { + Map> defaults = new HashMap>(); + for ( Map.Entry> each : recognizedSpecs.entrySet() ) + defaults.put( each.getKey(), each.getValue().defaultValues() ); + return defaults; + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpec.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpec.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.Collection; +import java.util.List; + +/** + * Describes options that an option parser recognizes. + * + *

Instances of this interface are returned by the "fluent interface" methods to allow retrieval of option arguments + * in a type-safe manner. Here's an example:

+ * + *

+ *     OptionParser parser = new OptionParser();
+ *     OptionSpec<Integer> count =
+ *         parser.accepts( "count" ).withRequiredArg().ofType( Integer.class );
+ *     OptionSet options = parser.parse( "--count", "2" );
+ *     assert options.has( count );
+ *     int countValue = options.valueOf( count );
+ *     assert countValue == count.value( options );
+ *     List<Integer> countValues = options.valuesOf( count );
+ *     assert countValues.equals( count.values( options ) );
+ * 
+ * + * @param represents the type of the arguments this option accepts + * @author Paul Holser + */ +public interface OptionSpec { + /** + * Gives any arguments associated with the given option in the given set of detected options. + * + *

Specifying a {@linkplain ArgumentAcceptingOptionSpec#defaultsTo(Object, Object[]) default argument value} + * for this option will cause this method to return that default value even if this option was not detected on the + * command line, or if this option can take an optional argument but did not have one on the command line.

+ * + * @param detectedOptions the detected options to search in + * @return the arguments associated with this option; an empty list if no such arguments are present, or if this + * option was not detected + * @throws OptionException if there is a problem converting this option's arguments to the desired type; for + * example, if the type does not implement a correct conversion constructor or method + * @throws NullPointerException if {@code detectedOptions} is {@code null} + * @see OptionSet#valuesOf(OptionSpec) + */ + List values( OptionSet detectedOptions ); + + /** + * Gives the argument associated with the given option in the given set of detected options. + * + *

Specifying a {@linkplain ArgumentAcceptingOptionSpec#defaultsTo(Object, Object[]) default argument value} + * for this option will cause this method to return that default value even if this option was not detected on the + * command line, or if this option can take an optional argument but did not have one on the command line.

+ * + * @param detectedOptions the detected options to search in + * @return the argument of the this option; {@code null} if no argument is present, or that option was not detected + * @throws OptionException if more than one argument was detected for the option + * @throws NullPointerException if {@code detectedOptions} is {@code null} + * @throws ClassCastException if the arguments of this option are not of the expected type + * @see OptionSet#valueOf(OptionSpec) + */ + V value( OptionSet detectedOptions ); + + /** + * @return the string representations of this option + */ + Collection options(); + + /** + * Tells whether this option is designated as a "help" option. The presence of a "help" option on a command line + * means that missing "required" options will not cause parsing to fail. + * + * @return whether this option is designated as a "help" option + */ + boolean isForHelp(); +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpecBuilder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpecBuilder.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * Allows callers to specify whether a given option accepts arguments (required or optional). + * + *

Instances are returned from {@link OptionParser#accepts(String)} to allow the formation of parser directives as + * sentences in a "fluent interface" language. For example:

+ * + *

+ *   OptionParser parser = new OptionParser();
+ *   parser.accepts( "c" ).withRequiredArg().ofType( Integer.class );
+ * 
+ * + *

If no methods are invoked on an instance of this class, then that instance's option will accept no argument.

+ * + *

Note that you should not use the fluent interface clauses in a way that would defeat the typing of option + * arguments:

+ * + *

+ *   OptionParser parser = new OptionParser();
+ *   ArgumentAcceptingOptionSpec<String> optionC =
+ *       parser.accepts( "c" ).withRequiredArg();
+ *   optionC.ofType( Integer.class );  // DON'T THROW AWAY THE TYPE!
+ *
+ *   String value = parser.parse( "-c", "2" ).valueOf( optionC );  // ClassCastException
+ * 
+ * + * @author Paul Holser + */ +public class OptionSpecBuilder extends NoArgumentOptionSpec { + private final OptionParser parser; + + OptionSpecBuilder( OptionParser parser, Collection options, String description ) { + super( options, description ); + + this.parser = parser; + attachToParser(); + } + + private void attachToParser() { + parser.recognize( this ); + } + + /** + * Informs an option parser that this builder's option requires an argument. + * + * @return a specification for the option + */ + public ArgumentAcceptingOptionSpec withRequiredArg() { + ArgumentAcceptingOptionSpec newSpec = + new RequiredArgumentOptionSpec( options(), description() ); + parser.recognize( newSpec ); + + return newSpec; + } + + /** + * Informs an option parser that this builder's option accepts an optional argument. + * + * @return a specification for the option + */ + public ArgumentAcceptingOptionSpec withOptionalArg() { + ArgumentAcceptingOptionSpec newSpec = + new OptionalArgumentOptionSpec( options(), description() ); + parser.recognize( newSpec ); + + return newSpec; + } + + /** + *

Informs an option parser that this builder's option is required if the given option is present on the command + * line.

+ * + *

For a given option, you should not mix this with {@link #requiredUnless(String, String...) + * requiredUnless} to avoid conflicts.

+ * + * @param dependent an option whose presence on a command line makes this builder's option required + * @param otherDependents other options whose presence on a command line makes this builder's option required + * @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 requiredIf( String dependent, String... otherDependents ) { + List dependents = validatedDependents( dependent, otherDependents ); + for ( String each : dependents ) { + parser.requiredIf( options(), each ); + } + + return this; + } + + /** + *

Informs an option parser that this builder's option is required if the given option is present on the command + * line.

+ * + *

For a given option, you should not mix this with {@link #requiredUnless(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 required + * @param otherDependents other options whose presence on a command line makes this builder's option required + * @return self, so that the caller can add clauses to the fluent interface sentence + */ + public OptionSpecBuilder requiredIf( OptionSpec dependent, OptionSpec... otherDependents ) { + parser.requiredIf( options(), dependent ); + for ( OptionSpec each : otherDependents ) + parser.requiredIf( options(), each ); + + return this; + } + + /** + *

Informs an option parser that this builder's option is required if the given option is absent on the command + * line.

+ * + *

For a given option, you should not mix this with {@link #requiredIf(OptionSpec, OptionSpec[]) + * requiredIf} to avoid conflicts.

+ * + * @param dependent an option whose absence on a command line makes this builder's option required + * @param otherDependents other options whose absence on a command line makes this builder's option required + * @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 requiredUnless( String dependent, String... otherDependents ) { + List dependents = validatedDependents( dependent, otherDependents ); + for ( String each : dependents ) { + parser.requiredUnless( options(), each ); + } + return this; + } + + /** + *

Informs an option parser that this builder's option is required if the given option is absent on the command + * line.

+ * + *

For a given option, you should not mix this with {@link #requiredIf(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 required + * @param otherDependents other options whose absence on a command line makes this builder's option required + * @return self, so that the caller can add clauses to the fluent interface sentence + */ + public OptionSpecBuilder requiredUnless( OptionSpec dependent, OptionSpec... otherDependents ) { + parser.requiredUnless( options(), dependent ); + for ( OptionSpec each : otherDependents ) + parser.requiredUnless( options(), each ); + + return this; + } + + private List validatedDependents( String dependent, String... otherDependents ) { + List dependents = new ArrayList(); + dependents.add( dependent ); + Collections.addAll( dependents, otherDependents ); + + for ( String each : dependents ) { + if ( !parser.isRecognized( each ) ) + throw new UnconfiguredOptionException( each ); + } + + return dependents; + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpecTokenizer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpecTokenizer.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.NoSuchElementException; + +import static jdk.internal.joptsimple.ParserRules.*; + +/** + * Tokenizes a short option specification string. + * + * @author Paul Holser + */ +class OptionSpecTokenizer { + private static final char POSIXLY_CORRECT_MARKER = '+'; + private static final char HELP_MARKER = '*'; + + private String specification; + private int index; + + OptionSpecTokenizer( String specification ) { + if ( specification == null ) + throw new NullPointerException( "null option specification" ); + + this.specification = specification; + } + + boolean hasMore() { + return index < specification.length(); + } + + AbstractOptionSpec next() { + if ( !hasMore() ) + throw new NoSuchElementException(); + + + String optionCandidate = String.valueOf( specification.charAt( index ) ); + index++; + + AbstractOptionSpec spec; + if ( RESERVED_FOR_EXTENSIONS.equals( optionCandidate ) ) { + spec = handleReservedForExtensionsToken(); + + if ( spec != null ) + return spec; + } + + ensureLegalOption( optionCandidate ); + + if ( hasMore() ) { + boolean forHelp = false; + if ( specification.charAt( index ) == HELP_MARKER ) { + forHelp = true; + ++index; + } + spec = hasMore() && specification.charAt( index ) == ':' + ? handleArgumentAcceptingOption( optionCandidate ) + : new NoArgumentOptionSpec( optionCandidate ); + if ( forHelp ) + spec.forHelp(); + } else + spec = new NoArgumentOptionSpec( optionCandidate ); + + return spec; + } + + void configure( OptionParser parser ) { + adjustForPosixlyCorrect( parser ); + + while ( hasMore() ) + parser.recognize( next() ); + } + + private void adjustForPosixlyCorrect( OptionParser parser ) { + if ( POSIXLY_CORRECT_MARKER == specification.charAt( 0 ) ) { + parser.posixlyCorrect( true ); + specification = specification.substring( 1 ); + } + } + + private AbstractOptionSpec handleReservedForExtensionsToken() { + if ( !hasMore() ) + return new NoArgumentOptionSpec( RESERVED_FOR_EXTENSIONS ); + + if ( specification.charAt( index ) == ';' ) { + ++index; + return new AlternativeLongOptionSpec(); + } + + return null; + } + + private AbstractOptionSpec handleArgumentAcceptingOption( String candidate ) { + index++; + + if ( hasMore() && specification.charAt( index ) == ':' ) { + index++; + return new OptionalArgumentOptionSpec( candidate ); + } + + return new RequiredArgumentOptionSpec( candidate ); + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionalArgumentOptionSpec.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionalArgumentOptionSpec.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.Collection; + +/** + * Specification of an option that accepts an optional argument. + * + * @param represents the type of the arguments this option accepts + * @author Paul Holser + */ +class OptionalArgumentOptionSpec extends ArgumentAcceptingOptionSpec { + OptionalArgumentOptionSpec( String option ) { + super( option, false ); + } + + OptionalArgumentOptionSpec( Collection options, String description ) { + super( options, false, description ); + } + + @Override + protected void detectOptionArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions ) { + if ( arguments.hasMore() ) { + String nextArgument = arguments.peek(); + + if ( !parser.looksLikeAnOption( nextArgument ) ) + handleOptionArgument( parser, detectedOptions, arguments ); + else if ( isArgumentOfNumberType() && canConvertArgument( nextArgument ) ) + addArguments( detectedOptions, arguments.next() ); + else + detectedOptions.add( this ); + } + else + detectedOptions.add( this ); + } + + private void handleOptionArgument( OptionParser parser, OptionSet detectedOptions, ArgumentList arguments ) { + if ( parser.posixlyCorrect() ) { + detectedOptions.add( this ); + parser.noMoreOptions(); + } + else + addArguments( detectedOptions, arguments.next() ); + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ParserRules.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ParserRules.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.Collection; + +import static java.lang.Character.*; + +/** + * Can tell whether or not options are well-formed. + * + * @author Paul Holser + */ +final class ParserRules { + static final char HYPHEN_CHAR = '-'; + static final String HYPHEN = String.valueOf( HYPHEN_CHAR ); + static final String DOUBLE_HYPHEN = "--"; + static final String OPTION_TERMINATOR = DOUBLE_HYPHEN; + static final String RESERVED_FOR_EXTENSIONS = "W"; + + private ParserRules() { + throw new UnsupportedOperationException(); + } + + static boolean isShortOptionToken( String argument ) { + return argument.startsWith( HYPHEN ) + && !HYPHEN.equals( argument ) + && !isLongOptionToken( argument ); + } + + static boolean isLongOptionToken( String argument ) { + return argument.startsWith( DOUBLE_HYPHEN ) && !isOptionTerminator( argument ); + } + + static boolean isOptionTerminator( String argument ) { + return OPTION_TERMINATOR.equals( argument ); + } + + static void ensureLegalOption( String option ) { + if ( option.startsWith( HYPHEN ) ) + throw new IllegalOptionSpecificationException( String.valueOf( option ) ); + + for ( int i = 0; i < option.length(); ++i ) + ensureLegalOptionCharacter( option.charAt( i ) ); + } + + static void ensureLegalOptions( Collection options ) { + for ( String each : options ) + ensureLegalOption( each ); + } + + private static void ensureLegalOptionCharacter( char option ) { + if ( !( isLetterOrDigit( option ) || isAllowedPunctuation( option ) ) ) + throw new IllegalOptionSpecificationException( String.valueOf( option ) ); + } + + private static boolean isAllowedPunctuation( char option ) { + String allowedPunctuation = "?." + HYPHEN_CHAR; + return allowedPunctuation.indexOf( option ) != -1; + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/README Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,3 @@ +JOpt Simple, Version 4.6 +https://pholser.github.io/jopt-simple/ + diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/RequiredArgumentOptionSpec.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/RequiredArgumentOptionSpec.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.Collection; + +/** + * Specification of an option that accepts a required argument. + * + * @param represents the type of the arguments this option accepts + * @author Paul Holser + */ +class RequiredArgumentOptionSpec extends ArgumentAcceptingOptionSpec { + RequiredArgumentOptionSpec( String option ) { + super( option, true ); + } + + RequiredArgumentOptionSpec( Collection options, String description ) { + super( options, true, description ); + } + + @Override + protected void detectOptionArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions ) { + if ( !arguments.hasMore() ) + throw new OptionMissingRequiredArgumentException( options() ); + + addArguments( detectedOptions, arguments.next() ); + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnacceptableNumberOfNonOptionsException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnacceptableNumberOfNonOptionsException.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import static java.util.Collections.*; + +/** + * Thrown when the option parser detects an unacceptable number of {@code linkplain NonOptionArgumentSpec + * non-option arguments}. + * + * @author Paul Holser + */ +class UnacceptableNumberOfNonOptionsException 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; + } + + @Override + public String getMessage() { + return String.format( "actual = %d, minimum = %d, maximum = %d", actual, minimum, maximum ); + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnconfiguredOptionException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnconfiguredOptionException.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import java.util.Collection; + +import static java.util.Collections.*; + +/** + * Thrown when an option parser refers to an option that is not in fact configured already on the parser. + * + * @author Paul Holser + */ +class UnconfiguredOptionException extends OptionException { + private static final long serialVersionUID = -1L; + + UnconfiguredOptionException( String option ) { + this( singletonList( option ) ); + } + + UnconfiguredOptionException( Collection options ) { + super( options ); + } + + @Override + public String getMessage() { + return "Option " + multipleOptionMessage() + " has not been configured on this parser"; + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnrecognizedOptionException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnrecognizedOptionException.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2009, 2015, 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; + +import static java.util.Collections.*; + +/** + * Thrown when the option parser encounters an unrecognized option. + * + * @author Paul Holser + */ +class UnrecognizedOptionException extends OptionException { + private static final long serialVersionUID = -1L; + + UnrecognizedOptionException( String option ) { + super( singletonList( option ) ); + } + + @Override + public String getMessage() { + return singleOptionMessage() + " is not a recognized option"; + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ValueConversionException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ValueConversionException.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2009, 2015, 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; + +/** + * Thrown by {@link ValueConverter}s when problems occur in converting string values to other Java types. + * + * @author Paul Holser + */ +public class ValueConversionException extends RuntimeException { + private static final long serialVersionUID = -1L; + + /** + * Creates a new exception with the specified detail message. + * + * @param message the detail message + */ + public ValueConversionException( String message ) { + this( message, null ); + } + + /** + * Creates a new exception with the specified detail message and cause. + * + * @param message the detail message + * @param cause the original exception + */ + public ValueConversionException( String message, Throwable cause ) { + super( message, cause ); + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ValueConverter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ValueConverter.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2009, 2015, 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; + +/** + * Instances of this interface are used to convert arguments of options into specific Java types. + * + * @param constraint on the type of values being converted to + * @author Paul Holser + */ +public interface ValueConverter { + /** + * Converts the given string value into a Java type. + * + * @param value the string to convert + * @return the converted value + * @throws ValueConversionException if a problem occurs while converting the value + */ + V convert( String value ); + + /** + * Gives the class of the type of values this converter converts to. + * + * @return the target class for conversion + */ + Class valueType(); + + /** + * Gives a string that describes the pattern of the values this converter expects, if any. For example, a date + * converter can respond with a {@link java.text.SimpleDateFormat date format string}. + * + * @return a value pattern, or {@code null} if there's nothing interesting here + */ + String valuePattern(); +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/AbbreviationMap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/AbbreviationMap.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2009, 2015, 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.internal; + +import java.util.Map; +import java.util.TreeMap; + +/** + *

A map whose keys are strings; when a key/value pair is added to the map, the longest unique abbreviations of that + * key are added as well, and associated with the value. Thus:

+ * + *
+ *   
+ *   abbreviations.put( "good", "bye" );
+ *   
+ * 
+ * + *

would make it such that you could retrieve the value {@code "bye"} from the map using the keys {@code "good"}, + * {@code "goo"}, {@code "go"}, and {@code "g"}. A subsequent invocation of:

+ *
+ *   
+ *   abbreviations.put( "go", "fish" );
+ *   
+ * 
+ * + *

would make it such that you could retrieve the value {@code "bye"} using the keys {@code "good"} and + * {@code "goo"}, and the value {@code "fish"} using the key {@code "go"}. The key {@code "g"} would yield + * {@code null}, since it would no longer be a unique abbreviation.

+ * + *

The data structure is much like a "trie".

+ * + * @param a constraint on the types of the values in the map + * @author Paul Holser + * @see Perl's Text::Abbrev module + */ +public class AbbreviationMap { + 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 + * @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; + } + + /** + *

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 + * @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 ); + + AbbreviationMap child = this; + for ( char each : chars ) { + child = child.children.get( each ); + if ( child == null ) + return null; + } + + return child.value; + } + + /** + *

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 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 ) { + if ( newValue == null ) + throw new NullPointerException(); + if ( aKey.length() == 0 ) + throw new IllegalArgumentException(); + + char[] chars = charsOf( aKey ); + add( chars, newValue, 0, chars.length ); + } + + /** + *

Associates a given value with a given set of keys. If there was a previous + * association, the old value is replaced with the new one.

+ * + * @param keys keys to create in the map + * @param newValue value to associate with the key + * @throws NullPointerException if {@code keys} or {@code newValue} is {@code null} + * @throws IllegalArgumentException if any of {@code keys} is a zero-length string + */ + public void putAll( Iterable keys, V newValue ) { + for ( String each : keys ) + put( each, newValue ); + } + + private boolean add( char[] chars, V newValue, int offset, int length ) { + if ( offset == length ) { + value = newValue; + boolean wasAlreadyAKey = key != null; + key = new String( chars ); + return !wasAlreadyAKey; + } + + char nextChar = chars[ offset ]; + AbbreviationMap child = children.get( nextChar ); + if ( child == null ) { + child = new AbbreviationMap(); + children.put( nextChar, child ); + } + + boolean newKeyAdded = child.add( chars, newValue, offset + 1, length ); + + if ( newKeyAdded ) + ++keysBeyond; + + if ( key == null ) + value = keysBeyond > 1 ? null : newValue; + + return newKeyAdded; + } + + /** + *

If the map contains the given key, dissociates the key from its value.

+ * + * @param aKey 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 ) + throw new IllegalArgumentException(); + + char[] keyChars = charsOf( aKey ); + remove( keyChars, 0, keyChars.length ); + } + + private boolean remove( char[] aKey, int offset, int length ) { + if ( offset == length ) + return removeAtEndOfKey(); + + char nextChar = aKey[ offset ]; + AbbreviationMap child = children.get( nextChar ); + if ( child == null || !child.remove( aKey, offset + 1, length ) ) + return false; + + --keysBeyond; + if ( child.keysBeyond == 0 ) + children.remove( nextChar ); + if ( keysBeyond == 1 && key == null ) + setValueToThatOfOnlyChild(); + + return true; + } + + private void setValueToThatOfOnlyChild() { + Map.Entry> entry = children.entrySet().iterator().next(); + AbbreviationMap onlyChild = entry.getValue(); + value = onlyChild.value; + } + + private boolean removeAtEndOfKey() { + if ( key == null ) + return false; + + key = null; + if ( keysBeyond == 1 ) + setValueToThatOfOnlyChild(); + else + value = null; + + return true; + } + + /** + * Gives a Java map representation of this abbreviation map. + * + * @return a Java map corresponding to this abbreviation map + */ + public Map toJavaUtilMap() { + Map mappings = new TreeMap(); + addToMappings( mappings ); + return mappings; + } + + private void addToMappings( Map mappings ) { + if ( key != null ) + mappings.put( key, value ); + + for ( AbbreviationMap each : children.values() ) + each.addToMappings( mappings ); + } + + private static char[] charsOf( String aKey ) { + char[] chars = new char[ aKey.length() ]; + aKey.getChars( 0, aKey.length(), chars, 0 ); + return chars; + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Classes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Classes.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2009, 2015, 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.internal; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Paul Holser + */ +public final class Classes { + private static final Map, Class> WRAPPERS = new HashMap, Class>( 13 ); + + static { + WRAPPERS.put( boolean.class, Boolean.class ); + WRAPPERS.put( byte.class, Byte.class ); + WRAPPERS.put( char.class, Character.class ); + WRAPPERS.put( double.class, Double.class ); + WRAPPERS.put( float.class, Float.class ); + WRAPPERS.put( int.class, Integer.class ); + WRAPPERS.put( long.class, Long.class ); + WRAPPERS.put( short.class, Short.class ); + WRAPPERS.put( void.class, Void.class ); + } + + private Classes() { + throw new UnsupportedOperationException(); + } + + /** + * Gives the "short version" of the given class name. Somewhat naive to inner classes. + * + * @param className class name to chew on + * @return the short name of the class + */ + public static String shortNameOf( String className ) { + return className.substring( className.lastIndexOf( '.' ) + 1 ); + } + + /** + * Gives the primitive wrapper class for the given class. If the given class is not + * {@linkplain Class#isPrimitive() primitive}, returns the class itself. + * + * @param generic class type + * @param clazz the class to check + * @return primitive wrapper type if {@code clazz} is primitive, otherwise {@code clazz} + */ + @SuppressWarnings( "unchecked" ) + public static Class wrapperOf( Class clazz ) { + return clazz.isPrimitive() ? (Class) WRAPPERS.get( clazz ) : clazz; + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Columns.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Columns.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2015, 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.internal; + +import java.text.BreakIterator; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import static java.text.BreakIterator.*; + +import static jdk.internal.joptsimple.internal.Strings.*; + +/** + * @author Paul Holser + */ +class Columns { + private static final int INDENT_WIDTH = 2; + + private final int optionWidth; + private final int descriptionWidth; + + Columns( int optionWidth, int descriptionWidth ) { + this.optionWidth = optionWidth; + this.descriptionWidth = descriptionWidth; + } + + List fit( Row row ) { + List options = piecesOf( row.option, optionWidth ); + List descriptions = piecesOf( row.description, descriptionWidth ); + + 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 ) ) ); + + return rows; + } + + private static String itemOrEmpty( List items, int index ) { + return index >= items.size() ? "" : items.get( index ); + } + + private List piecesOf( String raw, int width ) { + List pieces = new ArrayList(); + + for ( String each : raw.trim().split( LINE_SEPARATOR ) ) + pieces.addAll( piecesOfEmbeddedLine( each, width ) ); + + return pieces; + } + + private List piecesOfEmbeddedLine( String line, int width ) { + List pieces = new ArrayList(); + + BreakIterator words = BreakIterator.getLineInstance( Locale.US ); + words.setText( line ); + + StringBuilder nextPiece = new StringBuilder(); + + int start = words.first(); + for ( int end = words.next(); end != DONE; start = end, end = words.next() ) + nextPiece = processNextWord( line, nextPiece, start, end, width, pieces ); + + if ( nextPiece.length() > 0 ) + pieces.add( nextPiece.toString() ); + + return pieces; + } + + private StringBuilder processNextWord( String source, StringBuilder nextPiece, int start, int end, int width, + List pieces ) { + StringBuilder augmented = nextPiece; + + String word = source.substring( start, end ); + if ( augmented.length() + word.length() > width ) { + pieces.add( augmented.toString().replaceAll( "\\s+$", "" ) ); + augmented = new StringBuilder( repeat( ' ', INDENT_WIDTH ) ).append( word ); + } + else + augmented.append( word ); + + return augmented; + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/ConstructorInvokingValueConverter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/ConstructorInvokingValueConverter.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2015, 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.internal; + +import java.lang.reflect.Constructor; + +import jdk.internal.joptsimple.ValueConverter; + +import static jdk.internal.joptsimple.internal.Reflection.*; + +/** + * @param constraint on the type of values being converted to + * @author Paul Holser + */ +class ConstructorInvokingValueConverter implements ValueConverter { + private final Constructor ctor; + + ConstructorInvokingValueConverter( Constructor ctor ) { + this.ctor = ctor; + } + + public V convert( String value ) { + return instantiate( ctor, value ); + } + + public Class valueType() { + return ctor.getDeclaringClass(); + } + + public String valuePattern() { + return null; + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/MethodInvokingValueConverter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/MethodInvokingValueConverter.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2015, 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.internal; + +import java.lang.reflect.Method; + +import jdk.internal.joptsimple.ValueConverter; + +import static jdk.internal.joptsimple.internal.Reflection.*; + +/** + * @param constraint on the type of values being converted to + * @author Paul Holser + */ +class MethodInvokingValueConverter implements ValueConverter { + private final Method method; + private final Class clazz; + + MethodInvokingValueConverter( Method method, Class clazz ) { + this.method = method; + this.clazz = clazz; + } + + public V convert( String value ) { + return clazz.cast( invoke( method, value ) ); + } + + public Class valueType() { + return clazz; + } + + public String valuePattern() { + return null; + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Objects.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Objects.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2015, 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.internal; + +/** + * @author Paul Holser + */ +public final class Objects { + private Objects() { + throw new UnsupportedOperationException(); + } + + /** + * 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(); + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Reflection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Reflection.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2009, 2015, 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.internal; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import static java.lang.reflect.Modifier.*; + +import jdk.internal.joptsimple.ValueConverter; + +import static jdk.internal.joptsimple.internal.Classes.*; + +/** + * Helper methods for reflection. + * + * @author Paul Holser + */ +public final class Reflection { + private Reflection() { + throw new UnsupportedOperationException(); + } + + /** + * Finds an appropriate value converter for the given class. + * + * @param a constraint on the class object to introspect + * @param clazz class to introspect on + * @return a converter method or constructor + */ + public static ValueConverter findConverter( Class clazz ) { + Class maybeWrapper = wrapperOf( clazz ); + + ValueConverter valueOf = valueOfConverter( maybeWrapper ); + if ( valueOf != null ) + return valueOf; + + ValueConverter constructor = constructorConverter( maybeWrapper ); + if ( constructor != null ) + return constructor; + + throw new IllegalArgumentException( clazz + " is not a value type" ); + } + + private static ValueConverter valueOfConverter( Class clazz ) { + try { + Method valueOf = clazz.getDeclaredMethod( "valueOf", String.class ); + if ( meetsConverterRequirements( valueOf, clazz ) ) + return new MethodInvokingValueConverter( valueOf, clazz ); + + return null; + } + catch ( NoSuchMethodException ignored ) { + return null; + } + } + + private static ValueConverter constructorConverter( Class clazz ) { + try { + return new ConstructorInvokingValueConverter( clazz.getConstructor( String.class ) ); + } + catch ( NoSuchMethodException ignored ) { + return null; + } + } + + /** + * Invokes the given constructor with the given arguments. + * + * @param constraint on the type of the objects yielded by the constructor + * @param constructor constructor to invoke + * @param args arguments to hand to the constructor + * @return the result of invoking the constructor + * @throws ReflectionException in lieu of the gaggle of reflection-related exceptions + */ + public static T instantiate( Constructor constructor, Object... args ) { + try { + return constructor.newInstance( args ); + } + catch ( Exception ex ) { + throw reflectionException( ex ); + } + } + + /** + * Invokes the given static method with the given arguments. + * + * @param method method to invoke + * @param args arguments to hand to the method + * @return the result of invoking the method + * @throws ReflectionException in lieu of the gaggle of reflection-related exceptions + */ + public static Object invoke( Method method, Object... args ) { + try { + return method.invoke( null, args ); + } + catch ( Exception ex ) { + throw reflectionException( ex ); + } + } + + @SuppressWarnings( "unchecked" ) + public static V convertWith( ValueConverter converter, String raw ) { + return converter == null ? (V) raw : converter.convert( raw ); + } + + private static boolean meetsConverterRequirements( Method method, Class expectedReturnType ) { + int modifiers = method.getModifiers(); + return isPublic( modifiers ) && isStatic( modifiers ) && expectedReturnType.equals( method.getReturnType() ); + } + + private static RuntimeException reflectionException( Exception ex ) { + if ( ex instanceof IllegalArgumentException ) + return new ReflectionException( ex ); + if ( ex instanceof InvocationTargetException ) + return new ReflectionException( ex.getCause() ); + if ( ex instanceof RuntimeException ) + return (RuntimeException) ex; + + return new ReflectionException( ex ); + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/ReflectionException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/ReflectionException.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2009, 2015, 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.internal; + +/** + * This unchecked exception wraps reflection-oriented exceptions. + * + * @author Paul Holser + */ +public class ReflectionException extends RuntimeException { + private static final long serialVersionUID = -2L; + + ReflectionException( Throwable cause ) { + super( cause ); + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Row.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Row.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2015, 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.internal; + +/** + * @author Paul Holser + */ +class Row { + final String option; + final String description; + + Row( String option, String description ) { + this.option = option; + this.description = description; + } + + @Override + public boolean equals( Object that ) { + if ( that == this ) + return true; + if ( that == null || !getClass().equals( that.getClass() ) ) + return false; + + Row other = (Row) that; + return option.equals( other.option ) && description.equals( other.description ); + } + + @Override + public int hashCode() { + return option.hashCode() ^ description.hashCode(); + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Rows.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Rows.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2015, 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.internal; + +import java.util.LinkedHashSet; +import java.util.Set; + +import static java.lang.Math.*; + +import static jdk.internal.joptsimple.internal.Strings.*; + +/** + * @author Paul Holser + */ +public class Rows { + private final int overallWidth; + private final int columnSeparatorWidth; + private final Set rows = new LinkedHashSet(); + private int widthOfWidestOption; + private int widthOfWidestDescription; + + public Rows( int overallWidth, int columnSeparatorWidth ) { + this.overallWidth = overallWidth; + this.columnSeparatorWidth = columnSeparatorWidth; + } + + public void add( String option, String description ) { + add( new Row( option, description ) ); + } + + private void add( Row row ) { + rows.add( row ); + widthOfWidestOption = max( widthOfWidestOption, row.option.length() ); + widthOfWidestDescription = max( widthOfWidestDescription, row.description.length() ); + } + + private void reset() { + rows.clear(); + widthOfWidestOption = 0; + widthOfWidestDescription = 0; + } + + public void fitToWidth() { + Columns columns = new Columns( optionWidth(), descriptionWidth() ); + + Set fitted = new LinkedHashSet(); + for ( Row each : rows ) + fitted.addAll( columns.fit( each ) ); + + reset(); + + for ( Row each : fitted ) + add( each ); + } + + public String render() { + StringBuilder buffer = new StringBuilder(); + + for ( Row each : rows ) { + pad( buffer, each.option, optionWidth() ).append( repeat( ' ', columnSeparatorWidth ) ); + pad( buffer, each.description, descriptionWidth() ).append( LINE_SEPARATOR ); + } + + return buffer.toString(); + } + + private int optionWidth() { + return min( ( overallWidth - columnSeparatorWidth ) / 2, widthOfWidestOption ); + } + + private int descriptionWidth() { + return min( ( overallWidth - columnSeparatorWidth ) / 2, widthOfWidestDescription ); + } + + private StringBuilder pad( StringBuilder buffer, String s, int length ) { + buffer.append( s ).append( repeat( ' ', length - s.length() ) ); + return buffer; + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Strings.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Strings.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2009, 2015, 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.internal; + +import java.util.Iterator; +import java.util.List; + +import static java.lang.System.*; +import static java.util.Arrays.*; + +/** + * @author Paul Holser + */ +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() { + throw new UnsupportedOperationException(); + } + + /** + * Gives a string consisting of the given character repeated the given number of times. + * + * @param ch the character to repeat + * @param count how many times to repeat the character + * @return the resultant string + */ + public static String repeat( char ch, int count ) { + StringBuilder buffer = new StringBuilder(); + + for ( int i = 0; i < count; ++i ) + buffer.append( ch ); + + return buffer.toString(); + } + + /** + * Tells whether the given string is either {@code} or consists solely of whitespace characters. + * + * @param target string to check + * @return {@code true} if the target string is null or empty + */ + public static boolean isNullOrEmpty( String target ) { + return target == null || EMPTY.equals( target ); + } + + + /** + * Gives a string consisting of a given string prepended and appended with surrounding characters. + * + * @param target a string + * @param begin character to prepend + * @param end character to append + * @return the surrounded string + */ + public static String surround( String target, char begin, char end ) { + return begin + target + end; + } + + /** + * Gives a string consisting of the elements of a given array of strings, each separated by a given separator + * string. + * + * @param pieces the strings to join + * @param separator the separator + * @return the joined string + */ + public static String join( String[] pieces, String separator ) { + return join( asList( pieces ), separator ); + } + + /** + * Gives a string consisting of the string representations of the elements of a given array of objects, + * each separated by a given separator string. + * + * @param pieces the elements whose string representations are to be joined + * @param separator the separator + * @return the joined string + */ + public static String join( List pieces, String separator ) { + StringBuilder buffer = new StringBuilder(); + + for ( Iterator iter = pieces.iterator(); iter.hasNext(); ) { + buffer.append( iter.next() ); + + if ( iter.hasNext() ) + buffer.append( separator ); + } + + return buffer.toString(); + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/DateConverter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/DateConverter.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2015, 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.DateFormat; +import java.text.ParsePosition; +import java.text.SimpleDateFormat; +import java.util.Date; + +import jdk.internal.joptsimple.ValueConversionException; +import jdk.internal.joptsimple.ValueConverter; + +/** + * Converts values to {@link Date}s using a {@link DateFormat} object. + * + * @author Paul Holser + */ +public class DateConverter implements ValueConverter { + private final DateFormat formatter; + + /** + * Creates a converter that uses the given date formatter/parser. + * + * @param formatter the formatter/parser to use + * @throws NullPointerException if {@code formatter} is {@code null} + */ + public DateConverter( DateFormat formatter ) { + if ( formatter == null ) + throw new NullPointerException( "illegal null formatter" ); + + this.formatter = formatter; + } + + /** + * Creates a converter that uses a {@link SimpleDateFormat} with the given date/time pattern. The date formatter + * created is not {@link SimpleDateFormat#setLenient(boolean) lenient}. + * + * @param pattern expected date/time pattern + * @return the new converter + * @throws NullPointerException if {@code pattern} is {@code null} + * @throws IllegalArgumentException if {@code pattern} is invalid + */ + public static DateConverter datePattern( String pattern ) { + SimpleDateFormat formatter = new SimpleDateFormat( pattern ); + formatter.setLenient( false ); + + return new DateConverter( formatter ); + } + + public Date convert( String value ) { + ParsePosition position = new ParsePosition( 0 ); + + Date date = formatter.parse( value, position ); + if ( position.getIndex() != value.length() ) + throw new ValueConversionException( message( value ) ); + + return date; + } + + public Class valueType() { + return Date.class; + } + + public String valuePattern() { + return formatter instanceof SimpleDateFormat + ? ( (SimpleDateFormat) formatter ).toPattern() + : ""; + } + + private String message( String value ) { + String message = "Value [" + value + "] does not match date/time pattern"; + if ( formatter instanceof SimpleDateFormat ) + message += " [" + ( (SimpleDateFormat) formatter ).toPattern() + ']'; + + return message; + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/InetAddressConverter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/InetAddressConverter.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2015, 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.net.InetAddress; +import java.net.UnknownHostException; + +import jdk.internal.joptsimple.ValueConversionException; +import jdk.internal.joptsimple.ValueConverter; + +/** + * Converts values to {@link java.net.InetAddress} using {@link InetAddress#getByName(String) getByName}. + * + * @author Raymund F\u00FCl\u00F6p + */ +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 ); + } + } + + public Class valueType() { + return InetAddress.class; + } + + public String valuePattern() { + return null; + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/KeyValuePair.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/KeyValuePair.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2009, 2015, 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 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 + * command line system properties.

+ * + * @author Paul Holser + */ +public final class KeyValuePair { + public final String key; + public final String value; + + private KeyValuePair( String key, String value ) { + this.key = key; + this.value = value; + } + + /** + * Parses a string assumed to be of the form key=value into its parts. + * + * @param asString key-value string + * @return a key-value pair + * @throws NullPointerException if {@code stringRepresentation} is {@code null} + */ + public static KeyValuePair valueOf( String asString ) { + int equalsIndex = asString.indexOf( '=' ); + if ( equalsIndex == -1 ) + return new KeyValuePair( asString, EMPTY ); + + String aKey = asString.substring( 0, equalsIndex ); + String aValue = equalsIndex == asString.length() - 1 ? EMPTY : asString.substring( equalsIndex + 1 ); + + return new KeyValuePair( aKey, aValue ); + } + + @Override + public boolean equals( Object that ) { + if ( !( that instanceof KeyValuePair ) ) + return false; + + KeyValuePair other = (KeyValuePair) that; + return key.equals( other.key ) && value.equals( other.value ); + } + + @Override + public int hashCode() { + return key.hashCode() ^ value.hashCode(); + } + + @Override + public String toString() { + return key + '=' + value; + } +} diff -r 4a652e4ca952 -r 462f93ab37f2 jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/RegexMatcher.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/RegexMatcher.java Tue Jan 26 09:18:51 2016 +0000 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2015, 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.util.regex.Pattern; + +import static java.util.regex.Pattern.*; + +import jdk.internal.joptsimple.ValueConversionException; +import jdk.internal.joptsimple.ValueConverter; + +/** + * Ensures that values entirely match a regular expression. + * + * @author Paul Holser + */ +public class RegexMatcher implements ValueConverter { + private final Pattern pattern; + + /** + * Creates a matcher that uses the given regular expression, modified by the given flags. + * + * @param pattern the regular expression pattern + * @param flags modifying regex flags + * @throws IllegalArgumentException if bit values other than those corresponding to the defined match flags are + * set in {@code flags} + * @throws java.util.regex.PatternSyntaxException if the expression's syntax is invalid + */ + public RegexMatcher( String pattern, int flags ) { + this.pattern = compile( pattern, flags ); + } + + /** + * Gives a matcher that uses the given regular expression. + * + * @param pattern the regular expression pattern + * @return the new converter + * @throws java.util.regex.PatternSyntaxException if the expression's syntax is invalid + */ + public static ValueConverter regex( String pattern ) { + return new RegexMatcher( pattern, 0 ); + } + + public String convert( String value ) { + if ( !pattern.matcher( value ).matches() ) { + throw new ValueConversionException( + "Value [" + value + "] did not match regex [" + pattern.pattern() + ']' ); + } + + return value; + } + + public Class valueType() { + return String.class; + } + + public String valuePattern() { + return pattern.pattern(); + } +}