001 /* $Id: RegexRules.java 992060 2010-09-02 19:09:47Z simonetripodi $
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 @Override
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 @Override
095 public void clear() {
096 registeredRules.clear();
097 }
098
099 /**
100 * Finds matching rules by using current regex matching strategy.
101 * The rule associated with each path that matches is added to the list of matches.
102 * The order of matching rules is the same order that they were added.
103 *
104 * @param namespaceURI Namespace URI for which to select matching rules,
105 * or <code>null</code> to match regardless of namespace URI
106 * @param pattern Nesting pattern to be matched
107 * @return a list of matching <code>Rule</code>'s
108 */
109 @Override
110 public List<Rule> match(String namespaceURI, String pattern) {
111 //
112 // not a particularly quick implementation
113 // regex is probably going to be slower than string equality
114 // so probably should have a set of strings
115 // and test each only once
116 //
117 // XXX FIX ME - Time And Optimize
118 //
119 ArrayList<Rule> rules = new ArrayList<Rule>(registeredRules.size());
120 for (RegisteredRule rr : registeredRules) {
121 if (matcher.match(pattern, rr.pattern)) {
122 rules.add(rr.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 @Override
137 public List<Rule> rules() {
138 ArrayList<Rule> rules = new ArrayList<Rule>(registeredRules.size());
139 for (RegisteredRule rr : registeredRules) {
140 rules.add(rr.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 }