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.method;
    17
    18  import org.acegisecurity.ConfigAttribute;
    19  import org.acegisecurity.ConfigAttributeDefinition;
    20
    21  import org.springframework.metadata.Attributes;
    22
    23  import java.lang.reflect.Method;
    24
    25  import java.util.Collection;
    26  import java.util.Iterator;
    27
    28
    29  /***
    30   * Stores a {@link ConfigAttributeDefinition} for each method signature defined
    31   * by Commons Attributes.
    32   *
    33   * <P>
    34   * This class will only detect those attributes which are defined for:
    35   *
    36   * <ul>
    37   * <li>
    38   * The class-wide attributes defined for the intercepted class.
    39   * </li>
    40   * <li>
    41   * The class-wide attributes defined for interfaces explicitly implemented by
    42   * the intercepted class.
    43   * </li>
    44   * <li>
    45   * The method-specific attributes defined for the intercepted method of the
    46   * intercepted class.
    47   * </li>
    48   * <li>
    49   * The method-specific attributes defined by any explicitly implemented
    50   * interface if that interface contains a method signature matching that of
    51   * the intercepted method.
    52   * </li>
    53   * </ul>
    54   * </p>
    55   *
    56   * <P>
    57   * Note that attributes defined against parent classes (either for their
    58   * methods or interfaces) are not detected. The attributes must be defined
    59   * against an explicit method or interface on the intercepted class.
    60   * </p>
    61   *
    62   * <p>
    63   * Attributes detected that do not implement {@link ConfigAttribute} will be
    64   * ignored.
    65   * </p>
    66   *
    67   * @author Cameron Braid
    68   * @author Ben Alex
    69   * @version $Id: MethodDefinitionAttributes.java,v 1.5 2005/11/17 00:56:09 benalex Exp $
    70   */
    71  public class MethodDefinitionAttributes extends AbstractMethodDefinitionSource {
    72      //~ Instance fields ========================================================
    73
    74      private Attributes attributes;
    75
    76      //~ Methods ================================================================
    77
    78      public void setAttributes(Attributes attributes) {
    79          this.attributes = attributes;
    80      }
    81
    82      public Iterator getConfigAttributeDefinitions() {
    83          return null;
    84      }
    85
    86      protected ConfigAttributeDefinition lookupAttributes(Method method) {
    87          ConfigAttributeDefinition definition = new ConfigAttributeDefinition();
    88
    89          Class interceptedClass = method.getDeclaringClass();
    90
    91          // add the class level attributes for the implementing class
    92          addClassAttributes(definition, interceptedClass);
    93
    94          // add the class level attributes for the implemented interfaces
    95          addClassAttributes(definition, interceptedClass.getInterfaces());
    96
    97          // add the method level attributes for the implemented method
    98          addMethodAttributes(definition, method);
    99
    100         // add the method level attributes for the implemented intreface methods
    101         addInterfaceMethodAttributes(definition, method);
    102
    103         if (definition.size() == 0) {
    104             return null;
    105         } else {
    106             return definition;
    107         }
    108     }
    109
    110     private void add(ConfigAttributeDefinition definition, Collection attribs) {
    111         for (Iterator iter = attribs.iterator(); iter.hasNext();) {
    112             Object o = (Object) iter.next();
    113
    114             if (o instanceof ConfigAttribute) {
    115                 definition.addConfigAttribute((ConfigAttribute) o);
    116             }
    117         }
    118     }
    119
    120     private void addClassAttributes(ConfigAttributeDefinition definition,
    121         Class clazz) {
    122         addClassAttributes(definition, new Class[] {clazz});
    123     }
    124
    125     private void addClassAttributes(ConfigAttributeDefinition definition,
    126         Class[] clazz) {
    127         for (int i = 0; i < clazz.length; i++) {
    128             Collection classAttributes = attributes.getAttributes(clazz[i]);
    129
    130             if (classAttributes != null) {
    131                 add(definition, classAttributes);
    132             }
    133         }
    134     }
    135
    136     private void addInterfaceMethodAttributes(
    137         ConfigAttributeDefinition definition, Method method) {
    138         Class[] interfaces = method.getDeclaringClass().getInterfaces();
    139
    140         for (int i = 0; i < interfaces.length; i++) {
    141             Class clazz = interfaces[i];
    142
    143             try {
    144                 Method m = clazz.getDeclaredMethod(method.getName(),
    145                         (Class[]) method.getParameterTypes());
    146                 addMethodAttributes(definition, m);
    147             } catch (Exception e) {
    148                 // this won't happen since we are getting a method from an interface that
    149                 // the declaring class implements
    150             }
    151         }
    152     }
    153
    154     private void addMethodAttributes(ConfigAttributeDefinition definition,
    155         Method method) {
    156         // add the method level attributes
    157         Collection methodAttributes = attributes.getAttributes(method);
    158
    159         if (methodAttributes != null) {
    160             add(definition, methodAttributes);
    161         }
    162     }
    163 }