KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tomcat > util > digester > RulesBase


1 /* $Id: RulesBase.java 467222 2006-10-24 03:17:11Z markt $
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one or more
4  * contributor license agreements. See the NOTICE file distributed with
5  * this work for additional information regarding copyright ownership.
6  * The ASF licenses this file to You under the Apache License, Version 2.0
7  * (the "License"); you may not use this file except in compliance with
8  * the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19
20 package org.apache.tomcat.util.digester;
21
22
23 import java.util.ArrayList JavaDoc;
24 import java.util.HashMap JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.List JavaDoc;
27
28
29 /**
30  * <p>Default implementation of the <code>Rules</code> interface that supports
31  * the standard rule matching behavior. This class can also be used as a
32  * base class for specialized <code>Rules</code> implementations.</p>
33  *
34  * <p>The matching policies implemented by this class support two different
35  * types of pattern matching rules:</p>
36  * <ul>
37  * <li><em>Exact Match</em> - A pattern "a/b/c" exactly matches a
38  * <code>&lt;c&gt;</code> element, nested inside a <code>&lt;b&gt;</code>
39  * element, which is nested inside an <code>&lt;a&gt;</code> element.</li>
40  * <li><em>Tail Match</em> - A pattern "&#42;/a/b" matches a
41  * <code>&lt;b&gt;</code> element, nested inside an <code>&lt;a&gt;</code>
42  * element, no matter how deeply the pair is nested.</li>
43  * </ul>
44  */

