View Javadoc

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