You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by jk...@apache.org on 2003/05/25 22:21:10 UTC

cvs commit: jakarta-commons/cli/src/java/org/apache/commons/cli CommandLineParser.java

jkeyes      2003/05/25 13:21:09

  Modified:    cli/src/java/org/apache/commons/cli Tag: cli_1_x
                        CommandLineParser.java
  Log:
  added Javadoc
  added license
  replaced tabs with spaces
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.6.2.3   +678 -276  jakarta-commons/cli/src/java/org/apache/commons/cli/CommandLineParser.java
  
  Index: CommandLineParser.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/cli/src/java/org/apache/commons/cli/CommandLineParser.java,v
  retrieving revision 1.6.2.2
  retrieving revision 1.6.2.3
  diff -u -r1.6.2.2 -r1.6.2.3
  --- CommandLineParser.java	24 May 2003 17:25:03 -0000	1.6.2.2
  +++ CommandLineParser.java	25 May 2003 20:21:09 -0000	1.6.2.3
  @@ -1,3 +1,63 @@
  +/*
  + * $Header$
  + * $Revision$
  + * $Date$
  + *
  + * ====================================================================
  + *
  + * The Apache Software License, Version 1.1
  + *
  + * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights
  + * reserved.
  + *
  + * Redistribution and use in source and binary forms, with or without
  + * modification, are permitted provided that the following conditions
  + * are met:
  + *
  + * 1. Redistributions of source code must retain the above copyright
  + *    notice, this list of conditions and the following disclaimer.
  + *
  + * 2. Redistributions in binary form must reproduce the above copyright
  + *    notice, this list of conditions and the following disclaimer in
  + *    the documentation and/or other materials provided with the
  + *    distribution.
  + *
  + * 3. The end-user documentation included with the redistribution, if
  + *    any, must include the following acknowlegement:
  + *       "This product includes software developed by the
  + *        Apache Software Foundation (http://www.apache.org/)."
  + *    Alternately, this acknowlegement may appear in the software itself,
  + *    if and wherever such third-party acknowlegements normally appear.
  + *
  + * 4. The names "The Jakarta Project", "Commons", and "Apache Software
  + *    Foundation" must not be used to endorse or promote products derived
  + *    from this software without prior written permission. For written
  + *    permission, please contact apache@apache.org.
  + *
  + * 5. Products derived from this software may not be called "Apache"
  + *    nor may "Apache" appear in their names without prior written
  + *    permission of the Apache Group.
  + *
  + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  + * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  + * SUCH DAMAGE.
  + * ====================================================================
  + *
  + * This software consists of voluntary contributions made by many
  + * individuals on behalf of the Apache Software Foundation.  For more
  + * information on the Apache Software Foundation, please see
  + * <http://www.apache.org/>;.
  + *
  + */
   package org.apache.commons.cli;
   
   import java.util.ArrayList;
  @@ -13,344 +73,686 @@
   import java.util.Set;
   import java.util.StringTokenizer;
   
  +/**
  + * Parses command line arguments based upon the rules defined
  + * in the Options that are passed to it.
  + * 
  + * @author John Keyes
  + */
   public class CommandLineParser {
   
  +    /** 
  +     * @task investigate whether this can be eliminated
  +     * 
  +     * specifies whether to stop parsing at the first unknown
  +     * token
  +     */
       private boolean stopAtUnknown;
  +    
  +    /** a store for all of the options specified in the Options instance */
       private Map cache = new HashMap(11);
  +    
  +    /** a store of the required Options */
       private Set required = new HashSet();
  +    
  +    /** 
  +     * specifies the style of parsing to use, this is currently decided
  +     * when creating the Option cache.  If each Option has a single
  +     * character name, then treat the parsing as Posix, otherwise GNU.
  +     */
       private boolean posix = true;
   
  +    /**
  +     * @task should this be a method variable rather than
  +     *       a member variable?
  +     *  
  +     * the Options to be used for the current parse
  +     */
       private Options options = null;
   
  -    public CommandLineParser( ) {
  +    /**
  +     * the Java properties that were specified on the command line
  +     */
  +    private Properties props = new Properties();
  +
  +    /** 
  +     * Creates a CommandLineParser 
  +     */
  +    public CommandLineParser() {
       }
   
  -    public CommandLineParser( boolean stopAtUnknown ) {
  +    /**
  +     * Creates a CommandLineParser that will cease parsing at
  +     * the first unknown token encountered.
  +     * 
  +     * @param stopAtUnknown
  +     *     stop at the first unknown token
  +     */
  +    public CommandLineParser(boolean stopAtUnknown) {
           this.stopAtUnknown = stopAtUnknown;
       }
   
  -	public CommandLine parse( Options options, String[] args, CommandLineCreator cmdline)
  -	throws UnknownOptionException, MissingValueException, MissingOptionException, AlreadySelectedException, ParseException {
  -		this.options = options;
  -		List tokens = Arrays.asList( args );
  -		createOptionCache( options.getOptions() );
  -
  -		int index = 0;
  -		for( ListIterator iter = tokens.listIterator(); iter.hasNext(); ) {
  -			String token = (String)iter.next();
  -
  -			if( "--".equals(token)) {
  -	            cmdline.setUnprocessed(this.processTrailingValues(iter));
  -			}
  - 			// java property
  -			else if( token.startsWith("-D") && token.length()>2) {
  -				processJavaProperty(token);
  -			}
  -			// a simple key
  -			else if( cache.containsKey( token ) ) {
  -				Option option = (Option)cache.get( token );
  -
  -				if (option instanceof Argument) {
  -					cmdline.addArgument(
  -						(Argument) option,
  -				    	processArgument((Argument) option, iter));
  -				}
  -				else {
  -					cmdline.addOption( option );
  -				}
  -				
  -				if( option.hasChildren() ) {
  -    				processChildOptions( option, args, index, cmdline );
  -				}
  -				recordIfInOptionGroup( options, option );
  -				recordIfMandatory( option );
  -			}
  -			// we need to burst the key (one character at a time)
  -			else if( posix && !token.equals("-") && token.startsWith("-") && !token.startsWith("--")) {
  -				burst( token, cmdline, iter );
  -			}
  -			else if( token.startsWith("-") && !token.equals("-") ) {
  -				char[] chars = token.toCharArray();
  -				int findex = -1;
  -				for( int i = 0; i < chars.length && findex==-1; i++){
  -					if( !Character.isJavaIdentifierPart(chars[i]) && chars[i] != '-') {
  -						findex = i;
  -					}
  -				}
  -				
  -				String ntoken = (findex != -1 ) ? token.substring(0, findex) : "";
  -				
  -				if( cache.containsKey( ntoken ) ) {
  -					Argument argument = (Argument)cache.get( ntoken );
  -
  -					cmdline.addArgument(
  -							argument,
  -							processArgument(argument, iter, token.substring(findex+1)));
  -				}
  -				else {
  -					throw new UnknownOptionException( "Unknown option {" + token + "}" );
  -				}
  -			}
  -			else if( options.hasAnonymousArgument()) {
  -				iter.previous();
  -				cmdline.addArgument(options.getAnonymousArgument(),processAnonymousValues(iter));
  -			}
  - 			else {
  -				throw new UnknownOptionException( "Unknown option {" + token + "}" );
  -			}
  -			index++;
  -		}
  -
  -		if( !options.getRequired().equals( required ) ) {
  -			throw new MissingOptionException( "All of the required arguments have not been supplied" );
  -		}
  -
  -		for( Iterator iter = options.getOptionGroups().iterator(); iter.hasNext(); ) {
  -			OptionGroup group = (OptionGroup)iter.next();
  -			
  -			if( group instanceof ExclusiveOptionGroup) {
  -				ExclusiveOptionGroup g = (ExclusiveOptionGroup)group;
  -				if( g.isMandatory() && !group.isSelected() ) {
  -					throw new MissingOptionException( "Required Option not present." );
  -				}
  -				group.setSelected(null);
  -			}
  -			else {
  -				InclusiveOptionGroup g = (InclusiveOptionGroup)group;
  -				if( !g.allFound() ) {
  -					throw new MissingOptionException( "Required inclusive");
  -				}
  -			}
  -		}
  -		cmdline.setProperties(this.props);
  -        
  -		return (CommandLine)cmdline;
  -	}
  -	
  -	Properties props = new Properties();
  -	
  -	public Properties getProperties() {
  -		return props;
  -	}
  -	
  -	private void processJavaProperty( String token ) {
  -		int sep = token.indexOf('=');
  -		
  -		String key = null;
  -		String value = null;
  -		if( sep != -1 ) {
  -			key = token.substring(2, sep);
  -			value = token.substring( sep+1, token.length());
  -		}
  -		else {
  -			key = token.substring(2, token.length());
  -			value = "";
  -		}
  -
  -		props.setProperty(key,value);
  -	}
  -		
  -	public CommandLine parse( Options options, String[] args ) 
  -	throws UnknownOptionException, MissingValueException, MissingOptionException, AlreadySelectedException, ParseException {
  -		CommandLineCreator cmdline = new CommandLineImpl();
  -		parse( options, args, cmdline);
  -        return (CommandLine)cmdline;
  +    /**
  +     * Parse the specified command line arguments using the
  +     * specified Options and populate the specified CommandLineCreator
  +     * with the results.
  +     * 
  +     * @param options
  +     *     the Options definition
  +     * 
  +     * @param args
  +     *     the command line arguments
  +     * 
  +     * @param cmdline
  +     *     the CommandLineCreator that will populate the CommandLine
  +     *     that will be returned
  +     * 
  +     * @return the CommandLine populated with the values
  +     * 
  +     * @throws UnknownOptionException
  +     *     if an option is specoified on the command line that
  +     *     is not defined in the Options
  +     * 
  +     * @throws MissingValueException
  +     *     if an Argument that requires a value does not have one
  +     *     specified on the command line
  +     * 
  +     * @throws MissingOptionException
  +     *     if a required Option is not specified on the command line
  +     * 
  +     * @throws AlreadySelectedException
  +     *     if more than one Option in an OptionGroup is present on the
  +     *     same command line
  +     */
  +    private CommandLine parse(
  +        Options options,
  +        String[] args,
  +        CommandLineCreator cmdline)
  +    throws  UnknownOptionException,
  +            MissingValueException,
  +            MissingOptionException,
  +            AlreadySelectedException {
  +
  +        this.options = options;
  +        List tokens = Arrays.asList(args);
  +        createOptionCache(options.getOptions());
  +
  +
  +        int index = 0;
  +        for (ListIterator iter = tokens.listIterator(); iter.hasNext();) {
  +            String token = (String) iter.next();
  +
  +            if (false) { 
  +                boolean a = true;
  +            }
  +
  +            if ("--".equals(token)) {
  +                List trailing = this.processTrailingValues(iter);
  +                cmdline.setUnprocessed(trailing); 
  +            }
  +            // java property
  +            else if (token.startsWith("-D") && token.length() > 2) {
  +                processJavaProperty(token);
  +            }
  +            // a simple key
  +            else if (cache.containsKey(token)) {
  +                Option option = (Option) cache.get(token);
  +
  +                if (option instanceof Argument) {
  +                    cmdline.addArgument(
  +                        (Argument) option,
  +                        processArgument((Argument) option, iter));
  +                } else {
  +                    cmdline.addOption(option);
  +                }
  +
  +                if (option.hasChildren()) {
  +                    processChildOptions(option, args, index, cmdline);
  +                }
  +                recordIfInOptionGroup(options, option);
  +                recordIfMandatory(option);
  +            }
  +            // we need to burst the key (one character at a time)
  +            else if (
  +                posix
  +                    && !token.equals("-")
  +                    && token.startsWith("-")
  +                    && !token.startsWith("--")) {
  +                burst(token, cmdline, iter);
  +            } else if (token.startsWith("-") && !token.equals("-")) {
  +                char[] chars = token.toCharArray();
  +                int findex = -1;
  +                for (int i = 0; i < chars.length && findex == -1; i++) {
  +                    if (!Character.isJavaIdentifierPart(chars[i])
  +                        && chars[i] != '-') {
  +                        findex = i;
  +                    }
  +                }
  +
  +                String ntoken =
  +                    (findex != -1) ? token.substring(0, findex) : "";
  +
  +                if (cache.containsKey(ntoken)) {
  +                    Argument argument = (Argument) cache.get(ntoken);
  +
  +                    cmdline.addArgument(
  +                        argument,
  +                        processArgument(
  +                            argument,
  +                            iter,
  +                            token.substring(findex + 1)));
  +                } else {
  +                    throw new UnknownOptionException(
  +                        "Unknown option {" + token + "}");
  +                }
  +            } else if (options.hasAnonymousArgument()) {
  +                iter.previous();
  +                cmdline.addArgument(
  +                    options.getAnonymousArgument(),
  +                    processAnonymousValues(iter));
  +            } else {
  +                throw new UnknownOptionException(
  +                    "Unknown option {" + token + "}");
  +            }
  +            index++;
  +        }
  +
  +        if (!options.getRequired().equals(required)) {
  +            throw new MissingOptionException(
  +                "All of the required arguments have not been supplied");
  +        }
  +
  +        for (Iterator iter = options.getOptionGroups().iterator();
  +            iter.hasNext();
  +            ) {
  +            OptionGroup group = (OptionGroup) iter.next();
  +
  +            if (group instanceof ExclusiveOptionGroup) {
  +                ExclusiveOptionGroup g = (ExclusiveOptionGroup) group;
  +                if (g.isMandatory() && !group.isSelected()) {
  +                    throw new MissingOptionException(
  +                        "Required Option not present.");
  +                }
  +                group.setSelected(null);
  +            } else {
  +                InclusiveOptionGroup g = (InclusiveOptionGroup) group;
  +                if (!g.allFound()) {
  +                    throw new MissingOptionException("Required inclusive");
  +                }
  +            }
  +        }
  +        cmdline.setProperties(this.props);
  +
  +        return (CommandLine) cmdline;
       }
  -    
  -    private void processChildOptions( Option option, String[] arguments, int index, CommandLineCreator cmdline) 
  -    throws UnknownOptionException, MissingValueException, MissingOptionException, AlreadySelectedException, ParseException {
  -    	
  -    	if( option.getChildren().size() > 0 ) {
  -    		Options opts = new Options();
  -    		opts.addOptions( option.getChildren() );
  -    		
  -    		String[] args = new String[arguments.length - index - 1];
  -    		System.arraycopy(arguments, index+1, args, 0, arguments.length-index-1);
  -    		parse(opts, args, cmdline);
  -    	}
  -    	
  -    }
  -
  -    private void recordIfMandatory( Option option ) {
  -        if( option.isRequired() ) {
  -            required.add( option );
  +
  +    /**
  +     * Processes the specified token as a Java property
  +     * 
  +     * @param token
  +     *     the Java property
  +     */
  +    private void processJavaProperty(String token) {
  +        int sep = token.indexOf('=');
  +
  +        String key = null;
  +        String value = null;
  +        if (sep != -1) {
  +            key = token.substring(2, sep);
  +            value = token.substring(sep + 1, token.length());
  +        } else {
  +            key = token.substring(2, token.length());
  +            value = "";
           }
  +
  +        props.setProperty(key, value);
       }
   
  -    private List processArgument( Argument argument, ListIterator iter, String arg ) 
  -        throws MissingValueException
  -    {
  -        if( arg == null || arg.startsWith( "-" ) ) {
  -            throw new MissingValueException( "Missing value for argument {" + argument.getName() + "}" );
  +    /**
  +     * @task no need for the two parse methods, refactor this
  +     *       so there is only one
  +     * 
  +     * Parse the specified command line arguments using the
  +     * specified Options and populate the specified CommandLineCreator
  +     * with the results.
  +     * 
  +     * @param options
  +     *     the Options definition
  +     * 
  +     * @param args
  +     *     the command line arguments
  +     * 
  +     * @return the CommandLine populated with the values
  +     * 
  +     * @throws UnknownOptionException
  +     *     if an option is specoified on the command line that
  +     *     is not defined in the Options
  +     * 
  +     * @throws MissingValueException
  +     *     if an Argument that requires a value does not have one
  +     *     specified on the command line
  +     * 
  +     * @throws MissingOptionException
  +     *     if a required Option is not specified on the command line
  +     * 
  +     * @throws AlreadySelectedException
  +     *     if more than one Option in an OptionGroup is present on the
  +     *     same command line
  +     */
  +    public CommandLine parse(Options options, String[] args)
  +    throws UnknownOptionException,
  +           MissingValueException,
  +           MissingOptionException,
  +           AlreadySelectedException {
  +                
  +        CommandLineCreator cmdline = new CommandLineImpl();
  +        parse(options, args, cmdline);
  +        return (CommandLine) cmdline;
  +    }
  +
  +    /**
  +     * The specified Option has children so process the
  +     * specified command line arguments, from the specified
  +     * index and populate the specified CommandLineCreator with
  +     * the results.
  +     * 
  +     * @param option
  +     *     the Option that has child Options
  +     * 
  +     * @param arguments
  +     *     the command line arguments
  +     * 
  +     * @param index
  +     *     the index where the processing of the command line
  +     *     arguments will begin
  +     * 
  +     * @param cmdline
  +     *     the CommandLineCreator that will record the results
  +     * 
  +     * @throws UnknownOptionException
  +     *     if an option is specoified on the command line that
  +     *     is not defined in the Options
  +     * 
  +     * @throws MissingValueException
  +     *     if an Argument that requires a value does not have one
  +     *     specified on the command line
  +     * 
  +     * @throws MissingOptionException
  +     *     if a required Option is not specified on the command line
  +     * 
  +     * @throws AlreadySelectedException
  +     *     if more than one Option in an OptionGroup is present on the
  +     *     same command line
  +     */
  +    private void processChildOptions(
  +        Option option,
  +        String[] arguments,
  +        int index,
  +        CommandLineCreator cmdline)
  +    throws UnknownOptionException,
  +           MissingValueException,
  +           MissingOptionException,
  +           AlreadySelectedException {
  +
  +        if (option.getChildren().size() > 0) {
  +            Options opts = new Options();
  +            opts.addOptions(option.getChildren());
  +
  +            String[] args = new String[arguments.length - index - 1];
  +            System.arraycopy(
  +                arguments,
  +                index + 1,
  +                args,
  +                0,
  +                arguments.length - index - 1);
  +            parse(opts, args, cmdline);
           }
  -        List cmdline = new ArrayList();
  +
  +    }
  +
  +    /**
  +     * If the specified Option is a required Option then
  +     * record that it has been processed.
  +     * 
  +     * @param option
  +     *     the option that is checked to see if it is required
  +     */
  +    private void recordIfMandatory(Option option) {
  +        if (option.isRequired()) {
  +            required.add(option);
  +        }
  +    }
  +
  +    /**
  +     * Determine the values for the specified Argument.
  +     * 
  +     * @param argument
  +     *     the Argument whose values must be determined
  +     * 
  +     * @param iter
  +     *     an iterator over the command line arguments
  +     * 
  +     * @param arg
  +     *     the next token in the command line arguments,
  +     * 
  +     * @return the list of values for the specified Argument
  +     * 
  +     * @throws MissingValueException
  +     *     if <code>arg</code> is null or begins with "-"
  +     */
  +    private List processArgument(
  +        Argument argument,
  +        ListIterator iter,
  +        String arg)
  +    throws MissingValueException {
           
  -        String value = stripLeadingAndTrailingQuotes(arg);
  -        if( argument.getValueSeparator() != (char)0 ) {
  -        	cmdline.addAll(getValues( stripLeadingAndTrailingQuotes(value), argument.getValueSeparator() ));
  +        if (arg == null || arg.startsWith("-")) {
  +            throw new MissingValueException(
  +                "Missing value for argument {" + argument.getName() + "}");
           }
  -        else {
  -			cmdline.add( value );
  +        List cmdline = new ArrayList();
  +
  +        String value = stripLeadingAndTrailingQuotes(arg);
  +        if (argument.getValueSeparator() != (char) 0) {
  +            cmdline.addAll(
  +                getValues(
  +                    stripLeadingAndTrailingQuotes(value),
  +                    argument.getValueSeparator()));
  +        } else {
  +            cmdline.add(value);
           }
  -		processArgument( argument , iter, cmdline );
  +        processArgument(argument, iter, cmdline);
   
           return cmdline;
       }
   
  -	private Collection getValues( String value, char separator ) {
  -		List values = new ArrayList();
  -		StringTokenizer tokenizer = new StringTokenizer(value, String.valueOf(separator));
  -		while( tokenizer.hasMoreTokens()) {
  -			values.add( tokenizer.nextToken() );
  -		}
  -		return values;
  -	}
  -	
  -	private List processArgument( Argument argument, ListIterator iter ) 
  -	throws MissingValueException
  -	{
  -		return processArgument( argument, iter, new ArrayList());
  -	}
  -	
  -    private List processArgument( Argument argument, ListIterator iter, List argList ) 
  -    throws MissingValueException
  -    {
  +    /**
  +     * Returns a collection of the individual values from the
  +     * specified value using the specified separator.
  +     * 
  +     * @param value
  +     *     the value from which the individual tokens should be
  +     *     retrieved
  +     * 
  +     * @param separator
  +     *     the character used to separate the values in the specified
  +     *     value
  +     * 
  +     * @return the collection of values
  +     */
  +    private Collection getValues(String value, char separator) {
  +        List values = new ArrayList();
  +        StringTokenizer tokenizer =
  +            new StringTokenizer(value, String.valueOf(separator));
  +        while (tokenizer.hasMoreTokens()) {
  +            values.add(tokenizer.nextToken());
  +        }
  +        return values;
  +    }
  +
  +    /**
  +     * 
  +     * @param argument
  +     *     the argument that needs values
  +     * 
  +     * @param iter
  +     *     the iterator over the command line arguments
  +     * 
  +     * @return the list of argument values
  +     * 
  +     * @throws MissingValueException
  +     *     if an Argument that requires a value does not have one
  +     *     specified on the command line
  +     */
  +    private List processArgument(Argument argument, ListIterator iter)
  +        throws MissingValueException {
  +        return processArgument(argument, iter, new ArrayList());
  +    }
  +
  +    /**
  +     * @task the processed list is a reference so it should
  +     *       not need to be returned, hold the reference in
  +     *       the calling method
  +     * 
  +     * Processes the command line arguments for the specified
  +     * argument
  +     * 
  +     * @param argument
  +     *     the argument that needs values
  +     * 
  +     * @param iter
  +     *     the iterator over the command line arguments
  +     * 
  +     * @param argList
  +     *     the list of already processed values
  +     * 
  +     * @return the list of processed values
  +     * 
  +     * @throws MissingValueException
  +     *     if an Argument that requires a value does not have one
  +     *     specified on the command line
  +     */
  +    private List processArgument(
  +        Argument argument,
  +        ListIterator iter,
  +        List argList)
  +    throws MissingValueException {
  +        
           int size = argument.getSize();
           int processed = argList.size();
  -        
  -        if( !iter.hasNext() && processed == 0) {
  -        	if( argument.hasOptionalValues() ) {
  -        		return argList;
  -        	}
  -            throw new MissingValueException( "Missing value for argument {" + argument.getName() + "}" );
  +
  +        if (!iter.hasNext() && processed == 0) {
  +            if (argument.hasOptionalValues()) {
  +                return argList;
  +            }
  +            throw new MissingValueException(
  +                "Missing value for argument {" + argument.getName() + "}");
           }
   
  -        while( processed < size && iter.hasNext() ) {
  -            String arg = (String)iter.next();
  -            if( arg != null && ("-".equals(arg) || !arg.startsWith( "-" ) )) {
  -                argList.add( stripLeadingAndTrailingQuotes(arg) );
  +        while (processed < size && iter.hasNext()) {
  +            String arg = (String) iter.next();
  +            if (arg != null && ("-".equals(arg) || !arg.startsWith("-"))) {
  +                argList.add(stripLeadingAndTrailingQuotes(arg));
                   processed++;
  -            }
  -            else if( !argument.hasOptionalValues() ){
  -                throw new MissingValueException( "Missing value for argument {" + argument.getName() + "}" );
  -            }
  -            else {
  -            	iter.previous();
  -            	return argList;
  +            } else if (!argument.hasOptionalValues()) {
  +                throw new MissingValueException(
  +                    "Missing value for argument {" + argument.getName() + "}");
  +            } else {
  +                iter.previous();
  +                return argList;
               }
           }
           return argList;
       }
   
  -    private void createOptionCache( Set options ) {
  +    /**
  +     * Processes the Options for this parse and creates the
  +     * Option and required Option caches.
  +     * 
  +     * @param options
  +     *     the Options used for the current parse
  +     */
  +    private void createOptionCache(Set options) {
           cache.clear();
           required.clear();
   
  -        for( Iterator iter = options.iterator(); iter.hasNext(); ) {
  -            Option option = (Option)iter.next();
  +        for (Iterator iter = options.iterator(); iter.hasNext();) {
  +            Option option = (Option) iter.next();
   
               String name = option.getName();
  -            if( posix ) {
  -                if( name != null && name.length() > 1 ) {
  +            if (posix) {
  +                if (name != null && name.length() > 1) {
                       posix = false;
                   }
               }
  -            cache.put( "-" + name, option );
  -            cache.put( "--" + option.getLongName(), option );
  +            cache.put("-" + name, option);
  +            cache.put("--" + option.getLongName(), option);
           }
       }
   
  -    private void burst(String token, CommandLineCreator cmdline, ListIterator iter) 
  -    throws UnknownOptionException, MissingValueException, AlreadySelectedException
  -    {
  +    /**
  +     * If the parse is a 'POSIX' one then the token may need
  +     * to be burst i.e. '-abc' is equivalent to '-a', '-b' and
  +     * '-c' if each of these were Options.  If '-a' was an 
  +     * Argument, then the tokens would be '-a' and 'bc'. 
  +     * 
  +     * @param token
  +     *     the token to burst
  +     * 
  +     * @param cmdline
  +     *     the CommandLineCreator to populate
  +     * 
  +     * @param iter
  +     *     the iterator over the command line arguments
  +     * 
  +     * @throws UnknownOptionException
  +     *     if an option is specoified on the command line that
  +     *     is not defined in the Options
  +     * 
  +     * @throws MissingValueException
  +     *     if an Argument that requires a value does not have one
  +     *     specified on the command line
  +     * 
  +     * @throws AlreadySelectedException
  +     *     if more than one Option in an OptionGroup is present on the
  +     *     same command line
  +     */
  +    private void burst(
  +        String token,
  +        CommandLineCreator cmdline,
  +        ListIterator iter)
  +    throws UnknownOptionException,
  +           MissingValueException,
  +           AlreadySelectedException {
  +               
           int tokenLength = token.length();
   
  -        for (int i = 1; i < tokenLength; i++)
  -        {
  +        for (int i = 1; i < tokenLength; i++) {
               String ch = String.valueOf(token.charAt(i));
  -            Option option = (Option)cache.get("-" + ch);
  +            Option option = (Option) cache.get("-" + ch);
   
  -            if (option != null)
  -            {
  -                if( option instanceof Argument ) {
  +            if (option != null) {
  +                if (option instanceof Argument) {
                       List args = new ArrayList();
  -                    if( token.substring(i+1).length() == 0 ) {
  -                        cmdline.addArgument((Argument)option,processArgument( (Argument)option, iter ));
  -                    }
  -                    else {
  -                        cmdline.addArgument((Argument)option, processArgument((Argument)option, iter, token.substring(i+1)));
  +                    if (token.substring(i + 1).length() == 0) {
  +                        cmdline.addArgument(
  +                            (Argument) option,
  +                            processArgument((Argument) option, iter));
  +                    } else {
  +                        cmdline.addArgument(
  +                            (Argument) option,
  +                            processArgument(
  +                                (Argument) option,
  +                                iter,
  +                                token.substring(i + 1)));
                       }
  -					recordIfInOptionGroup( this.options, option );
  -					recordIfMandatory( option );
  -					break;
  -                }
  -                else if( option instanceof Option ) {
  -                    cmdline.addOption( option );
  -					recordIfInOptionGroup( this.options, option );
  -					recordIfMandatory( option );
  +                    recordIfInOptionGroup(this.options, option);
  +                    recordIfMandatory(option);
  +                    break;
  +                } else if (option instanceof Option) {
  +                    cmdline.addOption(option);
  +                    recordIfInOptionGroup(this.options, option);
  +                    recordIfMandatory(option);
                   }
  +            } else {
  +                throw new UnknownOptionException("Unknown option {" + ch + "}");
               }
  -            else {
  -                throw new UnknownOptionException( "Unknown option {" + ch + "}" );
  +        }
  +    }
  +
  +    /**
  +     * @task review the OptionGroup behaviour
  +     * 
  +     * If the specified Option is a member of an OptionGroup then
  +     * record that it has been found.
  +     * 
  +     * @param options
  +     *     the Options instance
  +     * 
  +     * @param option
  +     *     the Option that is being tested
  +     * 
  +     * @throws AlreadySelectedException 
  +     *     if the group is an Exclusive one and an Option from that
  +     *     group has already been selected.
  +     */
  +    private void recordIfInOptionGroup(Options options, Option option)
  +        throws AlreadySelectedException {
  +        for (Iterator iter = options.getOptionGroups().iterator();
  +            iter.hasNext();
  +            ) {
  +            OptionGroup group = (OptionGroup) iter.next();
  +
  +            if (group instanceof ExclusiveOptionGroup) {
  +                if (group.containsOption(option)) {
  +                    if (group.isSelected()) {
  +                        throw new AlreadySelectedException(
  +                            "Option already selected");
  +                    } else {
  +                        group.setSelected(option);
  +                    }
  +                }
  +            } else if (group instanceof InclusiveOptionGroup) {
  +                ((InclusiveOptionGroup) group).setFound(option);
               }
           }
  +
  +    }
  +
  +    /**
  +     * Return all of the values that have not been processed.
  +     * 
  +     * @param iter
  +     *     the iterator over the command line arguments
  +     * 
  +     * @return the List of the command line arguments that remain
  +     */
  +    private List processTrailingValues(Iterator iter) {
  +        List args = new ArrayList();
  +
  +        while (iter.hasNext()) {
  +            args.add(iter.next());
  +        }
  +        return args;
       }
  -    
  -    private void recordIfInOptionGroup( Options options, Option option ) 
  -    throws AlreadySelectedException
  -    {
  -		for (Iterator iter = options.getOptionGroups().iterator();
  -			iter.hasNext();
  -			) {
  -			OptionGroup group = (OptionGroup) iter.next();
  -
  -			if (group instanceof ExclusiveOptionGroup) {
  -				if (group.containsOption(option)) {
  -					if (group.isSelected()) {
  -						throw new AlreadySelectedException("Option already selected");
  -					} else {
  -						group.setSelected(option);
  -					}
  -				}
  -			}
  -			else if(group instanceof InclusiveOptionGroup) {
  -				((InclusiveOptionGroup)group).setFound(option);
  -			}
  -		}
  -
  -    }
  -	
  -	private List processTrailingValues( Iterator iter ) {
  -		List args = new ArrayList();
  -		
  -		while( iter.hasNext() ) {
  -			args.add( iter.next() );
  -		}
  -		return args;
  -	}
  -	
  -	private List processAnonymousValues( Iterator iter )
  -	throws ParseException 
  -	{
  -		List args = new ArrayList();
  -		
  -		while( iter.hasNext() ) {
  -			String value = (String)iter.next();
  -			//if( value.startsWith("-") )	{
  -			//	throw new ParseException( "option str in anonymous values" );
  -			//}
  -			args.add( value );
  -		}
  -		return args;
  -	}
  -	
  -    static String stripLeadingAndTrailingQuotes(String str)
  -    {
  +
  +    /**
  +     * All of the values that remain will be added to the anonymous
  +     * argument.
  +     * 
  +     * @param iter
  +     *     the iterator over the command line arguments
  +     * 
  +     * @return the List of the command line arguments that remain
  +     */
  +    private List processAnonymousValues(Iterator iter) {
  +        List args = new ArrayList();
  +
  +        while (iter.hasNext()) {
  +            String value = (String) iter.next();
  +            //if( value.startsWith("-") ) {
  +            //throw new ParseException( "option str in anonymous values" );
  +            //}
  +            args.add(value);
  +        }
  +        return args;
  +    }
  +
  +    /**
  +     * Removes the leading " and trailing " from the specified string
  +     * 
  +     * @param str
  +     *     the string that must be processed
  +     * 
  +     * @return <code>str</code> with its leading and trailing quotes (if there
  +     *     are any)
  +     */
  +    static String stripLeadingAndTrailingQuotes(String str) {
           if (str.startsWith("\"")) {
               str = str.substring(1, str.length());
           }
           if (str.endsWith("\"")) {
  -            str = str.substring(0, str.length()-1);
  +            str = str.substring(0, str.length() - 1);
           }
           return str;
       }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org