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 }