001 /* $Id: WithDefaultsRulesWrapper.java 471661 2006-11-06 08:09:25Z skitching $
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one or more
004 * contributor license agreements. See the NOTICE file distributed with
005 * this work for additional information regarding copyright ownership.
006 * The ASF licenses this file to You under the Apache License, Version 2.0
007 * (the "License"); you may not use this file except in compliance with
008 * the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package org.apache.commons.digester;
020
021 import java.util.ArrayList;
022 import java.util.Iterator;
023 import java.util.List;
024
025 /**
026 * <p><code>Rules</code> <em>Decorator</em> that returns default rules
027 * when no matches are returned by the wrapped implementation.</p>
028 *
029 * <p>This allows default <code>Rule</code> instances to be added to any
030 * existing <code>Rules</code> implementation. These default <code>Rule</code>
031 * instances will be returned for any match for which the wrapped
032 * implementation does not return any matches.</p>
033 * <p> For example,
034 * <pre>
035 * Rule alpha;
036 * ...
037 * WithDefaultsRulesWrapper rules = new WithDefaultsRulesWrapper(new BaseRules());
038 * rules.addDefault(alpha);
039 * ...
040 * digester.setRules(rules);
041 * ...
042 * </pre>
043 * when a pattern does not match any other rule, then rule alpha will be called.
044 * </p>
045 * <p><code>WithDefaultsRulesWrapper</code> follows the <em>Decorator</em> pattern.</p>
046 *
047 * @since 1.6
048 */
049
050 public class WithDefaultsRulesWrapper implements Rules {
051
052 // --------------------------------------------------------- Fields
053
054 /** The Rules implementation that this class wraps. */
055 private Rules wrappedRules;
056 /** Rules to be fired when the wrapped implementations returns none. */
057 private List defaultRules = new ArrayList();
058 /** All rules (preserves order in which they were originally added) */
059 private List allRules = new ArrayList();
060
061 // --------------------------------------------------------- Constructor
062
063 /**
064 * Base constructor.
065 *
066 * @param wrappedRules the wrapped <code>Rules</code> implementation, not null
067 * @throws IllegalArgumentException when <code>wrappedRules</code> is null
068 */
069 public WithDefaultsRulesWrapper(Rules wrappedRules) {
070 if (wrappedRules == null) {
071 throw new IllegalArgumentException("Wrapped rules must not be null");
072 }
073 this.wrappedRules = wrappedRules;
074 }
075
076 // --------------------------------------------------------- Properties
077
078 /** Gets digester using these Rules */
079 public Digester getDigester() {
080 return wrappedRules.getDigester();
081 }
082
083 /** Sets digeseter using these Rules */
084 public void setDigester(Digester digester) {
085 wrappedRules.setDigester(digester);
086 Iterator it = defaultRules.iterator();
087 while (it.hasNext()) {
088 Rule rule = (Rule) it.next();
089 rule.setDigester(digester);
090 }
091 }
092
093 /** Gets namespace to apply to Rule's added */
094 public String getNamespaceURI() {
095 return wrappedRules.getNamespaceURI();
096 }
097
098 /** Sets namespace to apply to Rule's added subsequently */
099 public void setNamespaceURI(String namespaceURI) {
100 wrappedRules.setNamespaceURI(namespaceURI);
101 }
102
103 /** Gets Rule's which will be fired when the wrapped implementation returns no matches */
104 public List getDefaults() {
105 return defaultRules;
106 }
107
108 // --------------------------------------------------------- Public Methods
109
110 public List match(String pattern) {
111 return match("", pattern);
112 }
113
114 /**
115 * Return list of rules matching given pattern.
116 * If wrapped implementation returns any matches return those.
117 * Otherwise, return default matches.
118 */
119 public List match(String namespaceURI, String pattern) {
120 List matches = wrappedRules.match(namespaceURI, pattern);
121 if (matches == null || matches.isEmpty()) {
122 // a little bit of defensive programming
123 return new ArrayList(defaultRules);
124 }
125 // otherwise
126 return matches;
127 }
128
129 /** Adds a rule to be fired when wrapped implementation returns no matches */
130 public void addDefault(Rule rule) {
131 // set up rule
132 if (wrappedRules.getDigester() != null) {
133 rule.setDigester(wrappedRules.getDigester());
134 }
135
136 if (wrappedRules.getNamespaceURI() != null) {
137 rule.setNamespaceURI(wrappedRules.getNamespaceURI());
138 }
139
140 defaultRules.add(rule);
141 allRules.add(rule);
142 }
143
144 /** Gets all rules */
145 public List rules() {
146 return allRules;
147 }
148
149 /** Clears all Rule's */
150 public void clear() {
151 wrappedRules.clear();
152 allRules.clear();
153 defaultRules.clear();
154 }
155
156 /**
157 * Adds a Rule to be fired on given pattern.
158 * Pattern matching is delegated to wrapped implementation.
159 */
160 public void add(String pattern, Rule rule) {
161 wrappedRules.add(pattern, rule);
162 allRules.add(rule);
163 }
164 }