1 package org.apache.commons.digester3;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.util.ArrayList;
23 import java.util.List;
24
25 import org.xml.sax.Attributes;
26
27 /**
28 * <p>
29 * <code>Rules</code> <em>Decorator</em> that returns default rules when no matches are returned by the wrapped
30 * implementation.
31 * </p>
32 * <p>
33 * This allows default <code>Rule</code> instances to be added to any existing <code>Rules</code> implementation. These
34 * default <code>Rule</code> instances will be returned for any match for which the wrapped implementation does not
35 * return any matches.
36 * </p>
37 * <p>
38 * For example,
39 *
40 * <pre>
41 * Rule alpha;
42 * ...
43 * WithDefaultsRulesWrapper rules = new WithDefaultsRulesWrapper(new BaseRules());
44 * rules.addDefault(alpha);
45 * ...
46 * digester.setRules(rules);
47 * ...
48 * </pre>
49 *
50 * when a pattern does not match any other rule, then rule alpha will be called.
51 * </p>
52 * <p>
53 * <code>WithDefaultsRulesWrapper</code> follows the <em>Decorator</em> pattern.
54 * </p>
55 *
56 * @since 1.6
57 */
58 public class WithDefaultsRulesWrapper
59 implements Rules
60 {
61
62 // --------------------------------------------------------- Fields
63
64 /** The Rules implementation that this class wraps. */
65 private Rules wrappedRules;
66
67 /** Rules to be fired when the wrapped implementations returns none. */
68 private List<Rule> defaultRules = new ArrayList<Rule>();
69
70 /** All rules (preserves order in which they were originally added) */
71 private List<Rule> allRules = new ArrayList<Rule>();
72
73 // --------------------------------------------------------- Constructor
74
75 /**
76 * Base constructor.
77 *
78 * @param wrappedRules the wrapped <code>Rules</code> implementation, not null
79 */
80 public WithDefaultsRulesWrapper( Rules wrappedRules )
81 {
82 if ( wrappedRules == null )
83 {
84 throw new IllegalArgumentException( "Wrapped rules must not be null" );
85 }
86 this.wrappedRules = wrappedRules;
87 }
88
89 // --------------------------------------------------------- Properties
90
91 /**
92 * {@inheritDoc}
93 */
94 public Digester getDigester()
95 {
96 return wrappedRules.getDigester();
97 }
98
99 /**
100 * {@inheritDoc}
101 */
102 public void setDigester( Digester digester )
103 {
104 wrappedRules.setDigester( digester );
105 for ( Rule rule : defaultRules )
106 {
107 rule.setDigester( digester );
108 }
109 }
110
111 /**
112 * {@inheritDoc}
113 */
114 public String getNamespaceURI()
115 {
116 return wrappedRules.getNamespaceURI();
117 }
118
119 /**
120 * {@inheritDoc}
121 */
122 public void setNamespaceURI( String namespaceURI )
123 {
124 wrappedRules.setNamespaceURI( namespaceURI );
125 }
126
127 /**
128 * Gets Rule's which will be fired when the wrapped implementation returns no matches
129 *
130 * @return Rule's which will be fired when the wrapped implementation returns no matches
131 **/
132 public List<Rule> getDefaults()
133 {
134 return defaultRules;
135 }
136
137 // --------------------------------------------------------- Public Methods
138
139 /**
140 * {@inheritDoc}
141 */
142 public List<Rule> match( String namespaceURI, String pattern, String name, Attributes attributes )
143 {
144 List<Rule> matches = wrappedRules.match( namespaceURI, pattern, name, attributes );
145 if ( matches == null || matches.isEmpty() )
146 {
147 // a little bit of defensive programming
148 return new ArrayList<Rule>( defaultRules );
149 }
150 // otherwise
151 return matches;
152 }
153
154 /**
155 * Adds a rule to be fired when wrapped implementation returns no matches
156 *
157 * @param rule a Rule to be fired when wrapped implementation returns no matches
158 **/
159 public void addDefault( Rule rule )
160 {
161 // set up rule
162 if ( wrappedRules.getDigester() != null )
163 {
164 rule.setDigester( wrappedRules.getDigester() );
165 }
166
167 if ( wrappedRules.getNamespaceURI() != null )
168 {
169 rule.setNamespaceURI( wrappedRules.getNamespaceURI() );
170 }
171
172 defaultRules.add( rule );
173 allRules.add( rule );
174 }
175
176 /**
177 * {@inheritDoc}
178 */
179 public List<Rule> rules()
180 {
181 return allRules;
182 }
183
184 /**
185 * {@inheritDoc}
186 */
187 public void clear()
188 {
189 wrappedRules.clear();
190 allRules.clear();
191 defaultRules.clear();
192 }
193
194 /**
195 * {@inheritDoc}
196 */
197 public void add( String pattern, Rule rule )
198 {
199 wrappedRules.add( pattern, rule );
200 allRules.add( rule );
201 }
202
203 }