com.internationalnetwork.util.conf
Class Rule

Object
  extended by com.internationalnetwork.util.conf.Rule

public class Rule
extends Object

This class is used by the ConfigurationResource class to keep track of rules that define directives and containers.

The actual syntax checks are performed by this class.  Where a Regular Expression defines the format, its pre-compiled pattern is also stored here to ensure better overall performance during configuration stream processing.

Example code

    // --------------------------------------------------------------------------
    // A simple example of a rule for a Directive called "Password" that accepts
    // any string of text with no restrictions aside from a maximum length (the
    // user may also specify up to 3 passwords; if the user specifies more than
    // 3, then an exception will be thrown when this error is encountered while
    // the ConfiguationResource.processStream() method is processing it).
    //
    // The configuration file could contain any of the following (note that the
    // phrase enclosed within quotation marks will be interpreted as a single
    // argument during processing by the ConfigurationResource.processStream()
    // method):
    //
    //    Password      secret
    //    Password      "first secret" second-password third
    //
    // Requires:  import com.internationalnetwork.util.conf.Rule;
    // --------------------------------------------------------------------------
    Rule rulePassword = new Rule( "Password", "elements=1..3", "text", "length=128" );

    // --------------------------------------------------------------------------
    // The next rule is a very complicated one that includes a variety of
    // different format types, multiple ranges, and whatnot.  The formatting of
    // the source code is intended to make it easier to understand.
    //
    // Although the order in which the types occurs is significant, the order of
    // the options (which are indented for your convenience) usually doesn't
    // matter (it certainly is significant for the "require" and "copy" options).
    //
    // The last type is optional, and up to 3 arguments can be provided by the
    // user.  This is implied through the "elements" option because it is the
    // 10th option, and the minimum requirement is 9.  The maximum of 12 assumes
    // that the last argument will repeat to fill in the extras, so the "copy"
    // option isn't needed for the final type.
    // --------------------------------------------------------------------------
    Rule ruleComplex = new Rule(

      "Complex",                 // Name of directive
        "scope=_root",           // Can only be set globally (not in a container)
        "elements=9..12",        // Require a minimum of 9 (maximum 12) arguments

      "path",                    // Type:  File system path
        "require=absolute",      // Path must be absolute
        "require=exist",         // Path must exist
        "alias=root=/",          // Allow user to specify the word "root" for "/"

      "flag",                    // Type:  Boolean
        "default=On",            // Set the default value to "true"

      "text",                    // Type:  Free-form text
        "regex=\\d{6}-\\d{3}",   // Allow format:  6 digits, a dash, and 3 digits
        "equal=Standard",        // Allow keyword "Standard"
        "equal=Traditional",     // Allow keyword "Traditional"
        "equal=International",   // Allow keyword "International"
        "error=Some text...",    // Define custom error message for this argument

      "number",                  // Type:  Number
        "range=100..200",        // Specify a range limit of 100 through 200
        "range=500..600",        // Specify a range limit of 500 through 600
        "range=750..1000",       // Specify a range limit of 750 through 1000
        "equal=0",               // Allow the number 0 (could also use "range=0")
        "error=Some text...",    // Define custom error message for this argument
        "copy=2",                // In total, 3 of these numbers will be required

      "ip",                      // Type:  IP address

      "hostname",                // Type:  Hostname
        "range=2..",             // Require a minimum of 1 delimiter (".")

      "email",                   // Type:  eMail address

      "text"                     // Type:  Free-form text

    );

Directive rules

The first element in the array is the name of the Directive (or Container, which must be enclosed within "<" and ">" characters).  The second element is the rule format (or rule type).  The remaining elements in the array are variable numbers of rule options, which are specified in the form of "option=parameters" (in any order).  When another format is encountered, it applies to the next argument provided with the directive (the last format defined applies to all remaining agruments that were provided with the directive).

Directive names are case-insensitive, although case is preserved for the purpose of ensuring that syntax errors are more user-friendly.  The values supplied in the configuration stream (after the rules have been defined) with each directive will be treated as case-sensitive by default.

Rule formats (or types)

Formats (or types) always stand alone without an equal sign.  This is one way you can differentiate, just by examining a rule, between a format and an option (option names are always followed by an equal sign).

cidr
IP address with bit mask in standard CIDR notation (e.g., 10/8).  Both IPv4 and IPv6 blocks are supported, and future address types should also be accepted when Java supports them due to the way this feature is programmed.

domain-literal
Domain Literal address.  Both IPv4 and IPv6 domain literals are supported, and future address types should also be accepted when Java supports them due to the way this feature is programmed.

