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 }