View Javadoc

    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      public Iterator getConfigAttributeDefinitions() {
    71          Set set = new HashSet();
    72          Iterator iter = requestMap.iterator();
    73
    74          while (iter.hasNext()) {
    75              EntryHolder entryHolder = (EntryHolder) iter.next();
    76              set.add(entryHolder.getConfigAttributeDefinition());
    77          }
    78
    79          return set.iterator();
    80      }
    81
    82      public void setConvertUrlToLowercaseBeforeComparison(
    83          boolean convertUrlToLowercaseBeforeComparison) {
    84          this.convertUrlToLowercaseBeforeComparison = convertUrlToLowercaseBeforeComparison;
    85      }
    86
    87      public boolean isConvertUrlToLowercaseBeforeComparison() {
    88          return convertUrlToLowercaseBeforeComparison;
    89      }
    90
    91      public int getMapSize() {
    92          return this.requestMap.size();
    93      }
    94
    95      public void addSecureUrl(String antPath, ConfigAttributeDefinition attr) {
    96          requestMap.add(new EntryHolder(antPath, attr));
    97
    98          if (logger.isDebugEnabled()) {
    99              logger.debug("Added Ant path: " + antPath + "; attributes: " + attr);
    100         }
    101     }
    102
    103     public ConfigAttributeDefinition lookupAttributes(String url) {
    104         Iterator iter = requestMap.iterator();
    105
    106         if (convertUrlToLowercaseBeforeComparison) {
    107             url = url.toLowerCase();
    108
    109             if (logger.isDebugEnabled()) {
    110                 logger.debug("Converted URL to lowercase, from: '" + url
    111                     + "'; to: '" + url + "'");
    112             }
    113         }
    114
    115         while (iter.hasNext()) {
    116             EntryHolder entryHolder = (EntryHolder) iter.next();
    117
    118             boolean matched = pathMatcher.match(entryHolder.getAntPath(), url);
    119
    120             if (logger.isDebugEnabled()) {
    121                 logger.debug("Candidate is: '" + url + "'; pattern is "
    122                     + entryHolder.getAntPath() + "; matched=" + matched);
    123             }
    124
    125             if (matched) {
    126                 return entryHolder.getConfigAttributeDefinition();
    127             }
    128         }
    129
    130         return null;
    131     }
    132
    133     //~ Inner Classes ==========================================================
    134
    135     protected class EntryHolder {
    136         private ConfigAttributeDefinition configAttributeDefinition;
    137         private String antPath;
    138
    139         public EntryHolder(String antPath, ConfigAttributeDefinition attr) {
    140             this.antPath = antPath;
    141             this.configAttributeDefinition = attr;
    142         }
    143
    144         protected EntryHolder() {
    145             throw new IllegalArgumentException("Cannot use default constructor");
    146         }
    147
    148         public String getAntPath() {
    149             return antPath;
    150         }
    151
    152         public ConfigAttributeDefinition getConfigAttributeDefinition() {
    153             return configAttributeDefinition;
    154         }
    155     }
    156 }