## Caller pointcuts

#### Callers

Execution pointcuts on methods and constructors are very useful, but limiting some times. For instance, what if you don't want a method to be intercepted once you are within the method's class? Another problem is that JBoss AOP does not allow you to have an execution pointcut applied to any Java system classes. This is where caller pointcuts come in. Executions are invoked whenever the method is called within the method itself. Callers are invoked at the point of the calling code. Callers allow you to specify what method in what class calls whatever method. Confused? Here's some examples from jboss-aop.xml.

       <bind pointcut="call(int java.util.ArrayList->size()) AND withincode(void Driver->caller())">
              <interceptor class="CallerInterceptor1"/>
       </bind>

Whenever `ArrayList.size()` method is called from within the `Driver.caller()` method, invoke `CallerInterceptor1`. You see? You can specify the point of interception from within the caller's code. You can also use boolean expressions to specify your within:

       <bind pointcut="call(int java.util.ArrayList->size()) AND withincode(* Driver->*(..)) AND !withincode(void Driver->caller())">
           <interceptor class="CallerInterceptor2"/>
       </bind>

This binding states to invoke `CallerInterceptor2` whenever `ArrayList.size()` is called from within any `Driver` class method, but not from within `Driver.caller()`.

       <bind pointcut="call(java.util.ArrayList->new()) AND within(Driver)">
           <interceptor class="CallerInterceptor1"/>
       </bind>

This binding is a little different in that it uses the within keyword rather than the withincode keyword. Within matches anything within an entire class. So the above pointcut states, whenever the ArrayList empty constructor is called from within any method or constructor of the Driver class.

#### Running

To compile and run:

      $ ant

It will javac the files and then run the AOPC precompiler to manipulate the bytecode, then finally run the example. The output should read as follows:

    run:
         [java] --- main is calling new ArrayList(); ---
         [java] <<< Entering CallerInterceptor1
         [java] >>> Leaving CallerInterceptor1
         [java] --- main is calling list.size(); ---
         [java] <<< Entering CallerInterceptor2
         [java] >>> Leaving CallerInterceptor2
         [java] --- caller is calling new ArrayList(); ---
         [java] <<< Entering CallerInterceptor1
         [java] >>> Leaving CallerInterceptor1
         [java] --- caller is calling list.size(); ---
         [java] <<< Entering CallerInterceptor1
         [java] >>> Leaving CallerInterceptor1
         [java] --- anotherCaller is calling new ArrayList(); ---
         [java] <<< Entering CallerInterceptor1
         [java] >>> Leaving CallerInterceptor1
         [java] --- anotherCaller is calling list.size(); ---
         [java] <<< Entering CallerInterceptor2
         [java] >>> Leaving CallerInterceptor2