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 }