1. /* $Id: WithDefaultsRulesWrapper.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><code>Rules</code> <em>Decorator</em> that returns default rules
  23. * when no matches are returned by the wrapped implementation.</p>
  24. *
  25. * <p>This allows default <code>Rule</code> instances to be added to any
  26. * existing <code>Rules</code> implementation. These default <code>Rule</code>
  27. * instances will be returned for any match for which the wrapped
  28. * implementation does not return any matches.</p>
  29. * <p> For example,
  30. * <pre>
  31. * Rule alpha;
  32. * ...
  33. * WithDefaultsRulesWrapper rules = new WithDefaultsRulesWrapper(new BaseRules());
  34. * rules.addDefault(alpha);
  35. * ...
  36. * digester.setRules(rules);
  37. * ...
  38. * </pre>
  39. * when a pattern does not match any other rule, then rule alpha will be called.
  40. * </p>
  41. * <p><code>WithDefaultsRulesWrapper</code> follows the <em>Decorator</em> pattern.</p>
  42. *
  43. * @since 1.6
  44. */
  45. public class WithDefaultsRulesWrapper implements Rules {
  46. // --------------------------------------------------------- Fields
  47. /** The Rules implementation that this class wraps. */
  48. private Rules wrappedRules;
  49. /** Rules to be fired when the wrapped implementations returns none. */
  50. private List defaultRules = new ArrayList();
  51. /** All rules (preserves order in which they were originally added) */
  52. private List allRules = new ArrayList();
  53. // --------------------------------------------------------- Constructor
  54. /**
  55. * Base constructor.
  56. *
  57. * @param wrappedRules the wrapped <code>Rules</code> implementation, not null
  58. * @throws IllegalArgumentException when <code>wrappedRules</code> is null
  59. */
  60. public WithDefaultsRulesWrapper(Rules wrappedRules) {
  61. if (wrappedRules == null) {
  62. throw new IllegalArgumentException("Wrapped rules must not be null");
  63. }
  64. this.wrappedRules = wrappedRules;
  65. }
  66. // --------------------------------------------------------- Properties
  67. /** Gets digester using these Rules */
  68. public Digester getDigester() {
  69. return wrappedRules.getDigester();
  70. }
  71. /** Sets digeseter using these Rules */
  72. public void setDigester(Digester digester) {
  73. wrappedRules.setDigester(digester);
  74. Iterator it = defaultRules.iterator();
  75. while (it.hasNext()) {
  76. Rule rule = (Rule) it.next();
  77. rule.setDigester(digester);
  78. }
  79. }
  80. /** Gets namespace to apply to Rule's added */
  81. public String getNamespaceURI() {
  82. return wrappedRules.getNamespaceURI();
  83. }
  84. /** Sets namespace to apply to Rule's added subsequently */
  85. public void setNamespaceURI(String namespaceURI) {
  86. wrappedRules.setNamespaceURI(namespaceURI);
  87. }
  88. /** Gets Rule's which will be fired when the wrapped implementation returns no matches */
  89. public List getDefaults() {
  90. return defaultRules;
  91. }
  92. // --------------------------------------------------------- Public Methods
  93. public List match(String pattern) {
  94. return match("", pattern);
  95. }
  96. /**
  97. * Return list of rules matching given pattern.
  98. * If wrapped implementation returns any matches return those.
  99. * Otherwise, return default matches.
  100. */
  101. public List match(String namespaceURI, String pattern) {
  102. List matches = wrappedRules.match(namespaceURI, pattern);
  103. if (matches == null || matches.isEmpty()) {
  104. // a little bit of defensive programming
  105. return new ArrayList(defaultRules);
  106. }
  107. // otherwise
  108. return matches;
  109. }
  110. /** Adds a rule to be fired when wrapped implementation returns no matches */
  111. public void addDefault(Rule rule) {
  112. // set up rule
  113. if (wrappedRules.getDigester() != null) {
  114. rule.setDigester(wrappedRules.getDigester());
  115. }
  116. if (wrappedRules.getNamespaceURI() != null) {
  117. rule.setNamespaceURI(wrappedRules.getNamespaceURI());
  118. }
  119. defaultRules.add(rule);
  120. allRules.add(rule);
  121. }
  122. /** Gets all rules */
  123. public List rules() {
  124. return allRules;
  125. }
  126. /** Clears all Rule's */
  127. public void clear() {
  128. wrappedRules.clear();
  129. allRules.clear();
  130. defaultRules.clear();
  131. }
  132. /**
  133. * Adds a Rule to be fired on given pattern.
  134. * Pattern matching is delegated to wrapped implementation.
  135. */
  136. public void add(String pattern, Rule rule) {
  137. wrappedRules.add(pattern, rule);
  138. allRules.add(rule);
  139. }
  140. }