277 lines
11 KiB
Java
277 lines
11 KiB
Java
|
package com.minres.scviewer.e4.application.options;
|
||
|
|
||
|
/**
|
||
|
* This class holds the information for a <i>set</i> of options. A set can hold any number of
|
||
|
* <code>OptionData</code> instances which are checked together to determine success or failure.
|
||
|
* <p>
|
||
|
* The approach to use this class looks like this:
|
||
|
* <p>
|
||
|
* <ol>
|
||
|
* <li> The user uses any of the <code>Options.addSet()</code> (e. g. {@link Options#addSet(String)}) to create
|
||
|
* any number of sets required (or just relies on the default set, if only one set is required)
|
||
|
* <li> The user adds all required option definitions to each set
|
||
|
* <li> Using any of the <code>Options.check()</code> methods, each set can be checked whether the options
|
||
|
* that were specified on the command line satisfy its requirements
|
||
|
* <li> If the check was successful for a given set, several data items are available from this class:
|
||
|
* <ul>
|
||
|
* <li> All options defined for the set (through with e. g. values, details, and multiplicity are available)
|
||
|
* <li> All data items found (these are the items on the command line which do not start with the prefix,
|
||
|
* i. e. non-option arguments)
|
||
|
* <li> All unmatched arguments on the command line (these are the items on the command line which start
|
||
|
* with the prefix, but do not match to one of the options).
|
||
|
* Programs can elect to ignore these, or react with an error
|
||
|
* </ul>
|
||
|
* </ol>
|
||
|
*/
|
||
|
|
||
|
public class OptionSet {
|
||
|
|
||
|
private final static String CLASS = "OptionSet";
|
||
|
|
||
|
private java.util.ArrayList<OptionData> options = new java.util.ArrayList<OptionData>();
|
||
|
private java.util.HashMap<String, OptionData> keys = new java.util.HashMap<String, OptionData>();
|
||
|
private java.util.ArrayList<String> unmatched = new java.util.ArrayList<String>();
|
||
|
private java.util.ArrayList<String> data = new java.util.ArrayList<String>();
|
||
|
private String setName = null;
|
||
|
private int minData = 0;
|
||
|
private int maxData = 0;
|
||
|
private Options.Prefix prefix = null;
|
||
|
private Options.Multiplicity defaultMultiplicity = null;
|
||
|
|
||
|
/**
|
||
|
* Constructor
|
||
|
*/
|
||
|
|
||
|
OptionSet(Options.Prefix prefix, Options.Multiplicity defaultMultiplicity, String setName, int minData, int maxData) {
|
||
|
if (setName == null) throw new IllegalArgumentException(CLASS + ": setName may not be null");
|
||
|
if (minData < 0) throw new IllegalArgumentException(CLASS + ": minData must be >= 0");
|
||
|
if (maxData < minData) throw new IllegalArgumentException(CLASS + ": maxData must be >= minData");
|
||
|
this.prefix = prefix;
|
||
|
this.defaultMultiplicity = defaultMultiplicity;
|
||
|
this.setName = setName;
|
||
|
this.minData = minData;
|
||
|
this.maxData = maxData;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get a list of all the options defined for this set
|
||
|
* <p>
|
||
|
* @return A list of {@link OptionData} instances defined for this set
|
||
|
*/
|
||
|
|
||
|
public java.util.ArrayList<OptionData> getOptionData() {
|
||
|
return options;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the data for a specific option, identified by its key name (which is unique)
|
||
|
* <p>
|
||
|
* @param key The key for the option
|
||
|
* <p>
|
||
|
* @return The {@link OptionData} instance
|
||
|
* <p>
|
||
|
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or unknown in this set
|
||
|
*/
|
||
|
|
||
|
public OptionData getOption(String key) {
|
||
|
if (key == null) throw new IllegalArgumentException(CLASS + ": key may not be null");
|
||
|
if (!keys.containsKey(key)) throw new IllegalArgumentException(CLASS + ": unknown key: " + key);
|
||
|
return keys.get(key);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check whether a specific option is set, i. e. whether it was specified at least once on the command line.
|
||
|
* <p>
|
||
|
* @param key The key for the option
|
||
|
* <p>
|
||
|
* @return <code>true</code> or <code>false</code>, depending on the outcome of the check
|
||
|
* <p>
|
||
|
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or unknown in this set
|
||
|
*/
|
||
|
|
||
|
public boolean isSet(String key) {
|
||
|
if (key == null) throw new IllegalArgumentException(CLASS + ": key may not be null");
|
||
|
if (!keys.containsKey(key)) throw new IllegalArgumentException(CLASS + ": unknown key: " + key);
|
||
|
return keys.get(key).getResultCount() > 0 ? true : false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Getter method for <code>setName</code> property
|
||
|
* <p>
|
||
|
* @return The value for the <code>setName</code> property
|
||
|
*/
|
||
|
|
||
|
public String getSetName() {
|
||
|
return setName;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Getter method for <code>minData</code> property
|
||
|
* <p>
|
||
|
* @return The value for the <code>minData</code> property
|
||
|
*/
|
||
|
|
||
|
public int getMinData() {
|
||
|
return minData;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Getter method for <code>maxData</code> property
|
||
|
* <p>
|
||
|
* @return The value for the <code>maxData</code> property
|
||
|
*/
|
||
|
|
||
|
public int getMaxData() {
|
||
|
return maxData;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return the data items found (these are the items on the command line which do not start with the prefix, i. e. non-option arguments)
|
||
|
* <p>
|
||
|
* @return A list of strings with all data items found
|
||
|
*/
|
||
|
|
||
|
public java.util.ArrayList<String> getData() {
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return all unmatched items found (these are the items on the command line which start with the prefix, but do not
|
||
|
* match to one of the options)
|
||
|
* <p>
|
||
|
* @return A list of strings with all unmatched items found
|
||
|
*/
|
||
|
|
||
|
public java.util.ArrayList<String> getUnmatched() {
|
||
|
return unmatched;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add a non-value option with the given key, and the default prefix and multiplicity
|
||
|
* <p>
|
||
|
* @param key The key for the option
|
||
|
* <p>
|
||
|
* @return The set instance itself (to support invocation chaining for <code>addOption()</code> methods)
|
||
|
* <p>
|
||
|
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or a key with this name has already been defined
|
||
|
*/
|
||
|
|
||
|
public OptionSet addOption(String key) {
|
||
|
return addOption(key, defaultMultiplicity);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add a non-value option with the given key and multiplicity, and the default prefix
|
||
|
* <p>
|
||
|
* @param key The key for the option
|
||
|
* @param multiplicity The multiplicity for the option
|
||
|
* <p>
|
||
|
* @return The set instance itself (to support invocation chaining for <code>addOption()</code> methods)
|
||
|
* <p>
|
||
|
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or a key with this name has already been defined
|
||
|
* or if <code>multiplicity</code> is <code>null</code>
|
||
|
*/
|
||
|
|
||
|
public OptionSet addOption(String key, Options.Multiplicity multiplicity) {
|
||
|
return addOption(key, false, Options.Separator.NONE, false, multiplicity);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add a value option with the given key and separator, no details, and the default prefix and multiplicity
|
||
|
* <p>
|
||
|
* @param key The key for the option
|
||
|
* @param separator The separator for the option
|
||
|
* <p>
|
||
|
* @return The set instance itself (to support invocation chaining for <code>addOption()</code> methods)
|
||
|
* <p>
|
||
|
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or a key with this name has already been defined
|
||
|
* or if <code>separator</code> is <code>null</code>
|
||
|
*/
|
||
|
|
||
|
public OptionSet addOption(String key, Options.Separator separator) {
|
||
|
return addOption(key, false, separator, true, defaultMultiplicity);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add a value option with the given key, separator, and multiplicity, no details, and the default prefix
|
||
|
* <p>
|
||
|
* @param key The key for the option
|
||
|
* @param separator The separator for the option
|
||
|
* @param multiplicity The multiplicity for the option
|
||
|
* <p>
|
||
|
* @return The set instance itself (to support invocation chaining for <code>addOption()</code> methods)
|
||
|
* <p>
|
||
|
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or a key with this name has already been defined
|
||
|
* or if <code>separator</code> or <code>multiplicity</code> are <code>null</code>
|
||
|
*/
|
||
|
|
||
|
public OptionSet addOption(String key, Options.Separator separator, Options.Multiplicity multiplicity) {
|
||
|
return addOption(key, false, separator, true, multiplicity);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
* Add a value option with the given key and separator, possibly details, and the default prefix and multiplicity
|
||
|
* <p>
|
||
|
* @param key The key for the option
|
||
|
* @param details A boolean indicating whether details are expected for the option
|
||
|
* @param separator The separator for the option
|
||
|
* <p>
|
||
|
* @return The set instance itself (to support invocation chaining for <code>addOption()</code> methods)
|
||
|
* <p>
|
||
|
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or a key with this name has already been defined
|
||
|
* or if <code>separator</code> is <code>null</code>
|
||
|
*/
|
||
|
|
||
|
public OptionSet addOption(String key, boolean details, Options.Separator separator) {
|
||
|
return addOption(key, details, separator, true, defaultMultiplicity);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add a value option with the given key, separator, and multiplicity, possibly details, and the default prefix
|
||
|
* <p>
|
||
|
* @param key The key for the option
|
||
|
* @param details A boolean indicating whether details are expected for the option
|
||
|
* @param separator The separator for the option
|
||
|
* @param multiplicity The multiplicity for the option
|
||
|
* <p>
|
||
|
* @return The set instance itself (to support invocation chaining for <code>addOption()</code> methods)
|
||
|
* <p>
|
||
|
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or a key with this name has already been defined
|
||
|
* or if <code>separator</code> or <code>multiplicity</code> are <code>null</code>
|
||
|
*/
|
||
|
|
||
|
public OptionSet addOption(String key, boolean details, Options.Separator separator, Options.Multiplicity multiplicity) {
|
||
|
return addOption(key, details, separator, true, multiplicity);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* The master method to add an option. Since there are combinations which are not
|
||
|
* acceptable (like a NONE separator and a true value), this method is not public.
|
||
|
* Internally, we only supply acceptable combinations.
|
||
|
*/
|
||
|
|
||
|
OptionSet addOption(String key,
|
||
|
boolean details,
|
||
|
Options.Separator separator,
|
||
|
boolean value,
|
||
|
Options.Multiplicity multiplicity) {
|
||
|
|
||
|
if (key == null) throw new IllegalArgumentException(CLASS + ": key may not be null");
|
||
|
if (multiplicity == null) throw new IllegalArgumentException(CLASS + ": multiplicity may not be null");
|
||
|
if (separator == null) throw new IllegalArgumentException(CLASS + ": separator may not be null");
|
||
|
if (keys.containsKey(key)) throw new IllegalArgumentException(CLASS + ": the key "
|
||
|
+ key + " has already been defined for this OptionSet");
|
||
|
|
||
|
OptionData od = new OptionData(prefix, key, details, separator, value, multiplicity);
|
||
|
options.add(od);
|
||
|
keys.put(key, od);
|
||
|
|
||
|
return this;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|