Clover coverage report - Acegi Security System for Spring - 1.0.0-RC1
Coverage timestamp: Mon Dec 5 2005 09:05:15 EST
file stats: LOC: 178   Methods: 10
NCLOC: 100   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
RegExpBasedFilterInvocationDefinitionMap.java 78.6% 91.7% 100% 90%
coverage coverage
 1    /* Copyright 2004, 2005 Acegi Technology Pty Limited
 2    *
 3    * Licensed under the Apache License, Version 2.0 (the "License");
 4    * you may not use this file except in compliance with the License.
 5    * You may obtain a copy of the License at
 6    *
 7    * http://www.apache.org/licenses/LICENSE-2.0
 8    *
 9    * Unless required by applicable law or agreed to in writing, software
 10    * distributed under the License is distributed on an "AS IS" BASIS,
 11    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12    * See the License for the specific language governing permissions and
 13    * limitations under the License.
 14    */
 15   
 16    package org.acegisecurity.intercept.web;
 17   
 18    import org.acegisecurity.ConfigAttributeDefinition;
 19   
 20    import org.apache.commons.logging.Log;
 21    import org.apache.commons.logging.LogFactory;
 22   
 23    import org.apache.oro.text.regex.MalformedPatternException;
 24    import org.apache.oro.text.regex.Pattern;
 25    import org.apache.oro.text.regex.PatternMatcher;
 26    import org.apache.oro.text.regex.Perl5Compiler;
 27    import org.apache.oro.text.regex.Perl5Matcher;
 28   
 29    import java.util.HashSet;
 30    import java.util.Iterator;
 31    import java.util.List;
 32    import java.util.Set;
 33    import java.util.Vector;
 34   
 35   
 36    /**
 37    * Maintains a <Code>List</code> of <code>ConfigAttributeDefinition</code>s
 38    * associated with different HTTP request URL regular expression patterns.
 39    *
 40    * <P>
 41    * Regular expressions are used to match a HTTP request URL against a
 42    * <code>ConfigAttributeDefinition</code>.
 43    * </p>
 44    *
 45    * <p>
 46    * The order of registering the regular expressions using the {@link
 47    * #addSecureUrl(String, ConfigAttributeDefinition)} is very important. The
 48    * system will identify the <B>first</B> matching regular expression for a
 49    * given HTTP URL. It will not proceed to evaluate later regular expressions
 50    * if a match has already been found. Accordingly, the most specific regular
 51    * expressions should be registered first, with the most general regular
 52    * expressions registered last.
 53    * </p>
 54    *
 55    * <P>
 56    * If no registered regular expressions match the HTTP URL, <code>null</code>
 57    * is returned.
 58    * </p>
 59    */
 60    public class RegExpBasedFilterInvocationDefinitionMap
 61    extends AbstractFilterInvocationDefinitionSource
 62    implements FilterInvocationDefinitionMap {
 63    //~ Static fields/initializers =============================================
 64   
 65    private static final Log logger = LogFactory.getLog(RegExpBasedFilterInvocationDefinitionMap.class);
 66   
 67    //~ Instance fields ========================================================
 68   
 69    private List requestMap = new Vector();
 70    private boolean convertUrlToLowercaseBeforeComparison = false;
 71   
 72    //~ Methods ================================================================
 73   
 74  2 public Iterator getConfigAttributeDefinitions() {
 75  2 Set set = new HashSet();
 76  2 Iterator iter = requestMap.iterator();
 77   
 78  2 while (iter.hasNext()) {
 79  2 EntryHolder entryHolder = (EntryHolder) iter.next();
 80  2 set.add(entryHolder.getConfigAttributeDefinition());
 81    }
 82   
 83  2 return set.iterator();
 84    }
 85   
 86  3 public void setConvertUrlToLowercaseBeforeComparison(
 87    boolean convertUrlToLowercaseBeforeComparison) {
 88  3 this.convertUrlToLowercaseBeforeComparison = convertUrlToLowercaseBeforeComparison;
 89    }
 90   
 91  7 public boolean isConvertUrlToLowercaseBeforeComparison() {
 92  7 return convertUrlToLowercaseBeforeComparison;
 93    }
 94   
 95  4 public int getMapSize() {
 96  4 return this.requestMap.size();
 97    }
 98   
 99  22 public void addSecureUrl(String perl5RegExp, ConfigAttributeDefinition attr) {
 100  22 Pattern compiledPattern;
 101  22 Perl5Compiler compiler = new Perl5Compiler();
 102   
 103  22 try {
 104  22 compiledPattern = compiler.compile(perl5RegExp,
 105    Perl5Compiler.READ_ONLY_MASK);
 106    } catch (MalformedPatternException mpe) {
 107  1 throw new IllegalArgumentException("Malformed regular expression: "
 108    + perl5RegExp);
 109    }
 110   
 111  21 requestMap.add(new EntryHolder(compiledPattern, attr));
 112   
 113  21 if (logger.isDebugEnabled()) {
 114  0 logger.debug("Added regular expression: "
 115    + compiledPattern.getPattern().toString() + "; attributes: "
 116    + attr);
 117    }
 118    }
 119   
 120  7 public ConfigAttributeDefinition lookupAttributes(String url) {
 121  7 PatternMatcher matcher = new Perl5Matcher();
 122   
 123  7 Iterator iter = requestMap.iterator();
 124   
 125  7 if (convertUrlToLowercaseBeforeComparison) {
 126  1 url = url.toLowerCase();
 127   
 128  1 if (logger.isDebugEnabled()) {
 129  0 logger.debug("Converted URL to lowercase, from: '" + url
 130    + "'; to: '" + url + "'");
 131    }
 132    }
 133   
 134  7 while (iter.hasNext()) {
 135  7 EntryHolder entryHolder = (EntryHolder) iter.next();
 136   
 137  7 boolean matched = matcher.matches(url,
 138    entryHolder.getCompiledPattern());
 139   
 140  7 if (logger.isDebugEnabled()) {
 141  0 logger.debug("Candidate is: '" + url + "'; pattern is "
 142    + entryHolder.getCompiledPattern().getPattern()
 143    + "; matched=" + matched);
 144    }
 145   
 146  7 if (matched) {
 147  5 return entryHolder.getConfigAttributeDefinition();
 148    }
 149    }
 150   
 151  2 return null;
 152    }
 153   
 154    //~ Inner Classes ==========================================================
 155   
 156    protected class EntryHolder {
 157    private ConfigAttributeDefinition configAttributeDefinition;
 158    private Pattern compiledPattern;
 159   
 160  21 public EntryHolder(Pattern compiledPattern,
 161    ConfigAttributeDefinition attr) {
 162  21 this.compiledPattern = compiledPattern;
 163  21 this.configAttributeDefinition = attr;
 164    }
 165   
 166  1 protected EntryHolder() {
 167  1 throw new IllegalArgumentException("Cannot use default constructor");
 168    }
 169   
 170  7 public Pattern getCompiledPattern() {
 171  7 return compiledPattern;
 172    }
 173   
 174  7 public ConfigAttributeDefinition getConfigAttributeDefinition() {
 175  7 return configAttributeDefinition;
 176    }
 177    }
 178    }