The Spring Framework

org.springframework.aop.aspectj
Class AspectJAdviceParameterNameDiscoverer

java.lang.Object
  extended by org.springframework.aop.aspectj.AspectJAdviceParameterNameDiscoverer
All Implemented Interfaces:
ParameterNameDiscoverer

public class AspectJAdviceParameterNameDiscoverer
extends Object
implements ParameterNameDiscoverer

Implementation of ParameterNameDiscover that tries to deduce parameter names for an advice method from the pointcut expression, returning, and throwing clauses. If an unambiguous interpretation is not avaliable, it will return null.

This class interprets arguments in the following way:

  1. If the first parameter of the method is of type JoinPoint or ProceedingJoinPoint, it is assumed to be for passing thisJoinPoint to the advice, and the parameter name will be assigned the value "thisJoinPoint".
  2. If the first parameter of the method is of type JoinPoint.StaticPart it is assumed to be for passing "thisJoinPointStaticPart" to the advice, and the parameter name will be assigned the value "thisJoinPointStaticPart"
  3. If a throwingName has been set, and there are no unbound arguments of type Throwable+, then an IllegalArgumentCondition is raised. If there is more than one unbound argument of type Throwable+, then an AmbiguousBindingCondition is raised. If there is exactly one unbound argument of type Throwable+, then the corresponding parameter name is assigned the value <throwingName>.
  4. If there remain unbound arguments, then the pointcut expression is examined. Let a be the number of annotation-based pointcut expressions (@annotation, @this, @target, @args, @within, @withincode) that are used in binding form. Usage in binding form has itself to be deduced: if the expression inside the pointcut is a single string literal that meets Java variable name conventions it is assumed to be a variable name. If a is zero we proceed to the next stage. If a > 1 then an AmbiguousBindingCondition is raised. If a == 1, and there are no unbound arguments of type Annotation+, then an IllegalArgumentCondition is raised. if there is exactly one such argument, then the corresponding parameter name is assigned the value from the pointcut expression.
  5. If a returningName has been set, and there are no unbound arguments then an IllegalArgumentCondition is raised. If there is more than one unbound argument then an AmbiguousBindingCondition is raised. If there is exactly one unbound argument then the corresponding parameter name is assigned the value <returningName>.
  6. If there remain unbound arguments, then the pointcut expression is examined once more for this, target, and args pointcut expressions used in the binding form (binding forms are deduced as described for the annotation based pointcuts). If there remains more than one unbound argument of a primitive type (which can only be bound in args) then an AmbiguousBindingCondition is raised. If there is exactly one argument of a primitive type, then if exactly one args bound variable was found, we assign the corresponding parameter name the variable name. If there were no args bound variables found an IllegalStateCondition is raised. If there are multiple args bound variables, an AmbiguousBindingCondition is raised. At this point, if there remains more than one unbound argument we raise an AmbiguousBindingCondition. If there are no unbound arguments remaining, we are done. If there is exactly one unbound argument remaining, and only one candidate variable name unbound from this, target, or args, it is assigned as the corresponding parameter name. If there are multiple possibilities, an AmbiguousBindingCondition is raised.

The behaviour on raising an IllegalArgumentCondition or AmbiguousBindingConfiguration is configurable to allow this discoverer to be used as part of a chain-of-responsibility. By default the condition will be logged and the getParameterNames method will simply return null. If the raiseExceptions property is set to true, the conditions will be thrown as IllegalArgumentException and AmbiguousBindingException respectively.

Was that perfectly clear?? ;)

Short version: if an unambiguous binding can be deduced, then it is. If the advice requirements cannot possibly be satisfied null is returned. By setting the raiseExceptions property to true, more descriptive exceptions will be thrown instead of returning null in the case that the parameter names cannot be discovered.

Since:
2.0
Author:
Adrian Colyer

Nested Class Summary
static class AspectJAdviceParameterNameDiscoverer.AmbiguousBindingException
           
 
Constructor Summary
AspectJAdviceParameterNameDiscoverer(String pointcutExpression)
          Create a new discoverer that attempts to discover parameter names from the given pointcut expression.
 
Method Summary
 String[] getParameterNames(Constructor ctor)
          An advice method can never be a constructor.
 String[] getParameterNames(Method method)
           Deduce the parameter names for an advice method.
 void setRaiseExceptions(boolean shouldRaise)
           Set this property to true to indicate the IllegalArgumentException and AmbiguousBindingException should be thrown as appropriate in the case of failing to deduce advice parameter names.
 void setReturningName(String returningName)
          If afterReturning advice binds the return value, the returning variable name must be specified.
 void setThrowingName(String throwingName)
          If afterThrowing advice binds the thrown value, the throwing variable name must be specified.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

AspectJAdviceParameterNameDiscoverer

public AspectJAdviceParameterNameDiscoverer(String pointcutExpression)
Create a new discoverer that attempts to discover parameter names from the given pointcut expression.

Parameters:
pointcutExpression -
Method Detail

setRaiseExceptions

public void setRaiseExceptions(boolean shouldRaise)

Set this property to true to indicate the IllegalArgumentException and AmbiguousBindingException should be thrown as appropriate in the case of failing to deduce advice parameter names.

Parameters:
shouldRaise -

setReturningName

public void setReturningName(String returningName)
If afterReturning advice binds the return value, the returning variable name must be specified.

Parameters:
returningName -

setThrowingName

public void setThrowingName(String throwingName)
If afterThrowing advice binds the thrown value, the throwing variable name must be specified.

Parameters:
throwingName -

getParameterNames

public String[] getParameterNames(Method method)

Deduce the parameter names for an advice method. See the javadoc comment for this class for details of the algorithm used.

Specified by:
getParameterNames in interface ParameterNameDiscoverer
Parameters:
method - method to find parameter names for
Returns:
an array of parameter names if the names can be resolved, or null if they cannot

getParameterNames

public String[] getParameterNames(Constructor ctor)
An advice method can never be a constructor.

Specified by:
getParameterNames in interface ParameterNameDiscoverer
Parameters:
ctor - constructor to find parameter names for
Returns:
null
Throws:
UnsupportedOperationException - iff raiseExceptions has been set to true

The Spring Framework

Copyright © 2002-2006 The Spring Framework.