Recipe12.2.Combining Pointcuts Using a Logical AND ()


Recipe 12.2. Combining Pointcuts Using a Logical AND (&&)

Problem

You want to combine some pointcut declarations, so advice is executed on a join point as long as all conditions within the pointcut declarations evaluate to true.

Solution

Use the && operator. The syntax of the && operator is:

pointcut <pointcut name>(<any values to be picked up>) :                          <pointcut declaration> && <pointcut declaration>

Discussion

Example 12-2 shows an example of the && operator combining the logic of two pointcuts into a single pointcut declaration.

Example 12-2. Using the && operator to combine two pointcuts
public aspect LogicalAndRecipe  {    /*            Specifies calling advice whenever a method             matching the following rules gets called:                        Class Name: MyClass            Method Name: Any Method            Method Return Type: Any Return Type            Method Parameters: Any Parameters    */    pointcut callAnyMethodOnMyClass( ) : call(* MyClass.* (..));    /*            Specifies calling advice whenever a method             matching the following rules gets called:                        Class Name: MyClass            Method Name: bar            Method Return Type: void            Method Parameters: None    */    pointcut callBarPointcut( ) : call(void MyClass.bar( ));    /*            Specifies calling advice whenever a join points is            encountered that would be picked by both pointcuts            specified:                        Pointcut name: callAnyMethodOnMyClass            Pointcut name: callBarPointcut            Method Return Type: void            Method Parameters: None    */    pointcut callIntersectionAnyAndBar( ) : callAnyMethodOnMyClass( )                            && callBarPointcut( );    // Advice declaration    before( ) : callAnyMethodOnMyClass( ) && !within(LogicalAndRecipe +)    {       System.out.println(          "------------------- Aspect Advice Logic --------------------");       System.out.println(          "In the advice picked by callAnyMethodOnMyClass");       System.out.println(          "Signature: " + thisJoinPoint.getSignature( ));       System.out.println(          "Source Line: " + thisJoinPoint.getSourceLocation( ));       System.out.println(          "------------------------------------------------------------");    }    // Advice declaration    before( ) : callBarPointcut( ) && !within(LogicalAndRecipe +)    {       System.out.println(          "------------------- Aspect Advice Logic --------------------");       System.out.println("In the advice picked by callBarPointcut");       System.out.println(          "Signature: " + thisJoinPoint.getSignature( ));       System.out.println(          "Source Line: " + thisJoinPoint.getSourceLocation( ));       System.out.println(          "------------------------------------------------------------");    }    // Advice declaration    before( ) : callIntersectionAnyAndBar( )       && !within(LogicalAndRecipe +)    {       System.out.println(          "------------------- Aspect Advice Logic --------------------");       System.out.println(          "In the advice picked by callIntersectionAnyAndBar");       System.out.println(          "Signature: " + thisJoinPoint.getSignature( ));       System.out.println(          "Source Line: " + thisJoinPoint.getSourceLocation( ));       System.out.println(          "------------------------------------------------------------");    } }

Most developers are familiar with the behavior of the && operator. However, for the newcomers, a mathematical explanation is that when two sets of things are combined using a logical AND, they combine to give the intersection of the two sets. Putting these mathematical terms into an AspectJ context, when two or more simple pointcuts are combined with the && operator into a compound pointcut, the join points that would be picked by both the individual pointcuts will trigger the compound pointcut's associated advice. More simply, if any one join point has been picked by either of the simple pointcuts, then it will not be picked by the overall compound pointcut.

The order of the pointcuts being combined using the && operator also has an effect on how the compound pointcut is interpreted. The runtime analysis of the && operators is executed from left to right. This means that as a candidate join point is examined, the first pointcut that indicates it would not include the join point is where the comparison stops. This is true for the && operator in Java and is especially useful when one of the comparisons in the combination must be protected by a previous condition, as shown in Example 12-3 (replicated from Recipe 9.1).

Example 12-3. Using the && operator ordering protecting later comparisons
 pointcut ifJoinPointThisHasUnRealisticSalaryPointcut( ) : if (     thisJoinPoint.getThis( ) instanceof MyClass  && ((MyClass) thisJoinPoint.getThis( )).getSalary( ) >= realisticSalary)  && !withincode(long MyClass.getSalary( ));

In this example, the first condition states that the this reference must be an instance of MyClass to continue with the evaluation of the rest of the statement. This protects the call in the next part of the statement, which casts the this reference to MyClass. If the first condition fails, then the second will never be reached; because of this behavior, the && operator is sometimes called a short-circuit operator.

See Also

Recipe 12.1 describes the if(Expression) pointcut; the within(TypePattern) pointcut is described in Recipe 9.1; the NOT(!) operator is described in Recipe 12.4; Chapter 13 describes the different types of advice available in AspectJ.



AspectJ Cookbook
Aspectj Cookbook
ISBN: 0596006543
EAN: 2147483647
Year: 2006
Pages: 203
Authors: Russ Miles

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net