fc.util
Class Args

java.lang.Object
  extended by fc.util.Args

public class Args
extends Object

Manages arguments passed to an application. Arguments can be optional or required. Arguments received by this class have to be either of the following formats:

-flagname1 value -flagname2=value2 .
Arguments consist of flag name and flag value pairs. All flags must begin with a '-' character and any new word beginning with a '-' character is seen as the start of a new flag name (the '-' character is always permissible inside a token, i.e., after the first character). Additionaly, a flag name is delimited from it's corresponding value by either a space or the '=' character.

Note, in the above example, - flagname1 is separated from it's value by a space whereas - flagname2 is seperated from it's value by a '=' character. Both delimiters are valid and can be intermixed on the same line.

Note also that if the delimiter is a space, then the value part cannot begin with the - character, but if the delimiter is =, then the value part can begin with the - character. That is, the following input is valid:

-flagname1=-value-for-flag1

whereas this is invalid:

-flagname1 -value-for-flag1
Here, -value-for-flag1 is seen as a new flag itself.

Following a flag name, all following values are assigned to that flagname, up until another flagname is encountered or the end of input is reached. Therefore, spaces do not have to be quoted. The following example,

-path \some file\some where else -port 80
is parsed as:
path
\some file\some where else
port
80

Different operating systems (and their command interpreters) also transform/modify command lines in various ways. This class (and Java/JVM) can only parse arguments that it recieves from the operating system and those may be different than what you may have specified on the command line, due to the aforementioned transformation. The following example,

-path "/foo/bar /baz" -anotherpath \"a/b c/\"
is parsed as:
path
/foo/bar /baz
anotherpath
"a/b c/"
Note, that the path value has lost it's double quotes whereas the anotherpath value has not. This is because the O.S., in this case, stripped the quotes for path since they were not escaped on the command line. Note also that various unix'en convert command line args into space delimited tokens. bash for example tokenizes the lines using the IFS variable, and then feeds the tokens (separated by space) to the invoked program, in this case, the java interpreter.

Sometimes flags are specified without any corresponding value, with the existence of the flag itself implying some condition. However for clarity, it's sometimes better to explicitly set an option to yes or no. Therefore instead of saying -flag, always say -flag=[yes|no], with the value part being "yes" or "no". However, the existence of the flag by itself can be simply checked by using the flagExists() method.

Typical usage of this class may look like:

//inside the main method Args myargs = new Args(args); args.setUsage("java myApp -port 80 -foo=moo -debugport=5432"); //to inform user int port = args.getRequired("port"); //get required "-port" flag String abc = args.get("foo"); //get optional "-foo" flag String bar = args.get("bar","5000"); //get optional "bar" flag, default to "5000"

Thread Safety: This class is thread safe and can be used by multiple threads after it's instantiated.

Version:
1.0 7/15/2001

Field Summary
static String DEFAULT_FLAGNAME
          If a flag name is not well formed, then the corresponding value (if any) is stored under this name.
static String FLAG_REPEAT_VALUE_DELIM
          If a flag name is repeated, then all corresponding values for that name are concatenated with each other and the concatenated values are delimited by this value.
 
Constructor Summary
Args(InputStream in)
          Creates a new instance, with the specified InputStream to read arguments from.
Args(String[] args)
          Creates a new instance, with the specified String[] to read arguments from.
 
Method Summary
 boolean flagExists(String flagname)
          Checks if the specified flag exits, regardless of whether a corresponding value exist for that flag.
 String get(int n)
          Returns an argument by positional value.
 String get(String flagname)
          Returns the value corresponding to the specified flag.
 String get(String flagname, String backup)
          Returns the value corresponding to the specified flag.
 boolean getBoolean(String flagname, boolean backup)
          Returns the value corresponding to the specified flag.
 int getFlagCount()
          Returns the total number of flags available
 Date getFriendlyDate(String flagname)
          Returns the value as a Date.
 int getInt(String flagname, int backup)
          Returns the value corresponding to the specified flag.
 long getLong(String flagname, long backup)
          Returns the value corresponding to the specified flag.
 String getMainClassName()
          Returns the fully qualified name of the class that contained the main() method used to invoke the application.
 String getRequired(int n)
          Returns a required argument by positional value.
 String getRequired(String flagname)
          Returns the value corresponding to the specified flag.
 boolean getRequiredBoolean(String flagname)
           
 File getRequiredFile(String flagname)
          Returns the value obtained via getRequired(String) as a File.
 Date getRequiredFriendlyDate(String flagname)
          Returns the value as a Date.
 int getRequiredInt(String flagname)
           
 int getRequiredInteger(String flagname)
          another alias for getRequiredInt(String)
 long getRequiredLong(String flagname)
           
 String getRequiredString(String flagname)
          another alias for getRequired(String)
 void isMutuallyExclusive(String... flags)
          Checks to see that one and only 1 of the specified flags is present.