email
RFC-compliant eMail address.

The optional "regex" option defines a Regular Expression pattern that will be used to enforce a specific format.

filename
Filename, with or without a path.

The optional "require" option ensures that the file exists, or creates it on-the-fly, depending on its parameter.

flag
A boolean type.  Possible values are:

True:  1, On, Yes, True, or Enabled
False:  0, Off, No, False, or Disabled

hostname
RFC-compliant hostname.

The optional "range" option limits the number of atoms that the hostname must have in the form of "min...max" where "min" and "max" specify the minimum (which cannot be lower than 1) and maximum (which should not be greater than 64 as per internet standards guidelines, although higher numbers are supported) possible atoms, respectively.

If you need a internet name without any periods, but which may begin with a digit (the official standard forbids internet names from beginning with digits), then a "hostname" rule with the option "range=1" will do this.

ip
IP address.  Both IPv4 and IPv6 addresses are supported, and future address types should also be accepted when Java supports them due to the way this feature is programmed.

number
Numeric value.

The optional "range" option defines the valid range in the form of "min...max" where "min" and "max" specify the minimum and maximum possible values, respectively.  The keywords "long," "int," "short," "byte," and "nybble" (the "range" option provides a full list of keywords and their corresponding value) may be used in place of these values to specify the minimum or maximum respectively, thus a range of "0..short" is the same as "0..32767" (you may also omit a number on either side to retain its infinite default).

The optional "regex" option defines a Regular Expression pattern that will be used to allow additional valid numbers by format.

path
An absolute or relative path, absent a filename.

The optional "require" option ensures that the path exists, the path is absolute or relative, and various other attributes.

text
Any free-formed text.

The optional "length" option defines the maximum number of characters permitted.

The optional "regex" option defines a Regular Expression pattern that will be used to enforce a specific format.

uri
RFC-compliant Universal Resource Identifier, such as a web or FTP site address.

Rule options

Options may only be specified for rules which explicitly indicate that such an option is supported, unless otherwise noted.  Attempts to use an option with a rule that doesn't support it will result in an exception being thrown.

Some of these rule options are implemented from within the ConfigurationResource class, but are documented here to serve as a complete reference.

alias=key=val
Defines an alias that takes effect before syntax checks.  This is useful for supporting alternative spellings for specific keywords, or defining numeric values for keywords like "default" or whatever else is needed.

The keyword to be replaced is defined by key and its replacement value is defined by val, thus an alias defined with "alias=Default=42" for a directive with a numeric format will convert "Directive Default" from the configuraiton stream to "Directive 42" before commencing with syntax checks.

Aliases are case-sensitive, and are processed before all syntax checks.

This option is supported by all rules.

copy=num
Creates num duplicates of the current rule, in its present state.  Any additional options following this option will only be applied to the last duplicate (additional copy options will yield the same behaviour again, ad infinitum).

This option is supported by all rules.

default=text
The value to use in place of a NULL object when this value isn't set by a directive within the configuration stream, or when the "default" keyword is present where a number is expected.

Every container will automatically set this default value when it is closed, unless a value was previously set by the respective directive in the configuration stream within the current container (or one of its parent containers).  The default value may not contain a substitution or alias (support for this may be added in a future version of this class).

Only Directive objects may have default values set.  This is not a valid option for Container types.

This option is supported by all rules.

elements=min..max|num
Defines the minimum and/or maximum, or specific, total number of arguments that will be permitted (not including the name of the Directive or Container).  The entire ruleset is re-evaluated for each argument encountered, after the total number is checked for compliance.

This option must be specified before the first format is defined.

This option may be specified more than once to support multiple ranges/numbers of elements.

To simulate infinity, omit a number from either side of the two periods.  For example, a range of "0.." allows for any optional number of arguments (this is the default).

If a number is specified without a range delimiter, then it is interpreted as a specific number of arguments instead.

The following reserved words may also be used in place of either the min or max values, and will be replaced with the following values, although only "none" and "nybble" are anticipated to be the only useful ones:

This option is supported by all rules.

equal=text
Defines a specific keyword or phrase that is allowed.  Use multiple definitions to specify multiple keywords.

Keywords (and phrases) are case-sensitive.  If you need case-insensitivity, use Regular Expressions instead (see the "regex" option below for its documentation).

This option is tested in the syntax checks before other tests such as regex, and format tests, so that you can override the required format type with an arbitrary keyword (e.g., you can allow certain arbitrary keyword exceptions where an IP address {which has a strict format} would normally be required).

This option is supported by all rules.

