package com.minres.scviewer.e4.application.options; /** * The central class for option processing. Sets are identified by their name, but there is also * an anonymous default set, which is very convenient if an application requieres only one set. */ public class Options { private final static String CLASS = "Options"; /** * The name used internally for the default set */ public final static String DEFAULT_SET = "DEFAULT_OPTION_SET"; /** * An enum encapsulating the possible separators between value options and their actual values. */ public enum Separator { /** * Separate option and value by ":" */ COLON(':'), /** * Separate option and value by "=" */ EQUALS('='), /** * Separate option and value by blank space */ BLANK(' '), // Or, more precisely, whitespace (as allowed by the CLI) /** * This is just a placeholder in case no separator is required (i. e. for non-value options) */ NONE('D'); // NONE is a placeholder in case no separator is required, 'D' is just an arbitrary dummy value private char c; private Separator(char c) { this.c = c; } /** * Return the actual separator character *
* @return The actual separator character */ char getName() { return c; } } /** * An enum encapsulating the possible prefixes identifying options (and separating them from command line data items) */ public enum Prefix { /** * Options start with a "-" (typically on Unix platforms) */ DASH('-'), /** * Options start with a "/" (typically on Windows platforms) */ SLASH('/'); private char c; private Prefix(char c) { this.c = c; } /** * Return the actual prefix character *
* @return The actual prefix character
*/
char getName() {
return c;
}
}
/**
* An enum encapsulating the possible multiplicities for options
*/
public enum Multiplicity {
/**
* Option needs to occur exactly once
*/
ONCE,
/**
* Option needs to occur at least once
*/
ONCE_OR_MORE,
/**
* Option needs to occur either once or not at all
*/
ZERO_OR_ONE,
/**
* Option can occur any number of times
*/
ZERO_OR_MORE;
}
private java.util.HashMap
* @param args The command line arguments to check
* @param prefix The prefix to use for all command line options. It can only be set here for all options at
* the same time
* @param defaultMultiplicity The default multiplicity to use for all options (can be overridden when adding an option)
* @param defMinData The default minimum number of data items for all sets (can be overridden when adding a set)
* @param defMaxData The default maximum number of data items for all sets (can be overridden when adding a set)
*
* @throws IllegalArgumentException If either
* @param args The command line arguments to check
* @param prefix The prefix to use for all command line options. It can only be set here for all options at
* the same time
* @param defaultMultiplicity The default multiplicity to use for all options (can be overridden when adding an option)
* @param data The default minimum and maximum number of data items for all sets (can be overridden when adding a set)
*
* @throws IllegalArgumentException If either
* @param args The command line arguments to check
* @param prefix The prefix to use for all command line options. It can only be set here for all options at
* the same time
* @param defaultMultiplicity The default multiplicity to use for all options (can be overridden when adding an option)
*
* @throws IllegalArgumentException If either
* @param args The command line arguments to check
* @param defaultMultiplicity The default multiplicity to use for all options (can be overridden when adding an option)
* @param defMinData The default minimum number of data items for all sets (can be overridden when adding a set)
* @param defMaxData The default maximum number of data items for all sets (can be overridden when adding a set)
*
* @throws IllegalArgumentException If either
* @param args The command line arguments to check
* @param defaultMultiplicity The default multiplicity to use for all options (can be overridden when adding an option)
* @param data The default minimum and maximum number of data items for all sets (can be overridden when adding a set)
*
* @throws IllegalArgumentException If either
* @param args The command line arguments to check
* @param defaultMultiplicity The default multiplicity to use for all options (can be overridden when adding an option)
*
* @throws IllegalArgumentException If either
* @param args The command line arguments to check
*
* @throws IllegalArgumentException If
* @param args The command line arguments to check
* @param data The default minimum and maximum number of data items for all sets (can be overridden when adding a set)
*
* @throws IllegalArgumentException If
* @param args The command line arguments to check
* @param defMinData The default minimum number of data items for all sets (can be overridden when adding a set)
* @param defMaxData The default maximum number of data items for all sets (can be overridden when adding a set)
*
* @throws IllegalArgumentException If
* @param args The command line arguments to check
* @param prefix The prefix to use for all command line options. It can only be set here for all options at
* the same time
*
* @throws IllegalArgumentException If either
* @param args The command line arguments to check
* @param prefix The prefix to use for all command line options. It can only be set here for all options at
* @param data The default minimum and maximum number of data items for all sets (can be overridden when adding a set)
*
* @throws IllegalArgumentException If either
* @param args The command line arguments to check
* @param prefix The prefix to use for all command line options. It can only be set here for all options at
* the same time
* @param defMinData The default minimum number of data items for all sets (can be overridden when adding a set)
* @param defMaxData The default maximum number of data items for all sets (can be overridden when adding a set)
*
* @throws IllegalArgumentException If either
* @return The first set which matches (i. e. the
* @param ignoreUnmatched A boolean to select whether unmatched options can be ignored in the checks or not
* @param requireDataLast A boolean to indicate whether the data items have to be the last ones on the command line or not
*
* @return The first set which matches (i. e. the
* @param setName The name for the set. This must be a unique identifier
* @param minData The minimum number of data items for this set
* @param maxData The maximum number of data items for this set
*
* @return The new
* @param setName The name for the set. This must be a unique identifier
* @param data The minimum and maximum number of data items for this set
*
* @return The new
* @param setName The name for the set. This must be a unique identifier
*
* @return The new
* @param setName The name for the set to retrieve
*
* @return The set to retrieve (or
* @return The default set
*/
public OptionSet getSet() {
if (getSet(DEFAULT_SET) == null)
addSet(DEFAULT_SET, defaultMinData, defaultMaxData);
return getSet(DEFAULT_SET);
}
/**
* The error messages collected during the last option check (invocation of any of the
* @return A string with all collected error messages
*/
public String getCheckErrors() {
return checkErrors.toString();
}
/**
* Run the checks for the default set.
* @return A boolean indicating whether all checks were successful or not
*/
public boolean check() {
return check(DEFAULT_SET, false, true);
}
/**
* Run the checks for the default set.
*
* @param ignoreUnmatched A boolean to select whether unmatched options can be ignored in the checks or not
* @param requireDataLast A boolean to indicate whether the data items have to be the last ones on the command line or not
*
* @return A boolean indicating whether all checks were successful or not
*/
public boolean check(boolean ignoreUnmatched, boolean requireDataLast) {
return check(DEFAULT_SET, ignoreUnmatched, requireDataLast);
}
/**
* Run the checks for the given set.
* @param setName The name for the set to check
*
* @return A boolean indicating whether all checks were successful or not
*
* @throws IllegalArgumentException If either
* @param setName The name for the set to check
* @param ignoreUnmatched A boolean to select whether unmatched options can be ignored in the checks or not
* @param requireDataLast A boolean to indicate whether the data items have to be the last ones on the command line or not
*
* @return A boolean indicating whether all checks were successful or not
*
* @throws IllegalArgumentException If either
* @return A string representing the instance
*/
public String toString() {
StringBuffer sb = new StringBuffer();
for (OptionSet set : optionSets.values()) {
sb.append("Set: ");
sb.append(set.getSetName());
sb.append('\n');
for (OptionData data : set.getOptionData()) {
sb.append(data.toString());
sb.append('\n');
}
}
return sb.toString();
}
}
args
, prefix
, or defaultMultiplicity
* is null
- or if the data range values don't make sense
*/
public Options(String args[], Prefix prefix, Multiplicity defaultMultiplicity, int defMinData, int defMaxData) {
if (args == null) throw new IllegalArgumentException(CLASS + ": args may not be null");
if (prefix == null) throw new IllegalArgumentException(CLASS + ": prefix may not be null");
if (defaultMultiplicity == null) throw new IllegalArgumentException(CLASS + ": defaultMultiplicity may not be null");
if (defMinData < 0) throw new IllegalArgumentException(CLASS + ": defMinData must be >= 0");
if (defMaxData < defMinData) throw new IllegalArgumentException(CLASS + ": defMaxData must be >= defMinData");
arguments = new String[args.length];
int i = 0;
for (String s : args)
arguments[i++] = s;
this.prefix = prefix;
this.defaultMultiplicity = defaultMultiplicity;
this.defaultMinData = defMinData;
this.defaultMaxData = defMaxData;
}
/**
* Constructor
* args
, prefix
, or defaultMultiplicity
* is null
- or if the data range value doesn't make sense
*/
public Options(String args[], Prefix prefix, Multiplicity defaultMultiplicity, int data) {
this(args, prefix, defaultMultiplicity, data, data);
}
/**
* Constructor. The default number of data items is set to 0.
* args
, prefix
, or defaultMultiplicity
* is null
*/
public Options(String args[], Prefix prefix, Multiplicity defaultMultiplicity) {
this(args, prefix, defaultMultiplicity, 0, 0);
}
/**
* Constructor. The prefix is set to {@link Prefix#DASH}.
* args
or defaultMultiplicity
* is null
- or if the data range values don't make sense
*/
public Options(String args[], Multiplicity defaultMultiplicity, int defMinData, int defMaxData) {
this(args, Prefix.DASH, defaultMultiplicity, defMinData, defMaxData);
}
/**
* Constructor. The prefix is set to {@link Prefix#DASH}.
* args
or defaultMultiplicity
* is null
- or if the data range value doesn't make sense
*/
public Options(String args[], Multiplicity defaultMultiplicity, int data) {
this(args, Prefix.DASH, defaultMultiplicity, data, data);
}
/**
* Constructor. The prefix is set to {@link Prefix#DASH}, and the default number of data items is set to 0.
* args
or defaultMultiplicity
* is null
*/
public Options(String args[], Multiplicity defaultMultiplicity) {
this(args, Prefix.DASH, defaultMultiplicity, 0, 0);
}
/**
* Constructor. The prefix is set to {@link Prefix#DASH}, the default number of data items is set to 0, and
* the multiplicity is set to {@link Multiplicity#ONCE}.
* args
is null
*/
public Options(String args[]) {
this(args, Prefix.DASH, Multiplicity.ONCE);
}
/**
* Constructor. The prefix is set to {@link Prefix#DASH}, and
* the multiplicity is set to {@link Multiplicity#ONCE}.
* args
is null
- or if the data range value doesn't make sense
*/
public Options(String args[], int data) {
this(args, Prefix.DASH, Multiplicity.ONCE, data, data);
}
/**
* Constructor. The prefix is set to {@link Prefix#DASH}, and
* the multiplicity is set to {@link Multiplicity#ONCE}.
* args
is null
- or if the data range values don't make sense
*/
public Options(String args[], int defMinData, int defMaxData) {
this(args, Prefix.DASH, Multiplicity.ONCE, defMinData, defMaxData);
}
/**
* Constructor. The default number of data items is set to 0, and
* the multiplicity is set to {@link Multiplicity#ONCE}.
* args
or prefix
is null
*/
public Options(String args[], Prefix prefix) {
this(args, prefix, Multiplicity.ONCE, 0, 0);
}
/**
* Constructor. The multiplicity is set to {@link Multiplicity#ONCE}.
* args
or prefix
is null
* - or if the data range value doesn't make sense
*/
public Options(String args[], Prefix prefix, int data) {
this(args, prefix, Multiplicity.ONCE, data, data);
}
/**
* Constructor. The multiplicity is set to {@link Multiplicity#ONCE}.
* args
or prefix
is null
* - or if the data range values don't make sense
*/
public Options(String args[], Prefix prefix, int defMinData, int defMaxData) {
this(args, prefix, Multiplicity.ONCE, defMinData, defMaxData);
}
/**
* Return the (first) matching set. This invocation does not ignore unmatched options and requires that
* data items are the last ones on the command line.
* check()
method returns true
) - or
* null
, if no set matches.
*/
public OptionSet getMatchingSet() {
return getMatchingSet(false, true);
}
/**
* Return the (first) matching set.
* check()
method returns true
) - or
* null
, if no set matches.
*/
public OptionSet getMatchingSet(boolean ignoreUnmatched, boolean requireDataLast) {
for (String setName : optionSets.keySet())
if (check(setName, ignoreUnmatched, requireDataLast))
return optionSets.get(setName);
return null;
}
/**
* Add an option set.
* Optionset
instance created. This is useful to allow chaining of addOption()
* calls right after this method
*/
public OptionSet addSet(String setName, int minData, int maxData) {
if (setName == null) throw new IllegalArgumentException(CLASS + ": setName may not be null");
if (optionSets.containsKey(setName)) throw new IllegalArgumentException(CLASS + ": a set with the name "
+ setName + " has already been defined");
OptionSet os = new OptionSet(prefix, defaultMultiplicity, setName, minData, maxData);
optionSets.put(setName, os);
return os;
}
/**
* Add an option set.
* Optionset
instance created. This is useful to allow chaining of addOption()
* calls right after this method
*/
public OptionSet addSet(String setName, int data) {
return addSet(setName, data, data);
}
/**
* Add an option set. The defaults for the number of data items are used.
* Optionset
instance created. This is useful to allow chaining of addOption()
* calls right after this method
*/
public OptionSet addSet(String setName) {
return addSet(setName, defaultMinData, defaultMaxData);
}
/**
* Return an option set - or null
, if no set with the given name exists
* null
, if no set with the given name exists)
*/
public OptionSet getSet(String setName) {
return optionSets.get(setName);
}
/**
* This returns the (anonymous) default set
* check()
methods). This
* is useful to determine what was wrong with the command line arguments provided
* ignoreUnmatched
is set to false
, and
* requireDataLast
is set to true
.
* ignoreUnmatched
is set to false
, and
* requireDataLast
is set to true
.
* setName
is null
, or the set is unknown.
*/
public boolean check(String setName) {
return check(setName, false, true);
}
/**
* Run the checks for the given set.
* setName
is null
, or the set is unknown.
*/
public boolean check(String setName, boolean ignoreUnmatched, boolean requireDataLast) {
if (setName == null) throw new IllegalArgumentException(CLASS + ": setName may not be null");
if (optionSets.get(setName) == null) throw new IllegalArgumentException(CLASS + ": Unknown OptionSet: " + setName);
checkErrors = new StringBuffer();
checkErrors.append("Checking set ");
checkErrors.append(setName);
checkErrors.append('\n');
//.... Access the data for the set to use
OptionSet set = optionSets.get(setName);
java.util.ArrayList