45
46 public class RulesBase implements Rules {
47
48
49     // ----------------------------------------------------- Instance Variables
50

51
52     /**
53      * The set of registered Rule instances, keyed by the matching pattern.
54      * Each value is a List containing the Rules for that pattern, in the
55      * order that they were orginally registered.
56      */

57     protected HashMap JavaDoc cache = new HashMap JavaDoc();
58
59
60     /**
61      * The Digester instance with which this Rules instance is associated.
62      */

63     protected Digester digester = null;
64
65
66     /**
67      * The namespace URI for which subsequently added <code>Rule</code>
68      * objects are relevant, or <code>null</code> for matching independent
69      * of namespaces.
70      */

71     protected String JavaDoc namespaceURI = null;
72
73
74     /**
75      * The set of registered Rule instances, in the order that they were
76      * originally registered.
77      */

78     protected ArrayList JavaDoc rules = new ArrayList JavaDoc();
79
80
81     // ------------------------------------------------------------- Properties
82

83
84     /**
85      * Return the Digester instance with which this Rules instance is
86      * associated.
87      */

88     public Digester getDigester() {
89
90         return (this.digester);
91
92     }
93
94
95     /**
96      * Set the Digester instance with which this Rules instance is associated.
97      *
98      * @param digester The newly associated Digester instance
99      */

100     public void setDigester(Digester digester) {
101
102         this.digester = digester;
103         Iterator JavaDoc items = rules.iterator();
104         while (items.hasNext()) {
105             Rule item = (Rule) items.next();
106             item.setDigester(digester);
107         }
108
109     }
110
111
112     /**
113      * Return the namespace URI that will be applied to all subsequently
114      * added <code>Rule</code> objects.
115      */

116     public String JavaDoc getNamespaceURI() {
117
118         return (this.namespaceURI);
119
120     }
121
122
123     /**
124      * Set the namespace URI that will be applied to all subsequently
125      * added <code>Rule</code> objects.
126      *
127      * @param namespaceURI Namespace URI that must match on all
128      * subsequently added rules, or <code>null</code> for matching
129      * regardless of the current namespace URI
130      */

131     public void setNamespaceURI(String JavaDoc namespaceURI) {
132
133         this.namespaceURI = namespaceURI;
134
135     }
136
137
138     // --------------------------------------------------------- Public Methods
139

140
141     /**
142      * Register a new Rule instance matching the specified pattern.
143      *
144      * @param pattern Nesting pattern to be matched for this Rule
145      * @param rule Rule instance to be registered
146      */

147     public void add(String JavaDoc pattern, Rule rule) {
148         // to help users who accidently add '/' to the end of their patterns
149
int patternLength = pattern.length();
150         if (patternLength>1 && pattern.endsWith("/")) {
151             pattern = pattern.substring(0, patternLength-1);
152         }
153         
154         
155         List JavaDoc list = (List JavaDoc) cache.get(pattern);
156         if (list == null) {
157             list = new ArrayList JavaDoc();
158             cache.put(pattern, list);
159         }
160         list.add(rule);
161         rules.add(rule);
162         if (this.digester != null) {
163             rule.setDigester(this.digester);
164         }
165         if (this.namespaceURI != null) {
166             rule.setNamespaceURI(this.namespaceURI);
167         }
168
169     }
170
171
172     /**
173      * Clear all existing Rule instance registrations.
174      */

175     public void clear() {
176
177         cache.clear();
178         rules.clear();
179
180     }
181
182
183     /**
184      * Return a List of all registered Rule instances that match the specified
185      * nesting pattern, or a zero-length List if there are no matches. If more
186      * than one Rule instance matches, they <strong>must</strong> be returned
187      * in the order originally registered through the <code>add()</code>
188      * method.
189      *
190      * @param pattern Nesting pattern to be matched
191      *
192      * @deprecated Call match(namespaceURI,pattern) instead.
193      */

194     public List JavaDoc match(String JavaDoc pattern) {
195
196         return (match(null, pattern));
197
198     }
199
200
201     /**
202      * Return a List of all registered Rule instances that match the specified
203      * nesting pattern, or a zero-length List if there are no matches. If more
204      * than one Rule instance matches, they <strong>must</strong> be returned
205      * in the order originally registered through the <code>add()</code>
206      * method.
207      *
208      * @param namespaceURI Namespace URI for which to select matching rules,
209      * or <code>null</code> to match regardless of namespace URI
210      * @param pattern Nesting pattern to be matched
211      */

212     public List JavaDoc match(String JavaDoc namespaceURI, String JavaDoc pattern) {
213
214         // List rulesList = (List) this.cache.get(pattern);
215
List JavaDoc rulesList = lookup(namespaceURI, pattern);
216         if ((rulesList == null) || (rulesList.size() < 1)) {
217             // Find the longest key, ie more discriminant
218
String JavaDoc longKey = "";
219             Iterator JavaDoc keys = this.cache.keySet().iterator();
220             while (keys.hasNext()) {
221                 String JavaDoc key = (String JavaDoc) keys.next();
222                 if (key.startsWith("*/")) {
223                     if (pattern.equals(key.substring(2)) ||
224                         pattern.endsWith(key.substring(1))) {
225                         if (key.length() > longKey.length()) {
226                             // rulesList = (List) this.cache.get(key);
227
rulesList = lookup(namespaceURI, key);
228                             longKey = key;
229                         }
230                     }
231                 }
232             }
233         }
234         if (rulesList == null) {
235             rulesList = new ArrayList JavaDoc();
236         }
237         return (rulesList);
238
239     }
240
241
242     /**
243      * Return a List of all registered Rule instances, or a zero-length List
244      * if there are no registered Rule instances. If more than one Rule
245      * instance has been registered, they <strong>must</strong> be returned
246      * in the order originally registered through the <code>add()</code>
247      * method.
248      */

249     public List JavaDoc rules() {
250
251         return (this.rules);
252
253     }
254
255
256     // ------------------------------------------------------ Protected Methods
257

258
259     /**
260      * Return a List of Rule instances for the specified pattern that also
261      * match the specified namespace URI (if any). If there are no such
262      * rules, return <code>null</code>.
263      *
264      * @param namespaceURI Namespace URI to match, or <code>null</code> to
265      * select matching rules regardless of namespace URI
266      * @param pattern Pattern to be matched
267      */

268     protected List JavaDoc lookup(String JavaDoc namespaceURI, String JavaDoc pattern) {
269
270         // Optimize when no namespace URI is specified
271
List JavaDoc list = (List JavaDoc) this.cache.get(pattern);
272         if (list == null) {
273             return (null);
274         }
275         if ((namespaceURI == null) || (namespaceURI.length() == 0)) {
276             return (list);
277         }
278
279         // Select only Rules that match on the specified namespace URI
280
ArrayList JavaDoc results = new ArrayList JavaDoc();
281         Iterator JavaDoc items = list.iterator();
282         while (items.hasNext()) {
283             Rule item = (Rule) items.next();
284             if ((namespaceURI.equals(item.getNamespaceURI())) ||
285                     (item.getNamespaceURI() == null)) {
286                 results.add(item);
287             }
288         }
289         return (results);
290
291     }
292
293
294 }
295
Popular Tags