001: /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
002: *
003: * Licensed under the Apache License, Version 2.0 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at
006: *
007: * http://www.apache.org/licenses/LICENSE-2.0
008: *
009: * Unless required by applicable law or agreed to in writing, software
010: * distributed under the License is distributed on an "AS IS" BASIS,
011: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: * See the License for the specific language governing permissions and
013: * limitations under the License.
014: */
015:
016: package org.acegisecurity.intercept.method;
017:
018: import org.acegisecurity.ConfigAttribute;
019: import org.acegisecurity.ConfigAttributeDefinition;
020:
021: import org.springframework.metadata.Attributes;
022:
023: import java.lang.reflect.Method;
024:
025: import java.util.Collection;
026: import java.util.Iterator;
027:
028: /**
029: * Stores a {@link ConfigAttributeDefinition} for each method signature defined by Commons Attributes.<P>This class
030: * will only detect those attributes which are defined for:
031: * <ul>
032: * <li>The class-wide attributes defined for the intercepted class.</li>
033: * <li>The class-wide attributes defined for interfaces explicitly implemented by the intercepted class.</li>
034: * <li>The method-specific attributes defined for the intercepted method of the intercepted class.</li>
035: * <li>The method-specific attributes defined by any explicitly implemented interface if that interface
036: * contains a method signature matching that of the intercepted method.</li>
037: * </ul>
038: * </p>
039: * <P>Note that attributes defined against parent classes (either for their methods or interfaces) are not
040: * detected. The attributes must be defined against an explicit method or interface on the intercepted class.</p>
041: * <p>Attributes detected that do not implement {@link ConfigAttribute} will be ignored.</p>
042: *
043: * @author Cameron Braid
044: * @author Ben Alex
045: * @version $Id: MethodDefinitionAttributes.java 1784 2007-02-24 21:00:24Z luke_t $
046: */
047: public class MethodDefinitionAttributes extends
048: AbstractMethodDefinitionSource {
049: //~ Instance fields ================================================================================================
050:
051: private Attributes attributes;
052:
053: //~ Methods ========================================================================================================
054:
055: private void add(ConfigAttributeDefinition definition,
056: Collection attribs) {
057: for (Iterator iter = attribs.iterator(); iter.hasNext();) {
058: Object o = (Object) iter.next();
059:
060: if (o instanceof ConfigAttribute) {
061: definition.addConfigAttribute((ConfigAttribute) o);
062: }
063: }
064: }
065:
066: private void addClassAttributes(
067: ConfigAttributeDefinition definition, Class clazz) {
068: addClassAttributes(definition, new Class[] { clazz });
069: }
070:
071: private void addClassAttributes(
072: ConfigAttributeDefinition definition, Class[] clazz) {
073: for (int i = 0; i < clazz.length; i++) {
074: Collection classAttributes = attributes
075: .getAttributes(clazz[i]);
076:
077: if (classAttributes != null) {
078: add(definition, classAttributes);
079: }
080: }
081: }
082:
083: private void addInterfaceMethodAttributes(
084: ConfigAttributeDefinition definition, Method method) {
085: Class[] interfaces = method.getDeclaringClass().getInterfaces();
086:
087: for (int i = 0; i < interfaces.length; i++) {
088: Class clazz = interfaces[i];
089:
090: try {
091: Method m = clazz.getDeclaredMethod(method.getName(),
092: (Class[]) method.getParameterTypes());
093: addMethodAttributes(definition, m);
094: } catch (Exception e) {
095: // this won't happen since we are getting a method from an interface that
096: // the declaring class implements
097: }
098: }
099: }
100:
101: private void addMethodAttributes(
102: ConfigAttributeDefinition definition, Method method) {
103: // add the method level attributes
104: Collection methodAttributes = attributes.getAttributes(method);
105:
106: if (methodAttributes != null) {
107: add(definition, methodAttributes);
108: }
109: }
110:
111: public Iterator getConfigAttributeDefinitions() {
112: return null;
113: }
114:
115: protected ConfigAttributeDefinition lookupAttributes(Method method) {
116: ConfigAttributeDefinition definition = new ConfigAttributeDefinition();
117:
118: Class interceptedClass = method.getDeclaringClass();
119:
120: // add the class level attributes for the implementing class
121: addClassAttributes(definition, interceptedClass);
122:
123: // add the class level attributes for the implemented interfaces
124: addClassAttributes(definition, interceptedClass.getInterfaces());
125:
126: // add the method level attributes for the implemented method
127: addMethodAttributes(definition, method);
128:
129: // add the method level attributes for the implemented intreface methods
130: addInterfaceMethodAttributes(definition, method);
131:
132: if (definition.size() == 0) {
133: return null;
134: } else {
135: return definition;
136: }
137: }
138:
139: public void setAttributes(Attributes attributes) {
140: this.attributes = attributes;
141: }
142: }
|