Class ExtendedBaseRules
- All Implemented Interfaces:
Rules
Extension of RulesBase
for complex schema.
This is an extension of the basic pattern matching scheme intended to improve support for mapping complex xml-schema. It is intended to be a minimal extension of the standard rules big enough to support complex schema but without the full generality offered by more exotic matching pattern rules.
When should you use this rather than the original?
This pattern-matching engine is complex and slower than the basic default RulesBase class, but offers more functionality:
- Universal patterns allow patterns to be specified which will match regardless of whether there are "better matching" patterns available.
- Parent-match patterns (eg "a/b/?") allow matching for all direct children of a specified element.
- Ancestor-match patterns (eg "a/b/*") allow matching all elements nested within a specified element to any nesting depth.
- Completely-wild patterns ("*" or "!*") allow matching all elements.
Universal Match Patterns
The default RulesBase pattern-matching engine always attempts to find the "best matching pattern", and will ignore rules associated with other patterns that match but are not "as good". As an example, if the pattern "a/b/c" is associated with rules 1 and 2, and "*/c" is associated with rules 3 and 4 then element "a/b/c" will cause only rules 1 and 2 to execute. Rules 3 and 4 do have matching patterns, but because the patterns are shorter and include wildcard characters they are regarded as being "not as good" as a direct match. In general, exact patterns are better than wildcard patterns, and among multiple patterns with wildcards, the longest is preferred. See the RulesBase class for more information.
This feature of preferring "better" patterns can be a powerful tool. However it also means that patterns can interact in unexpected ways.
When using the ExtendedBaseRules, any pattern prefixed with '!' bypasses the "best match" feature. Even if there is an exact match or a longer wildcard match, patterns prefixed by '!' will still be tested to see if they match, and if so their associated Rule objects will be included in the set of rules to be executed in the normal manner.
- Pattern
"!*/a/b"
matches whenever an 'b' element is inside an 'a'. - Pattern
"!a/b/?"
matches any child of a parent matching"a/b"
(see "Parent Match Patterns"). - Pattern
"!*/a/b/?"
matches any child of a parent matching"!*/a/b"
(see "Parent Match Patterns"). - Pattern
"!a/b/*"
matches any element whose path starts with "a" then "b" (see "Ancestor Match Patterns"). - Pattern
"!*/a/b/*"
matches any elements whose path contains 'a/b' (see "Ancestor Match Patterns").
Parent Match Patterns
These will match direct child elements of a particular parent element.
-
"a/b/c/?"
matches any child whose parent matches"a/b/c"
. Exact parent rules take precedence over Ancestor Match patterns. -
"*/a/b/c/?"
matches any child whose parent matches"*/a/b/c"
. The longest matching still applies to parent matches but the length excludes the '?', which effectively means that standard wildcard matches with the same level of depth are chosen in preference.
Ancestor Match Patterns
These will match elements whose parentage includes a particular sequence of elements.
-
"a/b/*"
matches any element whose path starts with 'a' then 'b'. Exact parent and parent match rules take precedence. The longest ancestor match will take precedence. -
"*/a/b/*"
matches any elements whose path contains an element 'a' followed by an element 'b'. The longest matching still applies but the length excludes the '*' at the end.
Completely Wild Patterns
Pattern "*"
matches every pattern that isn't matched by any other basic rule.
Pattern "!*"
matches every pattern.
Using The Extended Rules
By default, a Digester instance uses a RulesBase
instance as its pattern matching engine. To use an
ExtendedBaseRules instance, call the Digester.setRules method before adding any Rule objects to the digester
instance:
Digester digester = new Digester(); digester.setRules( new ExtendedBaseRules() );
The most important thing to remember when using the extended rules is that universal and non-universal patterns are completely independent. Universal patterns are never affected by the addition of new patterns or the removal of existing ones. Non-universal patterns are never affected by the addition of new universal patterns or the removal of existing universal patterns. As in the basic matching rules, non-universal (basic) patterns can be affected by the addition of new non-universal patterns or the removal of existing non-universal patterns, because only rules associated with the "best matching" pattern for each xml element are executed.
This means that you can use universal patterns to build up the simple parts of your structure - for example defining universal creation and property setting rules. More sophisticated and complex mapping will require non-universal patterns and this might mean that some of the universal rules will need to be replaced by a series of special cases using non-universal rules. But by using universal rules as your backbone, these additions should not break your existing rules.
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate int
Counts the entry number for the rules.The decision algorithm used (unfortunately) doesn't preserve the entry order. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprivate boolean
basicMatch
(String key, String pattern) Standard match.findExactAncesterMatch
(String parentPattern) Finds an exact ancester match for given patternmatch
(String namespaceURI, String pattern, String name, Attributes attributes) Return a List of all registered Rule instances that match the specified nesting pattern, or a zero-length List if there are no matches.private boolean
parentMatch
(String key, String parentPattern) Checks the input parentPattern contains the input key at the end.protected void
registerRule
(String pattern, Rule rule) Register rule at given pattern.Methods inherited from class org.apache.commons.digester3.RulesBase
clear, lookup, rules, setDigester
Methods inherited from class org.apache.commons.digester3.AbstractRulesImpl
add, getDigester, getNamespaceURI, setNamespaceURI
-
Field Details
-
counter
private int counterCounts the entry number for the rules. -
order
The decision algorithm used (unfortunately) doesn't preserve the entry order. This map is used by a comparator which orders the list of matches before it's returned. This map stores the entry number keyed by the rule.
-
-
Constructor Details
-
ExtendedBaseRules
public ExtendedBaseRules()
-
-
Method Details
-
registerRule
Register rule at given pattern. The the Digester and namespaceURI properties of the givenRule
can be assumed to have been set properly before this method is called.- Overrides:
registerRule
in classRulesBase
- Parameters:
pattern
- Nesting pattern to be matched for this Rulerule
- Rule instance to be registered
-
match
Return a List of all registered Rule instances that match the specified nesting pattern, or a zero-length List if there are no matches. If more than one Rule instance matches, they must be returned in the order originally registered through theadd()
method.- Specified by:
match
in interfaceRules
- Overrides:
match
in classRulesBase
- Parameters:
namespaceURI
- Namespace URI for which to select matching rules, ornull
to match regardless of namespace URIpattern
- Nesting pattern to be matchedname
- the local name if the parser is namespace aware, or just the element name otherwiseattributes
- The attribute list of the current matching element- Returns:
- a List of all registered Rule instances that match the specified nesting pattern
-
parentMatch
Checks the input parentPattern contains the input key at the end.- Parameters:
key
- The key to be foundparentPattern
- The pattern where looking for the key- Returns:
- true, if
key
is found insideparentPattern
, false otherwise
-
basicMatch
Standard match. Matches the end of the pattern to the key.- Parameters:
key
- The key to be foundpattern
- The pattern where looking for the key- Returns:
- true, if
key
is found insidepattern
, false otherwise
-
findExactAncesterMatch
Finds an exact ancester match for given pattern- Parameters:
parentPattern
- The input pattern- Returns:
- A list of
Rule
related to the input pattern
-