jkeyes 2002/11/25 15:43:41 Modified: cli/src/java/org/apache/commons/cli Option.java Options.java Parser.java cli/src/test/org/apache/commons/cli BugsTest.java ValuesTest.java Log: fix bug 14786, some refactorings Revision Changes Path 1.18 +160 -122 jakarta-commons/cli/src/java/org/apache/commons/cli/Option.java Index: Option.java =================================================================== RCS file: /home/cvs/jakarta-commons/cli/src/java/org/apache/commons/cli/Option.java,v retrieving revision 1.17 retrieving revision 1.18 diff -u -r1.17 -r1.18 --- Option.java 19 Nov 2002 22:53:08 -0000 1.17 +++ Option.java 25 Nov 2002 23:43:40 -0000 1.18 @@ -287,101 +287,104 @@ return this.description; } - /** - * <p>Query to see if this Option requires an argument</p> - * - * @return boolean flag indicating if an argument is required - */ - public boolean isRequired() { - return this.required; - } - - /** - * <p>Sets whether this Option is mandatory.</p> - * - * @param required specifies whether this Option is mandatory - */ - public void setRequired( boolean required ) { - this.required = required; - } - - /** - * <p>Sets the display name for the argument value.</p> - * - * @param argName the display name for the argument value. - */ - public void setArgName( String argName ) { - this.argName = argName; - } - - /** - * <p>Gets the display name for the argument value.</p> - * - * @return the display name for the argument value. - */ - public String getArgName() { - return this.argName; - } - - /** - * <p>Returns whether the display name for the argument value - * has been set.</p> - * - * @return if the display name for the argument value has been - * set. - */ - public boolean hasArgName() { - return (this.argName != null && this.argName.length() > 0 ); - } - - /** - * <p>Query to see if this Option can take many values</p> - * - * @return boolean flag indicating if multiple values are allowed - */ - public boolean hasArgs() { - return ( this.numberOfArgs > 1 || this.numberOfArgs == UNLIMITED_VALUES ); - } - - /** - * <p>Sets the number of argument values this Option can take.</p> - * - * @param num the number of argument values - */ - public void setArgs( int num ) { - this.numberOfArgs = num; - } - - /** - * <p>Sets the value separator. For example if the argument value - * was a Java property, the value separator would be '='.</p> - * - * @param sep The value separator. - */ - public void setValueSeparator( char sep ) { - this.valuesep = sep; - } - - /** - * <p>Returns the value separator character.</p> - * - * @return the value separator character. - */ - public char getValueSeparator() { - return this.valuesep; - } - - /** - * <p>Returns the number of argument values this Option can take.</p> - * - * @return num the number of argument values - */ - public int getArgs( ) { - return this.numberOfArgs; - } + /** + * <p>Query to see if this Option requires an argument</p> + * + * @return boolean flag indicating if an argument is required + */ + public boolean isRequired() { + return this.required; + } + + /** + * <p>Sets whether this Option is mandatory.</p> + * + * @param required specifies whether this Option is mandatory + */ + public void setRequired( boolean required ) { + this.required = required; + } - public void clearValues() { - this.values.clear(); + /** + * <p>Sets the display name for the argument value.</p> + * + * @param argName the display name for the argument value. + */ + public void setArgName( String argName ) { + this.argName = argName; + } + + /** + * <p>Gets the display name for the argument value.</p> + * + * @return the display name for the argument value. + */ + public String getArgName() { + return this.argName; + } + + /** + * <p>Returns whether the display name for the argument value + * has been set.</p> + * + * @return if the display name for the argument value has been + * set. + */ + public boolean hasArgName() { + return (this.argName != null && this.argName.length() > 0 ); + } + + /** + * <p>Query to see if this Option can take many values</p> + * + * @return boolean flag indicating if multiple values are allowed + */ + public boolean hasArgs() { + return this.numberOfArgs > 1 || this.numberOfArgs == UNLIMITED_VALUES; + } + + /** + * <p>Sets the number of argument values this Option can take.</p> + * + * @param num the number of argument values + */ + public void setArgs( int num ) { + this.numberOfArgs = num; + } + + /** + * <p>Sets the value separator. For example if the argument value + * was a Java property, the value separator would be '='.</p> + * + * @param sep The value separator. + */ + public void setValueSeparator( char sep ) { + this.valuesep = sep; + } + + /** + * <p>Returns the value separator character.</p> + * + * @return the value separator character. + */ + public char getValueSeparator() { + return this.valuesep; + } + + /** + * ... + */ + public boolean hasValueSeparator() { + return ( this.valuesep > 0 ); + } + + /** + * <p>Returns the number of argument values this Option can take.</p> + * + * @return num the number of argument values + */ + public int getArgs( ) { + return this.numberOfArgs; } /** @@ -389,38 +392,73 @@ * * @param value is a/the value of this Option */ - public boolean addValue( String value ) { - + void addValue( String value ) + { switch( numberOfArgs ) { case UNINITIALIZED: - return false; - case UNLIMITED_VALUES: - if( getValueSeparator() > 0 ) { - int index = 0; - while( (index = value.indexOf( getValueSeparator() ) ) != -1 ) { - this.values.add( value.substring( 0, index ) ); - value = value.substring( index+1 ); - } - } - this.values.add( value ); - return true; + break; default: - if( getValueSeparator() > 0 ) { - int index = 0; - while( (index = value.indexOf( getValueSeparator() ) ) != -1 ) { - if( values.size() > numberOfArgs-1 ) { - return false; - } - this.values.add( value.substring( 0, index ) ); - value = value.substring( index+1 ); - } - } - if( values.size() > numberOfArgs-1 ) { - return false; - } - this.values.add( value ); - return true; + processValue( value ); + } + } + + /** + * <p>Processes the value. If this Option has a value separator + * the value will have to be parsed into individual tokens. When + * n-1 tokens have been processed and there are more value separators + * in the value, parsing is ceased and the remaining characters are + * added as a single token.</p> + * + * @since 1.0.1 + */ + private void processValue( String value ) { + + // this Option has a separator character + if( hasValueSeparator() ) { + + // get the separator character + char sep = getValueSeparator(); + + // store the index for the value separator + int index = value.indexOf( sep ); + + // while there are more value separators + while( index != -1 ) { + + // next value to be added + if( values.size() == numberOfArgs-1 ) { + break; + } + + // store + add( value.substring( 0, index ) ); + + // parse + value = value.substring( index+1 ); + + // get new index + index = value.indexOf( sep ); + } + } + + // store the actual value or the last value that has been parsed + add( value ); + } + + /** + * <p>Add the value to this Option. If the number of arguments + * is greater than zero and there is enough space in the list then + * add the value. Otherwise, throw a runtime exception. + * </p> + * + * @since 1.0.1 + */ + private void add( String value ) { + if( numberOfArgs > 0 && values.size() > numberOfArgs-1 ) { + throw new RuntimeException( "Cannot add value, list full." ); } + // store value + this.values.add( value ); } /** 1.17 +10 -11 jakarta-commons/cli/src/java/org/apache/commons/cli/Options.java Index: Options.java =================================================================== RCS file: /home/cvs/jakarta-commons/cli/src/java/org/apache/commons/cli/Options.java,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- Options.java 18 Nov 2002 08:41:26 -0000 1.16 +++ Options.java 25 Nov 2002 23:43:40 -0000 1.17 @@ -165,20 +165,19 @@ * @return the resulting Options instance */ public Options addOption(Option opt) { - String shortOpt = opt.getOpt(); + String key = opt.getKey(); - // add it to the long option list - if ( opt.hasLongOpt() ) { - longOpts.put( opt.getLongOpt(), opt ); - } + // add it to the long option list + if ( opt.hasLongOpt() ) { + longOpts.put( opt.getLongOpt(), opt ); + } - // if the option is required add it to the required list - if ( opt.isRequired() ) { - requiredOpts.add( opt.getKey() ); - } + // if the option is required add it to the required list + if ( opt.isRequired() && !requiredOpts.contains( key ) ) { + requiredOpts.add( key ); + } + shortOpts.put( key, opt ); - shortOpts.put( shortOpt, opt ); - return this; } 1.9 +12 -7 jakarta-commons/cli/src/java/org/apache/commons/cli/Parser.java Index: Parser.java =================================================================== RCS file: /home/cvs/jakarta-commons/cli/src/java/org/apache/commons/cli/Parser.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- Parser.java 18 Nov 2002 08:41:26 -0000 1.8 +++ Parser.java 25 Nov 2002 23:43:40 -0000 1.9 @@ -299,9 +299,14 @@ break; } // found a value - else if( !opt.addValue( str ) ) { - iter.previous(); - break; + else { + try { + opt.addValue( str ) ; + } + catch( RuntimeException exp ) { + iter.previous(); + break; + } } } 1.12 +19 -1 jakarta-commons/cli/src/test/org/apache/commons/cli/BugsTest.java Index: BugsTest.java =================================================================== RCS file: /home/cvs/jakarta-commons/cli/src/test/org/apache/commons/cli/BugsTest.java,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- BugsTest.java 18 Nov 2002 08:41:26 -0000 1.11 +++ BugsTest.java 25 Nov 2002 23:43:41 -0000 1.12 @@ -343,4 +343,22 @@ fail( "Unexpected exception: " + exp.getClass().getName() + ":" + exp.getMessage() ); } } + + public void test14786() { + Option o = OptionBuilder.isRequired().withDescription("test").create("test"); + Options opts = new Options(); + opts.addOption(o); + opts.addOption(o); + + CommandLineParser parser = new GnuParser(); + + String[] args = new String[] { "-test" }; + try { + CommandLine line = parser.parse( opts, args ); + } + catch( ParseException exp ) { + fail( "Unexpected exception:" + exp.getMessage() ); + } + } + } 1.9 +2 -2 jakarta-commons/cli/src/test/org/apache/commons/cli/ValuesTest.java Index: ValuesTest.java =================================================================== RCS file: /home/cvs/jakarta-commons/cli/src/test/org/apache/commons/cli/ValuesTest.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- ValuesTest.java 19 Sep 2002 22:59:44 -0000 1.8 +++ ValuesTest.java 25 Nov 2002 23:43:41 -0000 1.9 @@ -192,8 +192,8 @@ String[] values = new String[] { "key", "value", "key", "value" }; assertTrue( _cmdline.hasOption( "j" ) ); assertTrue( _cmdline.hasOption( 'j' ) ); - assertTrue( _cmdline.getOptionValues( "j" ).length == 4); - assertTrue( _cmdline.getOptionValues( 'j' ).length == 4); + assertEquals( 4, _cmdline.getOptionValues( "j" ).length ); + assertEquals( 4, _cmdline.getOptionValues( 'j' ).length ); assertTrue( Arrays.equals( values, _cmdline.getOptionValues( "j" ) ) ); assertTrue( Arrays.equals( values, _cmdline.getOptionValues( 'j' ) ) );
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>