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 }