static void main(String[] args)
           
 void onlyOneOf(String... flags)
          Checks to see that one and only 1 of the specified flags is present.
 String[] rawValues()
          Returns the raw String[] passed to this object during construction.
 void setDefaultUsage(Object caller)
          Convenience method to display the usage information in case of program error.
 void setDefaultUsage(String pathToFile)
          Convenience method to display the usage information in case of program error.
 void setUsage(String str)
          Specify program usage information to be output when an error occurs.
 void showError()
          Invoking this method gives the same results as invoking getRequired with a non-existent flag name.
 Map values()
          Returns a Map containing all flagname/flagvalue pairs.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

DEFAULT_FLAGNAME

public static String DEFAULT_FLAGNAME
If a flag name is not well formed, then the corresponding value (if any) is stored under this name. For example:
- abc
is missing a flagname ('-' followed by whitespace), therefore the value abc is stored under this default name.


FLAG_REPEAT_VALUE_DELIM

public static String FLAG_REPEAT_VALUE_DELIM
If a flag name is repeated, then all corresponding values for that name are concatenated with each other and the concatenated values are delimited by this value. It's value in this class is ,. For example:
-foo abc -foo xyz
has the same flag repeated twice (foo) and the resulting value for this flag will be
abc,xyz

Constructor Detail

Args

public Args(String[] args)
Creates a new instance, with the specified String[] to read arguments from. Typically, the static void main(String[] args) method gets a String[] array from the JVM, containing the arguments passed to the application. This array will typically be be passed to this constructor.


Args

public Args(InputStream in)
Creates a new instance, with the specified InputStream to read arguments from. Reads as much as possible from the specified stream, so as to not block and delay the construction of this object. Any data not available via the specified InputStream at the time of construction, is not used later on and is essentially lost. The stream encoding is assumed to be ISO-8859-1, i.e., the flags names and values read from the stream are treated as normal ascii characters. Be aware of differences between parsing command line args and parsing args from a file, because typically command line args are modified by the shell before being passed to the application.

Method Detail

flagExists

public boolean flagExists(String flagname)
Checks if the specified flag exits, regardless of whether a corresponding value exist for that flag. For example, suppose the invoked arguments looked like:
-foo -bar=baz
. Then the flag foo would exist but have no corresponding value.

Parameters:
flagname - the flagname to check
Returns:
true if flag exists, false otherwise

getFlagCount

public int getFlagCount()
Returns the total number of flags available


getMainClassName

public String getMainClassName()
Returns the fully qualified name of the class that contained the main() method used to invoke the application. Note: this method must be called from the same thread (the "main" thread) that started the application. Newly started threads that call this method will instead obtain the class name containing that thread's run() method.


get

public String get(int n)
Returns an argument by positional value. get(n) is the same as static void main(String[] args) --> args[n] and is provided here for convenience.

Parameters:
n - the 0-based index of the String[] passed to main()
Throws:
NullPointerException - if the specified index is greater than the number of arguments

getRequired

public String getRequired(int n)
Returns a required argument by positional value. get(n) is the same as static void main(String[] args) --> args[n] and is provided here for convenience. Ff the specified index is greater than the number of arguments, then the error is handled in the same way as getRequired(String)

Parameters:
n - the 0-based index of the String[] passed to main()

get

public String get(String flagname)
Returns the value corresponding to the specified flag.

Parameters:
flagname - the name of the flag without the leading - character
Returns:
null either if the flag itself was not found, or if the flag was found but no associated value was found.

get

public String get(String flagname,
                  String backup)
Returns the value corresponding to the specified flag. If the flag and/or it's value is not found, this method returns the specified backup value instead.

Parameters:
flagname - the name of the flag without the leading - character
backup - the value to return if flag not found
Returns:
value of specified flag or backup string

getBoolean

public boolean getBoolean(String flagname,
                          boolean backup)
Returns the value corresponding to the specified flag. If the flag and/or it's value is not found, this method returns the specified backup value instead. If the property is present, then the corresponding value is true if the property value is any of the following (case-insensitive):
yes, 1, true
else false is returned. Also see flagExists(java.lang.String).

Parameters:
flagname - the name of the flag without the leading - character
backup - value to return if the property for the specified property is not present
Returns:
value of specified key or backup string

getInt

public int getInt(String flagname,
                  int backup)
Returns the value corresponding to the specified flag. If the flag and/or it's value is not found or is found but cannot be converted into an integer (via a Integer.parseInt(String) call), the backup value will be returned.

