001 /* $Id: WithDefaultsRulesWrapper.java 729104 2008-12-23 20:45:23Z rahul $ 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.List; 023 024 /** 025 * <p><code>Rules</code> <em>Decorator</em> that returns default rules 026 * when no matches are returned by the wrapped implementation.</p> 027 * 028 * <p>This allows default <code>Rule</code> instances to be added to any 029 * existing <code>Rules</code> implementation. These default <code>Rule</code> 030 * instances will be returned for any match for which the wrapped 031 * implementation does not return any matches.</p> 032 * <p> For example, 033 * <pre> 034 * Rule alpha; 035 * ... 036 * WithDefaultsRulesWrapper rules = new WithDefaultsRulesWrapper(new BaseRules()); 037 * rules.addDefault(alpha); 038 * ... 039 * digester.setRules(rules); 040 * ... 041 * </pre> 042 * when a pattern does not match any other rule, then rule alpha will be called. 043 * </p> 044 * <p><code>WithDefaultsRulesWrapper</code> follows the <em>Decorator</em> pattern.</p> 045 * 046 * @since 1.6 047 */ 048 049 public class WithDefaultsRulesWrapper implements Rules { 050 051 // --------------------------------------------------------- Fields 052 053 /** The Rules implementation that this class wraps. */ 054 private Rules wrappedRules; 055 /** Rules to be fired when the wrapped implementations returns none. */ 056 private List<Rule> defaultRules = new ArrayList<Rule>(); 057 /** All rules (preserves order in which they were originally added) */ 058 private List<Rule> allRules = new ArrayList<Rule>(); 059 060 // --------------------------------------------------------- Constructor 061 062 /** 063 * Base constructor. 064 * 065 * @param wrappedRules the wrapped <code>Rules</code> implementation, not null 066 * @throws IllegalArgumentException when <code>wrappedRules</code> is null 067 */ 068 public WithDefaultsRulesWrapper(Rules wrappedRules) { 069 if (wrappedRules == null) { 070 throw new IllegalArgumentException("Wrapped rules must not be null"); 071 } 072 this.wrappedRules = wrappedRules; 073 } 074 075 // --------------------------------------------------------- Properties 076 077 /** Gets digester using these Rules */ 078 public Digester getDigester() { 079 return wrappedRules.getDigester(); 080 } 081 082 /** Sets digeseter using these Rules */ 083 public void setDigester(Digester digester) { 084 wrappedRules.setDigester(digester); 085 for (Rule rule : defaultRules) { 086 rule.setDigester(digester); 087 } 088 } 089 090 /** Gets namespace to apply to Rule's added */ 091 public String getNamespaceURI() { 092 return wrappedRules.getNamespaceURI(); 093 } 094 095 /** Sets namespace to apply to Rule's added subsequently */ 096 public void setNamespaceURI(String namespaceURI) { 097 wrappedRules.setNamespaceURI(namespaceURI); 098 } 099 100 /** Gets Rule's which will be fired when the wrapped implementation returns no matches */ 101 public List<Rule> getDefaults() { 102 return defaultRules; 103 } 104 105 // --------------------------------------------------------- Public Methods 106 107 public List<Rule> match(String pattern) { 108 return match("", pattern); 109 } 110 111 /** 112 * Return list of rules matching given pattern. 113 * If wrapped implementation returns any matches return those. 114 * Otherwise, return default matches. 115 */ 116 public List<Rule> match(String namespaceURI, String pattern) { 117 List<Rule> matches = wrappedRules.match(namespaceURI, pattern); 118 if (matches == null || matches.isEmpty()) { 119 // a little bit of defensive programming 120 return new ArrayList<Rule>(defaultRules); 121 } 122 // otherwise 123 return matches; 124 } 125 126 /** Adds a rule to be fired when wrapped implementation returns no matches */ 127 public void addDefault(Rule rule) { 128 // set up rule 129 if (wrappedRules.getDigester() != null) { 130 rule.setDigester(wrappedRules.getDigester()); 131 } 132 133 if (wrappedRules.getNamespaceURI() != null) { 134 rule.setNamespaceURI(wrappedRules.getNamespaceURI()); 135 } 136 137 defaultRules.add(rule); 138 allRules.add(rule); 139 } 140 141 /** Gets all rules */ 142 public List<Rule> rules() { 143 return allRules; 144 } 145 146 /** Clears all Rule's */ 147 public void clear() { 148 wrappedRules.clear(); 149 allRules.clear(); 150 defaultRules.clear(); 151 } 152 153 /** 154 * Adds a Rule to be fired on given pattern. 155 * Pattern matching is delegated to wrapped implementation. 156 */ 157 public void add(String pattern, Rule rule) { 158 wrappedRules.add(pattern, rule); 159 allRules.add(rule); 160 } 161 }