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(
075: "RegexMatcher must not be null.");
076: }
077: this .matcher = matcher;
078: }
079:
080: // --------------------------------------------------------- Public Methods
081:
082: /**
083: * Register a new Rule instance matching the specified pattern.
084: *
085: * @param pattern Nesting pattern to be matched for this Rule
086: * @param rule Rule instance to be registered
087: */
088: protected void registerRule(String pattern, Rule rule) {
089: registeredRules.add(new RegisteredRule(pattern, rule));
090: }
091:
092: /**
093: * Clear all existing Rule instance registrations.
094: */
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: public List match(String namespaceURI, String pattern) {
110: //
111: // not a particularly quick implementation
112: // regex is probably going to be slower than string equality
113: // so probably should have a set of strings
114: // and test each only once
115: //
116: // XXX FIX ME - Time And Optimize
117: //
118: ArrayList rules = new ArrayList(registeredRules.size());
119: Iterator it = registeredRules.iterator();
120: while (it.hasNext()) {
121: RegisteredRule next = (RegisteredRule) it.next();
122: if (matcher.match(pattern, next.pattern)) {
123: rules.add(next.rule);
124: }
125: }
126: return rules;
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: }
|