001 /* $Id: RegexRules.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>Rules implementation that uses regular expression matching for paths.</p>
027 *
028 * <p>The regex implementation is pluggable, allowing different strategies to be used.
029 * The basic way that this class work does not vary.
030 * All patterns are tested to see if they match the path using the regex matcher.
031 * All those that do are return in the order which the rules were added.</p>
032 *
033 * @since 1.5
034 */
035
036 public class RegexRules extends AbstractRulesImpl {
037
038 // --------------------------------------------------------- Fields
039
040 /** All registered <code>Rule</code>'s */
041 private ArrayList registeredRules = new ArrayList();
042 /** The regex strategy used by this RegexRules */
043 private RegexMatcher matcher;
044
045 // --------------------------------------------------------- Constructor
046
047 /**
048 * Construct sets the Regex matching strategy.
049 *
050 * @param matcher the regex strategy to be used, not null
051 * @throws IllegalArgumentException if the strategy is null
052 */
053 public RegexRules(RegexMatcher matcher) {
054 setRegexMatcher(matcher);
055 }
056
057 // --------------------------------------------------------- Properties
058
059 /**
060 * Gets the current regex matching strategy.
061 */
062 public RegexMatcher getRegexMatcher() {
063 return matcher;
064 }
065
066 /**
067 * Sets the current regex matching strategy.
068 *
069 * @param matcher use this RegexMatcher, not null
070 * @throws IllegalArgumentException if the strategy is null
071 */
072 public void setRegexMatcher(RegexMatcher matcher) {
073 if (matcher == null) {
074 throw new IllegalArgumentException("RegexMatcher must not be null.");
075 }
076 this.matcher = matcher;
077 }
078
079 // --------------------------------------------------------- Public Methods
080
081 /**
082 * Register a new Rule instance matching the specified pattern.
083 *
084 * @param pattern Nesting pattern to be matched for this Rule
085 * @param rule Rule instance to be registered
086 */
087 protected void registerRule(String pattern, Rule rule) {
088 registeredRules.add(new RegisteredRule(pattern, rule));
089 }
090
091 /**
092 * Clear all existing Rule instance registrations.
093 */
094 public void clear() {
095 registeredRules.clear();
096 }
097
098 /**
099 * Finds matching rules by using current regex matching strategy.
100 * The rule associated with each path that matches is added to the list of matches.
101 * The order of matching rules is the same order that they were added.
102 *
103 * @param namespaceURI Namespace URI for which to select matching rules,
104 * or <code>null</code> to match regardless of namespace URI
105 * @param pattern Nesting pattern to be matched
106 * @return a list of matching <code>Rule</code>'s
107 */
108 public List match(String namespaceURI, String pattern) {
109 //
110 // not a particularly quick implementation
111 // regex is probably going to be slower than string equality
112 // so probably should have a set of strings
113 // and test each only once
114 //
115 // XXX FIX ME - Time And Optimize
116 //
117 ArrayList rules = new ArrayList(registeredRules.size());
118 Iterator it = registeredRules.iterator();
119 while (it.hasNext()) {
120 RegisteredRule next = (RegisteredRule) it.next();
121 if (matcher.match(pattern, next.pattern)) {
122 rules.add(next.rule);
123 }
124 }
125 return rules;
126 }
127
128
129 /**
130 * Return a List of all registered Rule instances, or a zero-length List
131 * if there are no registered Rule instances. If more than one Rule
132 * instance has been registered, they <strong>must</strong> be returned
133 * in the order originally registered through the <code>add()</code>
134 * method.
135 */
136 public List rules() {
137 ArrayList rules = new ArrayList(registeredRules.size());
138 Iterator it = registeredRules.iterator();
139 while (it.hasNext()) {
140 rules.add(((RegisteredRule) it.next()).rule);
141 }
142 return rules;
143 }
144
145 /** Used to associate rules with paths in the rules list */
146 private class RegisteredRule {
147 String pattern;
148 Rule rule;
149
150 RegisteredRule(String pattern, Rule rule) {
151 this.pattern = pattern;
152 this.rule = rule;
153 }
154 }
155 }