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: 156   Methods: 10
NCLOC: 83   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
PathBasedFilterInvocationDefinitionMap.java 78.6% 90% 100% 88.9%
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.springframework.util.PathMatcher;
 24    import org.springframework.util.AntPathMatcher;
 25   
 26    import java.util.HashSet;
 27    import java.util.Iterator;
 28    import java.util.List;
 29    import java.util.Set;
 30    import java.util.Vector;
 31   
 32   
 33    /**
 34    * Maintains a <Code>List</code> of <code>ConfigAttributeDefinition</code>s
 35    * associated with different HTTP request URL Apache Ant path-based patterns.
 36    *
 37    * <P>
 38    * Apache Ant path expressions are used to match a HTTP request URL against a
 39    * <code>ConfigAttributeDefinition</code>.
 40    * </p>
 41    *
 42    * <p>
 43    * The order of registering the Ant paths using the {@link
 44    * #addSecureUrl(String, ConfigAttributeDefinition)} is very important. The
 45    * system will identify the <b>first</b> matching path for a given HTTP URL.
 46    * It will not proceed to evaluate later paths if a match has already been
 47    * found. Accordingly, the most specific paths should be registered first,
 48    * with the most general paths registered last.
 49    * </p>
 50    *
 51    * <P>
 52    * If no registered paths match the HTTP URL, <code>null</code> is returned.
 53    * </p>
 54    */
 55    public class PathBasedFilterInvocationDefinitionMap
 56    extends AbstractFilterInvocationDefinitionSource
 57    implements FilterInvocationDefinitionMap {
 58    //~ Static fields/initializers =============================================
 59   
 60    private static final Log logger = LogFactory.getLog(PathBasedFilterInvocationDefinitionMap.class);
 61   
 62    //~ Instance fields ========================================================
 63   
 64    private List requestMap = new Vector();
 65    private boolean convertUrlToLowercaseBeforeComparison = false;
 66    private PathMatcher pathMatcher = new AntPathMatcher();
 67   
 68    //~ Methods ================================================================
 69   
 70  15 public Iterator getConfigAttributeDefinitions() {
 71  15 Set set = new HashSet();
 72  15 Iterator iter = requestMap.iterator();
 73   
 74  15 while (iter.hasNext()) {
 75  28 EntryHolder entryHolder = (EntryHolder) iter.next();
 76  28 set.add(entryHolder.getConfigAttributeDefinition());
 77    }
 78   
 79  15 return set.iterator();
 80    }
 81   
 82  13 public void setConvertUrlToLowercaseBeforeComparison(
 83    boolean convertUrlToLowercaseBeforeComparison) {
 84  13 this.convertUrlToLowercaseBeforeComparison = convertUrlToLowercaseBeforeComparison;
 85    }
 86   
 87  7 public boolean isConvertUrlToLowercaseBeforeComparison() {
 88  7 return convertUrlToLowercaseBeforeComparison;
 89    }
 90   
 91  2 public int getMapSize() {
 92  2 return this.requestMap.size();
 93    }
 94   
 95  42 public void addSecureUrl(String antPath, ConfigAttributeDefinition attr) {
 96  42 requestMap.add(new EntryHolder(antPath, attr));
 97   
 98  42 if (logger.isDebugEnabled()) {
 99  0 logger.debug("Added Ant path: " + antPath + "; attributes: " + attr);
 100    }
 101    }
 102   
 103  9 public ConfigAttributeDefinition lookupAttributes(String url) {
 104  9 Iterator iter = requestMap.iterator();
 105   
 106  9 if (convertUrlToLowercaseBeforeComparison) {
 107  3 url = url.toLowerCase();
 108   
 109  3 if (logger.isDebugEnabled()) {
 110  0 logger.debug("Converted URL to lowercase, from: '" + url
 111    + "'; to: '" + url + "'");
 112    }
 113    }
 114   
 115  9 while (iter.hasNext()) {
 116  10 EntryHolder entryHolder = (EntryHolder) iter.next();
 117   
 118  10 boolean matched = pathMatcher.match(entryHolder.getAntPath(), url);
 119   
 120  10 if (logger.isDebugEnabled()) {
 121  0 logger.debug("Candidate is: '" + url + "'; pattern is "
 122    + entryHolder.getAntPath() + "; matched=" + matched);
 123    }
 124   
 125  10 if (matched) {
 126  6 return entryHolder.getConfigAttributeDefinition();
 127    }
 128    }
 129   
 130  3 return null;
 131    }
 132   
 133    //~ Inner Classes ==========================================================
 134   
 135    protected class EntryHolder {
 136    private ConfigAttributeDefinition configAttributeDefinition;
 137    private String antPath;
 138   
 139  42 public EntryHolder(String antPath, ConfigAttributeDefinition attr) {
 140  42 this.antPath = antPath;
 141  42 this.configAttributeDefinition = attr;
 142    }
 143   
 144  1 protected EntryHolder() {
 145  1 throw new IllegalArgumentException("Cannot use default constructor");
 146    }
 147   
 148  10 public String getAntPath() {
 149  10 return antPath;
 150    }
 151   
 152  34 public ConfigAttributeDefinition getConfigAttributeDefinition() {
 153  34 return configAttributeDefinition;
 154    }
 155    }
 156    }