/* ***************************************************************************** * $Header: /cm/ldap/src/javaldap/samples/arguments/Argument.java,v 1.4 2003/01/28 16:52:10 vtag Exp $ * Copyright (c) 2001 Novell, Inc. All Rights Reserved. * * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND * TREATIES. USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE LICENSE * AGREEMENT ACCOMPANYING THE SOFTWARE DEVELOPMENT KIT (SDK) THAT CONTAINS * THIS WORK. PURSUANT TO THE SDK LICENSE AGREEMENT, NOVELL HEREBY GRANTS TO * DEVELOPER A ROYALTY-FREE, NON-EXCLUSIVE LICENSE TO INCLUDE NOVELL'S SAMPLE * CODE IN ITS PRODUCT. NOVELL GRANTS DEVELOPER WORLDWIDE DISTRIBUTION RIGHTS * TO MARKET, DISTRIBUTE, OR SELL NOVELL'S SAMPLE CODE AS A COMPONENT OF * DEVELOPER'S PRODUCTS. NOVELL SHALL HAVE NO OBLIGATIONS TO DEVELOPER OR * DEVELOPER'S CUSTOMERS WITH RESPECT TO THIS CODE. ******************************************************************************/ package arguments; import java.util.ArrayList; import java.util.Enumeration; import java.util.NoSuchElementException; import java.text.ParseException; /** * The argument class represents a single command line argument. * The actual type of argument represented depends on the * constructor used when instantiating the class. The following * variations are allowed for kinds of Arguments. * <p> * Argument values are type Boolean, String, or Integer. * <p> * Argument values are multi-valued or single-valued. A single-valued * argument is limited to a single value, whereas a multi-valued * argument may have many values. * <p> * Arguments values are determined an option letter or a by position * on the command line. * * An option letter is represented on the command line by a dash followed * by an option letter, i.e. -a is the option a. Integer and * String option arguments have a value associated with the option, * that follows the option, i.e. for the String option -s sub, * sub is the String value for option s. * Option letters are case sensitive, i.e. -N is not the same as -n. *<p> * A positional parameter has no option letter associated with it. * Its meaning depends on its position in relation to other positional * parameters. For instance, a.txt, b.txt, c.txt could be a multivalued * positional parameter representing filenames. The parameters "user" * "password" might represent a user-name and a password used for * authentication. * Positional parameters are either of type String or Integer. *<p> * Boolean arguments are represented by a single option letter. * The presence of the option generates a value opposite to the * the default, i.e. if the default is 'false' for option 'b', then * the value for a '-b' on the command line is 'true' Boolean * options may be strung together, i.e. -abc is the same as -a -b -c * <p> * Integer and string arguments must have a value following * the option letter. Since Integer or String options are * not allowed to be strung together, the value may follow immediately * after the option or may be separated by a space, i.e. -d stop or -dstop. * If the option is multivalued, then each additional value is also * preceded by the option letter, i.e for -a dog -a cat -a pig, * dog, cat, & pig are values for the 'a' option. * * Positional parameters are order dependent, i.e. the order on the command * line determines which parameter is associated with the value. */ public class Argument { private char argumentLetter; private Object defaultValue; private String description; private String name; private boolean required; private boolean multiValued; /*protected*/ ArrayList argValues = new ArrayList(); /** * Specified whether the argument is required or optional */ final private static boolean REQUIRED = true; final private static boolean OPTIONAL = false; /** * Specified on required positional parameters to * indicate whether they are of type Integer or String */ final public static boolean REQUIRED_INTEGER = true; final public static boolean REQUIRED_STRING = false; /** * Specified on Integer or String values to indicate * whether they are single or multi-valued. */ final public static boolean MULTI_VALUED = true; final public static boolean SINGLE_VALUED = false; /** * Creates a Boolean argument * * @param argumentLetter a single character representing the argument letter * used on the command line. * @param description A string specifying the complete meaning of the * argument with possible values. It may contain * multiple lines. The description of the default * value is be appended to this description when * the usage string is formed. * @param defaultValue The value to use if no argument on the command * line is specified. */ public Argument( char argumentLetter, String description, boolean defaultValue) { setParams( argumentLetter, "", description, OPTIONAL, SINGLE_VALUED); this.defaultValue = new Boolean(defaultValue); return; } /** * Creates required positional argument * * @param type determines the the type of this required * argument #REQUIRED_INTEGER or #REQUIRED_STRING * @param name A one-word argument name. It is displayed on * the command line usage. * line description, to included in the usage string. * @param description A string specifying the complete meaning of the * argument with possible values. It may contain * multiple lines. The description of the default * value is be appended to this description when * the usage string is formed. * @param multiValued Determines if this Argument is to be multi-valued * or single valued, #MULTI_VALUED or #SINGLE_VALUED. * * @see #MULTI_VALUED * @see #SINGLE_VALUED */ public Argument( boolean type, String name, String description, boolean multiValued) { if( type == REQUIRED_INTEGER) { this.defaultValue = new Integer(0); } else { this.defaultValue = "";// Empty String } setParams( '\0', name, description, REQUIRED, multiValued); return; } /** * Creates required argument specified by an option letter * * @param type determines the the type of this required * argument #REQUIRED_INTEGER or #REQUIRED_STRING * @param argumentLetter a single character representing the argument letter * used on the command line. * @param name A one-word argument name. It is displayed on * the command line usage. * line description, to included in the usage string. * @param description A string specifying the complete meaning of the * argument with possible values. It may contain * multiple lines. The description of the default * value is be appended to this description when * the usage string is formed. * @param multiValued Determines if this Argument is to be MULTI_VALUED * or SINGLE_VALUED. * * @see #MULTI_VALUED * @see #SINGLE_VALUED * @see #REQUIRED_INTEGER * @see #REQUIRED_STRING */ public Argument( boolean type, char argumentLetter, String name, String description, boolean multiValued) { if( type == REQUIRED_INTEGER) { this.defaultValue = new Integer(0); } else { this.defaultValue = "";// Empty String } setParams( argumentLetter, name, description, REQUIRED, multiValued); return; } /** * Creates optional String positional argument * * @param name A one-word argument name. It is displayed on * the command line usage. * line description, to included in the usage string. * @param description A string specifying the complete meaning of the * argument with possible values. It may contain * multiple lines. The description of the default * value is be appended to this description when * the usage string is formed. * @param defaultValue The value to use if no argument on the command * line is specified. The type of the parameter * determines the type of argument value, i.e. * String, or Integer. * @param multiValued Determines if this Argument is to be multi-valued * or single valued, #MULTI_VALUED or #SINGLE_VALUED. * * @see #MULTI_VALUED * @see #SINGLE_VALUED */ public Argument( String name, String description, String defaultValue, boolean multiValued) { setParams( '\0', name, description, OPTIONAL, multiValued); if( defaultValue == null) { defaultValue = ""; } this.defaultValue = defaultValue; return; } /** * Creates optional Integer positional argument * * @param name A one-word argument name. It is displayed on * the command line usage. * line description, to included in the usage string. * @param description A string specifying the complete meaning of the * argument with possible values. It may contain * multiple lines. The description of the default * value is be appended to this description when * the usage string is formed. * @param defaultValue The value to use if no argument on the command * line is specified. The type of the parameter * determines the type of argument value, i.e. * String, or Integer. * @param multiValued Determines if this Argument is to be multi-valued * or single valued, #MULTI_VALUED or #SINGLE_VALUED. * * @see #MULTI_VALUED * @see #SINGLE_VALUED */ public Argument( String name, String description, int defaultValue, boolean multiValued) { setParams( '\0', name, description, OPTIONAL, multiValued); this.defaultValue = new Integer(defaultValue); return; } /** * Creates a optional String argument * * @param argumentLetter a single character representing the argument letter * used on the command line. * @param name A one-word argument name. It is displayed on * the command line usage. * line description, to included in the usage string. * @param description A string specifying the complete meaning of the * argument with possible values. It may contain * multiple lines. The description of the default * value is be appended to this description when * the usage string is formed. * @param defaultValue The value to use if no argument on the command * line is specified. The type of the parameter * determines the type of argument value, i.e. * String, or Integer. * @param multiValued Determines if this Argument is to be multi-valued * or single valued, #MULTI_VALUED or #SINGLE_VALUED. * * @see #MULTI_VALUED * @see #SINGLE_VALUED */ public Argument( char argumentLetter, String name, String description, String defaultValue, boolean multiValued) { setParams( argumentLetter, name, description, OPTIONAL, multiValued); if( defaultValue == null) { defaultValue = ""; // Make sure we have a String type here } this.defaultValue = defaultValue; return; } /** * Creates an optional Integer argument * * @param argumentLetter a single character representing the argument letter * used on the command line. * @param name A one-word argument name. It is displayed on * the command line usage. * line description, to included in the usage string. * @param description A string specifying the complete meaning of the * argument with possible values. It may contain * multiple lines. The description of the default * value is be appended to this description when * the usage string is formed. * @param defaultValue The value to use if no argument on the command * line is specified. The type of the parameter * determines the type of argument value, i.e. * String, or Integer. * @param multiValued Determines if this Argument is to be multi-valued * or single valued, #MULTI_VALUED or #SINGLE_VALUED. * * @see #MULTI_VALUED * @see #SINGLE_VALUED */ public Argument( char argumentLetter, String name, String description, int defaultValue, boolean multiValued) { setParams( argumentLetter, name, description, OPTIONAL, multiValued); this.defaultValue = new Integer(defaultValue); return; } /** * Set parameters common to all constructors * * @param argumentLetter a single character representing the argument letter * used on the command line. * @param name A one-word argument name. It is displayed on * the command line usage. * line description, to included in the usage string. * @param description A string specifying the complete meaning of the * argument with possible values. It may contain * multiple lines. The description of the default * value is be appended to this description when * the usage string is formed. * @param required Determines if this Argument is to be REQUIRED * or OPTIONAL. REQUIRED Arguments must be * present on the command line. * @param multiValued Determines if this Argument is to be multi-valued * or single valued, #MULTI_VALUED or #SINGLE_VALUED. * * @see #MULTI_VALUED * @see #SINGLE_VALUED * @see #REQUIRED_INTEGER * @see #REQUIRED_STRING */ private void setParams( char argumentLetter, String name, String description, boolean required, boolean multiValued) { this.argumentLetter = argumentLetter; this.name = name; this.description = description; this.required = required; this.multiValued = multiValued; return; } /** * Returns the number of values specified for this argument on the * command line. */ final public int getValueCount() { return argValues.size(); } /** * Add a value to this arguments values. The value must be compatible * with the default value specified on the constructor. * * @param value option value to add * * @param position parameter position, used for error message * * @return true */ final public boolean add( Object value, int position) throws ParseException { if( (argValues.size() == 1) && ! multiValued) { throw new ParseException("Parameter " + position + ": '-" + argumentLetter + "' cannot have more than one value", position); } argValues.add(value); return true; } /** * Returns the option letter associated with this argument */ final public char getArgumentLetter() { return argumentLetter; } /** * Returns the name of this argument */ final public String getName() { return name; } /** * Returns the description of this argument */ final public String getDescription() { return description; } /** * Returns true if this argument is required to be on the command line */ final public boolean isRequired() { return required; } /** * Returns true if this argument is of type Boolean */ final public boolean isBoolean() { return defaultValue instanceof Boolean; } /** * Returns true if this argument is of type Integer */ final public boolean isInteger() { return defaultValue instanceof Integer; } /** * Returns true if this argument is of type String */ final public boolean isString() { return defaultValue instanceof String; } /** * Returns true if this argument is a positional parameter */ final public boolean isPositional() { return argumentLetter == '\0'; } /** * Returns true if this argument can have more than one value */ final public boolean isMultivalued() { return multiValued; } /** * Returns the default value for this argument. The type of the default * object will be Boolean, Integer, or String. */ final public Object getDefaultValue() { return defaultValue; } /** * Returns the first value if the argument, or if the argument is single- * valued, the only argument value. */ final public Object getValue() { if( argValues.size() == 0) { return defaultValue; } return argValues.get(0); } /** * Returns an enumeration containing all the values of the argument * in the order specified on the command line. If no values were * specified, it returns an enumeration containing the default value. */ final public Enumeration getValues() { if( argValues.size() == 0) { if( isBoolean()) { return new ArgEnumeration( new Boolean[] { (Boolean)defaultValue }); } else if( isInteger()) { return new ArgEnumeration( new Integer[] { (Integer)defaultValue }); } else if( isString()) { return new ArgEnumeration( new String[] { (String)defaultValue }); } } return new ArgEnumeration( argValues.toArray()); } /** * Clears all the values of this argument. */ final public void clearValues() { argValues = new ArrayList(); return; } /** * A class to return the elements of an array as an Enumeration */ public class ArgEnumeration implements Enumeration { private Object[] eArray; private int index = 0; /** * Constructor to create the Enumeration * * @param eArray the array to use for the Enumeration */ public ArgEnumeration( Object[] eArray) { this.eArray = eArray; return; } public boolean hasMoreElements() { return (index < eArray.length); } public Object nextElement() throws NoSuchElementException { if( index >= eArray.length) { throw new NoSuchElementException("No more elements for argument " + argumentLetter); } return eArray[index++]; } } }