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 }