Source code: org/acegisecurity/intercept/method/MethodDefinitionAttributes.java
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 }