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 }