View Javadoc

1   /* Copyright 2004 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.ConfigAttributeDefinition;
19  
20  import org.aopalliance.intercept.MethodInvocation;
21  
22  import org.apache.commons.logging.Log;
23  import org.apache.commons.logging.LogFactory;
24  
25  import org.aspectj.lang.JoinPoint;
26  import org.aspectj.lang.reflect.CodeSignature;
27  import org.springframework.util.Assert;
28  
29  import java.lang.reflect.Method;
30  
31  
32  /***
33   * Abstract implementation of <Code>MethodDefinitionSource</code>.
34   *
35   * @author Ben Alex
36   * @version $Id: AbstractMethodDefinitionSource.java,v 1.5 2005/11/17 00:56:09 benalex Exp $
37   */
38  public abstract class AbstractMethodDefinitionSource
39      implements MethodDefinitionSource {
40      //~ Static fields/initializers =============================================
41  
42      private static final Log logger = LogFactory.getLog(AbstractMethodDefinitionSource.class);
43  
44      //~ Methods ================================================================
45  
46      public ConfigAttributeDefinition getAttributes(Object object)
47          throws IllegalArgumentException {
48          Assert.notNull(object, "Object cannot be null");
49  
50          if (object instanceof MethodInvocation) {
51              return this.lookupAttributes(((MethodInvocation) object).getMethod());
52          }
53  
54          if (object instanceof JoinPoint) {
55              JoinPoint jp = (JoinPoint) object;
56              Class targetClazz = jp.getTarget().getClass();
57              String targetMethodName = jp.getStaticPart().getSignature().getName();
58              Class[] types = ((CodeSignature) jp.getStaticPart().getSignature())
59                      .getParameterTypes();
60  
61              if (logger.isDebugEnabled()) {
62                  logger.debug("Target Class: " + targetClazz);
63                  logger.debug("Target Method Name: " + targetMethodName);
64  
65                  for (int i = 0; i < types.length; i++) {
66                      if (logger.isDebugEnabled()) {
67                          logger.debug("Target Method Arg #" + i + ": "
68                                  + types[i]);
69                      }
70                  }
71              }
72  
73              try {
74                  return this.lookupAttributes(targetClazz.getMethod(targetMethodName, types));
75              } catch (NoSuchMethodException nsme) {
76                  throw new IllegalArgumentException("Could not obtain target method from JoinPoint: " + jp);
77              }
78          }
79  
80          throw new IllegalArgumentException("Object must be a MethodInvocation or JoinPoint");
81      }
82  
83      public boolean supports(Class clazz) {
84          return (MethodInvocation.class.isAssignableFrom(clazz)
85          || JoinPoint.class.isAssignableFrom(clazz));
86      }
87  
88      /***
89       * Performs the actual lookup of the relevant
90       * <code>ConfigAttributeDefinition</code> for the specified
91       * <code>Method</code> which is subject of the method invocation.
92       * 
93       * <P>
94       * Provided so subclasses need only to provide one basic method to properly
95       * interface with the <code>MethodDefinitionSource</code>.
96       * </p>
97       * 
98       * <p>
99       * Returns <code>null</code> if there are no matching attributes for the
100      * method.
101      * </p>
102      *
103      * @param method the method being invoked for which configuration
104      *        attributes should be looked up
105      *
106      * @return the <code>ConfigAttributeDefinition</code> that applies to the
107      *         specified <code>Method</code>
108      */
109     protected abstract ConfigAttributeDefinition lookupAttributes(Method method);
110 }