Parameters:
flagname - the name of the flag without the leading - character
backup - value to return if the property for the specified property is not present
Returns:
value of specified key or backup string

getLong

public long getLong(String flagname,
                    long backup)
Returns the value corresponding to the specified flag. If the flag and/or it's value is not found or is found but cannot be converted into an long (via a Long.parseLong(String) call), the backup value will be returned.

Parameters:
flagname - the name of the flag without the leading - character
backup - value to return if the property for the specified property is not present
Returns:
value of specified key or backup string

getRequired

public String getRequired(String flagname)
Returns the value corresponding to the specified flag. If the flag's value is not found (even if the flag name exists), this method calls the error method, which by default prints a stack trace and exits the application.

If the handleError method is overriden to not exit the application, then this method will return null if the specified flag is not found.

Parameters:
flagname - the name of the flag without the leading '-' character
Returns:
value of specified flag
See Also:
handleError(java.lang.String)

getRequiredString

public String getRequiredString(String flagname)
another alias for getRequired(String)


getRequiredBoolean

public boolean getRequiredBoolean(String flagname)

getRequiredFile

public File getRequiredFile(String flagname)
Returns the value obtained via getRequired(String) as a File.

If the handleError method is overriden to not exit the application, then this method will return false if the specified file does not exist.


getRequiredInt

public int getRequiredInt(String flagname)

getRequiredInteger

public int getRequiredInteger(String flagname)
another alias for getRequiredInt(String)


getRequiredLong

public long getRequiredLong(String flagname)

getRequiredFriendlyDate

public Date getRequiredFriendlyDate(String flagname)
Returns the value as a Date. Understands the following (case-insensitive) values
now, today
today's date (this instant)
tomorrow
tomorrow's date (24 hours from now)
nextweek
a date representing 1 week from now
atweekbegin, atbeginweek, atbeginofweek
first day of the current week

If none of these special keywords are found, returns the value by trying to parsing it as: yyyy-MM-dd HH:mm:ss or yyyy-MM-dd

If the date cannot be parsed using either of the above patterns, an exception is thrown.


getFriendlyDate

public Date getFriendlyDate(String flagname)
Returns the value as a Date. Understands the following (case-insensitive) values
now, today
today's date (this instant)
tomorrow
tomorrow's date (24 hours from now)
nextweek
a date representing 1 week from now
atweekbegin, atbeginweek, atbeginofweek
first day of the current week

If none of these special keywords are found, returns the value by trying to parsing it as: yyyy-MM-dd HH:mm:ss or yyyy-MM-dd

The flag is optional but if it is present and cannot be parsed using either of the above patterns, an exception is thrown.


onlyOneOf

public void onlyOneOf(String... flags)
Checks to see that one and only 1 of the specified flags is present. Useful for mutualy exclusive arguments.


isMutuallyExclusive

public void isMutuallyExclusive(String... flags)
Checks to see that one and only 1 of the specified flags is present. Useful for mutualy exclusive arguments. Alias for the onlyOneOf method.


rawValues

public String[] rawValues()
Returns the raw String[] passed to this object during construction. If an InputStream was passed in via construction, returns a String[] created from that InputStream (tokenized by whitespace). The returned String[] is modifiable but it's modification will not affect any other method in this class.

Returns:
String[] of unparsed values

values

public Map values()
Returns a Map containing all flagname/flagvalue pairs. The returned map is an unmodifiable view of the map contained in this class.

Returns:
Map of flagnames/values

setUsage

public void setUsage(String str)
Specify program usage information to be output when an error occurs. This information should contain a short description of expected and/or optional flags and information that the application expects.

Parameters:
str - Usage information

setDefaultUsage

public void setDefaultUsage(Object caller)
Convenience method to display the usage information in case of program error. Reads and sets the usage file found in the same directory/resource location as the calling object's package. For example, if clazz a.b.foo calls this method, then the usage file should exist in the a/b directory (typically starting from the classpath or a jar/zip file).

The name of the usage file is the same as the class name of the specified object (without the ending ".java") appended with "_usage.txt". Therefore the usage file for code residing in a.b.foo.java should be called foo_usage.txt and reside in the a/b directory.

Parameters:
caller - the calling object or Class Class corresponding to that object

setDefaultUsage

public void setDefaultUsage(String pathToFile)
Convenience method to display the usage information in case of program error. Reads and sets the usage file found specified by the pathToFile argument of this method. This path should be a path to a file reachable from any directory in the classpath (i.e., relative to the classpath) and should not start with a "/"


showError

public void showError()
Invoking this method gives the same results as invoking getRequired with a non-existent flag name.


main

public static void main(String[] args)
                 throws Exception
Throws:
Exception