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