1. /* $Id: RegexRules.java,v 1.9 2004/05/10 06:52:50 skitching Exp $
  2. *
  3. * Copyright 2003-2004 The Apache Software Foundation.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package org.apache.commons.digester;
  18. import java.util.ArrayList;
  19. import java.util.Iterator;
  20. import java.util.List;
  21. /**
  22. * <p>Rules implementation that uses regular expression matching for paths.</p>
  23. *
  24. * <p>The regex implementation is pluggable, allowing different strategies to be used.
  25. * The basic way that this class work does not vary.
  26. * All patterns are tested to see if they match the path using the regex matcher.
  27. * All those that do are return in the order which the rules were added.</p>
  28. *
  29. * @since 1.5
  30. */
  31. public class RegexRules extends AbstractRulesImpl {
  32. // --------------------------------------------------------- Fields
  33. /** All registered <code>Rule</code>'s */
  34. private ArrayList registeredRules = new ArrayList();
  35. /** The regex strategy used by this RegexRules */
  36. private RegexMatcher matcher;
  37. // --------------------------------------------------------- Constructor
  38. /**
  39. * Construct sets the Regex matching strategy.
  40. *
  41. * @param matcher the regex strategy to be used, not null
  42. * @throws IllegalArgumentException if the strategy is null
  43. */
  44. public RegexRules(RegexMatcher matcher) {
  45. setRegexMatcher(matcher);
  46. }
  47. // --------------------------------------------------------- Properties
  48. /**
  49. * Gets the current regex matching strategy.
  50. */
  51. public RegexMatcher getRegexMatcher() {
  52. return matcher;
  53. }
  54. /**
  55. * Sets the current regex matching strategy.
  56. *
  57. * @param matcher use this RegexMatcher, not null
  58. * @throws IllegalArgumentException if the strategy is null
  59. */
  60. public void setRegexMatcher(RegexMatcher matcher) {
  61. if (matcher == null) {
  62. throw new IllegalArgumentException("RegexMatcher must not be null.");
  63. }
  64. this.matcher = matcher;
  65. }
  66. // --------------------------------------------------------- Public Methods
  67. /**
  68. * Register a new Rule instance matching the specified pattern.
  69. *
  70. * @param pattern Nesting pattern to be matched for this Rule
  71. * @param rule Rule instance to be registered
  72. */
  73. protected void registerRule(String pattern, Rule rule) {
  74. registeredRules.add(new RegisteredRule(pattern, rule));
  75. }
  76. /**
  77. * Clear all existing Rule instance registrations.
  78. */
  79. public void clear() {
  80. registeredRules.clear();
  81. }
  82. /**
  83. * Finds matching rules by using current regex matching strategy.
  84. * The rule associated with each path that matches is added to the list of matches.
  85. * The order of matching rules is the same order that they were added.
  86. *
  87. * @param namespaceURI Namespace URI for which to select matching rules,
  88. * or <code>null</code> to match regardless of namespace URI
  89. * @param pattern Nesting pattern to be matched
  90. * @return a list of matching <code>Rule</code>'s
  91. */
  92. public List match(String namespaceURI, String pattern) {
  93. //
  94. // not a particularly quick implementation
  95. // regex is probably going to be slower than string equality
  96. // so probably should have a set of strings
  97. // and test each only once
  98. //
  99. // XXX FIX ME - Time And Optimize
  100. //
  101. ArrayList rules = new ArrayList(registeredRules.size());
  102. Iterator it = registeredRules.iterator();
  103. while (it.hasNext()) {
  104. RegisteredRule next = (RegisteredRule) it.next();
  105. if (matcher.match(pattern, next.pattern)) {
  106. rules.add(next.rule);
  107. }
  108. }
  109. return rules;
  110. }
  111. /**
  112. * Return a List of all registered Rule instances, or a zero-length List
  113. * if there are no registered Rule instances. If more than one Rule
  114. * instance has been registered, they <strong>must</strong> be returned
  115. * in the order originally registered through the <code>add()</code>
  116. * method.
  117. */
  118. public List rules() {
  119. ArrayList rules = new ArrayList(registeredRules.size());
  120. Iterator it = registeredRules.iterator();
  121. while (it.hasNext()) {
  122. rules.add(((RegisteredRule) it.next()).rule);
  123. }
  124. return rules;
  125. }
  126. /** Used to associate rules with paths in the rules list */
  127. private class RegisteredRule {
  128. String pattern;
  129. Rule rule;
  130. RegisteredRule(String pattern, Rule rule) {
  131. this.pattern = pattern;
  132. this.rule = rule;
  133. }
  134. }
  135. }