error=text
The error message text to send to STDERR in the event of a syntax error.

This option is supported by all rules.

length=max
Defines the maximum length of the data (e.g., free-form text) for the current format.

This test is performed after aliases have been converted, and all short-circuit "equal" operations have been dealt with.

This option is supported by all rules.

range=min..max
Defines a numeric range of whole or decimal numbers.

This option may be specified more than once to support multiple numeric ranges that are not contiguous.

To simulate infinity, omit a number from either side of the two periods.  For example, a range of "0.." allows non-negative whole numbers only.

Also, if the first range includes a decimal point in either the "min" or "max" values, then all ranges (with or without decimal points) will be treated as decimal numbers instead of whole numbers.  Switching to decimal numbers after the first range specifies only whole numbers is not supported.

The following reserved words may also be used in place of either the min or max values, and will be replaced as follows (see the documentation for the com.internationalnetwork.math.ConvertNumber class for additional information):

These same substitutes may also be used with the "alias" and "default" options.

regex=pattern
Regular Expression pattern used to enforce a specific format, which uses industry standard Perl-style Regular Expressions as provided with the standard Java libraries (see the java.util.regex.Pattern class for full documentation on Regular Expression syntax).

To ensure efficiency, all Regular Expression patterns are compiled before-hand so that multiple pattern match attempts will utilize less processing power.  This also provides another advantage where a malformed Regular Expression pattern will be detected before any configuration file processing can occur (in other words, correctly formatted Regular Expression patterns are a requirement).

A few simple examples (you can make your Regular Expression as complex as is supported by the java.util.regex.Pattern class):

Note that MULTILINE mode is not useful because multiple lines from the configuration stream are always combined into a single line prior to processing.  Thus, each Regular Expression attempts to match the entire string by default.

This option may be specified more than once to support multiple patterns, which may be a lot easier than trying to construct a single Regular Expression to handle all needed possibilities.

require=requirement
For use with "path" and "filename" rules.  If the specified path or filename doesn't meet one of the following requirements, an error will be generated:

Note that when any requirement is specified, an additional test is performed to ensure that paths and filenames are of the respective types they are expected to be (that is, if a path exists where a file is expected, or visa-versa, then the test will fail).

This option may be specified more than once to support multiple requirements.

scope=list
Specifies which containers this Directive (or Container) is permitted to have as its parent.

The "list" parameter is a space-delimited list of containers.  The root container is identified by "_root" (reserved internal name).  An exclaimation point ("!") preceeding a container name specifically disallows it, and causes everything else not matching this to fail.  Switch back, finally, to a container name without the leading exclaimation point will implicitly cause all remaining container names to be valid.

This option must be specified before the first format is defined.

This option may be specified more than once to expand the scope.

This option is supported by all rules.


Field Summary
static String VERSION
          Version number of this Package (read-only).
 
Constructor Summary
Rule(String... args)
          Creates a new Rule that will be used for basic syntax checking when reading the configuration stream.  Rules are parsed at this point.
 
