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(
072: "Wrapped rules must not be null");
073: }
074: this .wrappedRules = wrappedRules;
075: }
076:
077: // --------------------------------------------------------- Properties
078:
079: /** Gets digester using these Rules */
080: public Digester getDigester() {
081: return wrappedRules.getDigester();
082: }
083:
084: /** Sets digeseter using these Rules */
085: public void setDigester(Digester digester) {
086: wrappedRules.setDigester(digester);
087: Iterator it = defaultRules.iterator();
088: while (it.hasNext()) {
089: Rule rule = (Rule) it.next();
090: rule.setDigester(digester);
091: }
092: }
093:
094: /** Gets namespace to apply to Rule's added */
095: public String getNamespaceURI() {
096: return wrappedRules.getNamespaceURI();
097: }
098:
099: /** Sets namespace to apply to Rule's added subsequently */
100: public void setNamespaceURI(String namespaceURI) {
101: wrappedRules.setNamespaceURI(namespaceURI);
102: }
103:
104: /** Gets Rule's which will be fired when the wrapped implementation returns no matches */
105: public List getDefaults() {
106: return defaultRules;
107: }
108:
109: // --------------------------------------------------------- Public Methods
110:
111: public List match(String pattern) {
112: return match("", pattern);
113: }
114:
115: /**
116: * Return list of rules matching given pattern.
117: * If wrapped implementation returns any matches return those.
118: * Otherwise, return default matches.
119: */
120: public List match(String namespaceURI, String pattern) {
121: List matches = wrappedRules.match(namespaceURI, pattern);
122: if (matches == null || matches.isEmpty()) {
123: // a little bit of defensive programming
124: return new ArrayList(defaultRules);
125: }
126: // otherwise
127: return matches;
128: }
129:
130: /** Adds a rule to be fired when wrapped implementation returns no matches */
131: public void addDefault(Rule rule) {
132: // set up rule
133: if (wrappedRules.getDigester() != null) {
134: rule.setDigester(wrappedRules.getDigester());
135: }
136:
137: if (wrappedRules.getNamespaceURI() != null) {
138: rule.setNamespaceURI(wrappedRules.getNamespaceURI());
139: }
140:
141: defaultRules.add(rule);
142: allRules.add(rule);
143: }
144:
145: /** Gets all rules */
146: public List rules() {
147: return allRules;
148: }
149:
150: /** Clears all Rule's */
151: public void clear() {
152: wrappedRules.clear();
153: allRules.clear();
154: defaultRules.clear();
155: }
156:
157: /**
158: * Adds a Rule to be fired on given pattern.
159: * Pattern matching is delegated to wrapped implementation.
160: */
161: public void add(String pattern, Rule rule) {
162: wrappedRules.add(pattern, rule);
163: allRules.add(rule);
164: }
165: }
|