Method Summary
 Rule clone()
          Creates a duplicate of the current Rule object.
 int compareToElementRange(int value)
          Indicates if the given int[eger] is in Element Range.
 int compareToEqual(String value)
          Indicates if the given String matches one of the "equal" strings.
 int compareToRange(String value)
          Indicates if the given String is in Range.  If range limits are not defined, the format of the string is still checked to ensure that it is a valid number.
 int compareToRegEx(String value)
          Indicates if the given String matches one of the pre-compiled Regular Expression patterns.
 int compareToRequire(boolean isFile, String value)
          Indicates if the path or filename in the given String matches all of the test requirements.
 int compareToScope(String value)
          Indicates if the given String, which is the name of the directive's parent container, is valid for this rule's scope.
 String convertAlias(String key)
          Attempts to convert the alias.  If an alias can't be found, the no conversion takes place and the original key String is returned.
 HashMap<String,String> getAliases()
          Returns this Rule's aliases.
 String getDefault()
          Returns this Rule's default value.
 int[][] getElementRanges()
          Returns this Rule's element quantity ranges as an array of integers.  Each element in the array contains a two-element array that hold the "min" and "max" integer.
 String[] getEqualStrings()
          Returns this Rule's "equal" strings.
 String getError()
          Returns this Rule's error text.
 String getFormat()
          Returns the Format/Type for this Rule.
 int getLength()
          Returns this Rule's length limit.  A value of -1 indicates that it is either not set (so there is no limit), or it can't be set for this Rule (e.g., because it's not applicable).
 String getName()
          Returns the name of the Directive (or Container without enclosing "<" and ">" characters) that this Rule applies to.
 String getNameLiteral()
          Returns the name of the Directive (or Container with enclosing "<" and ">" characters) that this Rule applies to.
 String[] getOptions()
          Returns the array of Options for this Rule.
 Number[][] getRanges()
          Returns this Rule's ranges as an array of Numbers.  Each element in the array contains a two-element array that hold the "min" and "max" numbers.
 java.util.regex.Pattern[] getRegExPatterns()
          Returns this Rule's pre-compiled Regular Expression patterns.
 String[] getRequire()
          Returns this Rule's "require" options.
 String[] getScope()
          Returns this Rule's "scope" options.
 boolean hasAliases()
          Indicates if this Rule contains any aliases.
 boolean hasDefault()
          Indicates if this Rule contains a default value.
 boolean hasElementRanges()
          Indicates if this Rule has at least one "element" range defined.
 boolean hasError()
          Indicates if this Rule has any error message text defined.
 boolean hasRanges()
          Indicates if this Rule has at least one range defined.
 boolean hasValidSyntax(ConfigurationDirective directive)
          Tests the syntax of a ConfigurationDirective's object using this particular Rule.  This method is mostly used by the ConfigurationResource class to optionally (when "wildcard" mode is enabled) validate the syntax ConfigurationDirective objects before adding them to the configuration hierarchy.
 boolean isContainer()
          Indicates if this Rule is for a Container.
 boolean isDirective()
          Indicates if this Rule is for a Directive or anything else that will not be classified as a Container (this convenience method returns the opposite of isContainer(), and so it should be thought of as if its name was "isNotContainer()").
 boolean isRangeDecimal()
          Indicates if this Rule's ranges are comprised of whole numbers (the default), or decimal numbers.
 
Methods inherited from class Object
equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

VERSION

public static final String VERSION
Version number of this Package (read-only).

See Also:
Constant Field Values
Constructor Detail

Rule

public Rule(String... args)
Creates a new Rule that will be used for basic syntax checking when reading the configuration stream.  Rules are parsed at this point.

Parameters:
args - Directive/Container name, plus format/type, plus additional options (see the ConfigurationResource documentation for a complete list of rules, formats/types, and options), either as a set of separate strings, or an array of strings
Throws:
IllegalArgumentException - if there was a minor problem with one of the arguments such as being out of range or incomplete
UnsupportedOperationException - if there was a serious problem with one of the arguments such as re-defining a previously defined final value or being an unrecognized format/type or option
Method Detail

clone

public Rule clone()
Creates a duplicate of the current Rule object.

This is primarily used by the ConfigurationResource.clone() method.

Overrides:
clone in class Object
Returns:
Rule cloned

compareToElementRange

public int compareToElementRange(int value)
Indicates if the given int[eger] is in Element Range.

This method is also used internally by the hasValidSyntax method.

Parameters:
value - The int[eger] value to test
Returns:
int -1 = out of range, 0 = no range to compare, 1 = in range

compareToEqual

public int compareToEqual(String value)
Indicates if the given String matches one of the "equal" strings.

This method is also used internally by the hasValidSyntax method.

Parameters:
value - The String value to test
Returns:
int -1 = no matches, 0 = no "equal" strings to compare, 1 = match

compareToRange

public int compareToRange(String value)
Indicates if the given String is in Range.  If range limits are not defined, the format of the string is still checked to ensure that it is a valid number.

If the value provided fails to convert to a number (e.g., because it contains non-numeric characters), then it will be assumed "out of range" and a value of -1 will be returned.

This method is also used internally by the hasValidSyntax method.

Parameters:
value - The String value to test
Returns:
int -1 = out of range, 0 = no range to compare, 1 = in range

compareToRegEx

public int compareToRegEx(String value)
Indicates if the given String matches one of the pre-compiled Regular Expression patterns.

This method is also used internally by the hasValidSyntax method.

Parameters:
value - The String value to test
Returns:
int -1 = no matches, 0 = no RegEx patterns to compare, 1 = match

compareToRequire

public int compareToRequire(boolean isFile,
                            String value)
Indicates if the path or filename in the given String matches all of the test requirements.

This method is also used internally by the hasValidSyntax method.

Parameters:
isFile - True = Filename included, False = Path only
value - The String value to test
Returns:
int -1 = any test failed, 0 = no requirements, 1 = all tests passed

compareToScope

public int compareToScope(String value)
Indicates if the given String, which is the name of the directive's parent container, is valid for this rule's scope.

This method is also used internally by the hasValidSyntax method.

Parameters:
value - The String value to test
Returns:
int -1 = not valid, 0 = no Scope definitions to compare, 1 = is valid

convertAlias

public String convertAlias(String key)
Attempts to convert the alias.  If an alias can't be found, the no conversion takes place and the original key String is returned.

This method is also used internally by the hasValidSyntax method.

Parameters:
key - The String value to attempt to convert
Returns:
String The converted (or unconverted) String

getAliases

public HashMap<String,String> getAliases()
Returns this Rule's aliases.

Returns:
HashMap Aliases

getDefault

public String getDefault()
Returns this Rule's default value.

Returns:
String Default value (or NULL if not defined)

getElementRanges

public int[][] getElementRanges()
Returns this Rule's element quantity ranges as an array of integers.  Each element in the array contains a two-element array that hold the "min" and "max" integer.

Returns:
int[][] Array of 2-element int[] arrays

getEqualStrings

public String[] getEqualStrings()
Returns this Rule's "equal" strings.

Returns:
String[] Array of "equal" strings

getError

public String getError()
Returns this Rule's error text.

Returns:
String Error text (or "" if not defined, for easy inclusion in error text when throwing an exception)

getFormat

public String getFormat()
Returns the Format/Type for this Rule.

Returns:
String Format/Type

getLength

public int getLength()
Returns this Rule's length limit.  A value of -1 indicates that it is either not set (so there is no limit), or it can't be set for this Rule (e.g., because it's not applicable).

Returns:
int Maximum length (-1 = unlimited or N/A)

getName

public String getName()
Returns the name of the Directive (or Container without enclosing "<" and ">" characters) that this Rule applies to.

Returns:
String Directive (or Container) name

getNameLiteral

public String getNameLiteral()
Returns the name of the Directive (or Container with enclosing "<" and ">" characters) that this Rule applies to.

Returns:
String "Directive" (or "") name

getOptions

public String[] getOptions()
Returns the array of Options for this Rule.

Returns:
String[] Options

getRanges

public Number[][] getRanges()
Returns this Rule's ranges as an array of Numbers.  Each element in the array contains a two-element array that hold the "min" and "max" numbers.

Returns:
Number[][] Array of 2-element BigInteger[] or BigDecimal[] arrays

getRegExPatterns

public java.util.regex.Pattern[] getRegExPatterns()
Returns this Rule's pre-compiled Regular Expression patterns.

Returns:
Pattern[] Array of pre-compiled RegEx patterns

getRequire

public String[] getRequire()
Returns this Rule's "require" options.

Returns:
String[] Array of "require" options

getScope

public String[] getScope()
Returns this Rule's "scope" options.

Returns:
String[] Array of "scope" options

hasAliases

public boolean hasAliases()
Indicates if this Rule contains any aliases.

Returns:
boolean True = aliases defined, False = no aliases

hasDefault

public boolean hasDefault()
Indicates if this Rule contains a default value.

Returns:
boolean True = default value defined, False = no default value

hasElementRanges

public boolean hasElementRanges()
Indicates if this Rule has at least one "element" range defined.

Returns:
boolean True = element range defined, Flase = not defined

hasError

public boolean hasError()
Indicates if this Rule has any error message text defined.

Returns:
boolean True = error text defined, False = no error text defined

hasRanges

public boolean hasRanges()
Indicates if this Rule has at least one range defined.

Returns:
boolean True = range(s) defined, Flase = range(s) not defined

hasValidSyntax

public boolean hasValidSyntax(ConfigurationDirective directive)
Tests the syntax of a ConfigurationDirective's object using this particular Rule.  This method is mostly used by the ConfigurationResource class to optionally (when "wildcard" mode is enabled) validate the syntax ConfigurationDirective objects before adding them to the configuration hierarchy.

Parameters:
directive - The ConfigurationDirective object to test (a NULL value will always result in a syntax failure)
Returns:
boolean True = syntax check passed, False = syntax check failed

isContainer

public boolean isContainer()
Indicates if this Rule is for a Container.

Returns:
boolean True = Container, False = Directive

isDirective

public final boolean isDirective()
Indicates if this Rule is for a Directive or anything else that will not be classified as a Container (this convenience method returns the opposite of isContainer(), and so it should be thought of as if its name was "isNotContainer()").

Returns:
boolean True = Not a container, False = Container

isRangeDecimal

public boolean isRangeDecimal()
Indicates if this Rule's ranges are comprised of whole numbers (the default), or decimal numbers.

Returns:
boolean True = decimal numbers, False = whole numbers