Introduction

Java is an object-oriented programming language developed by Sun Microsystems that has proven itself in numerous projects. The Java Platform is hardware and operating system independent and comes in three editions: Micro Edition for PDAs and cell phones; Standard Edition for computer programs; and Enterprise Edition for distributed, transactional, and portable applications.

Saturday, May 8th, 2004 at 9:37 pm

AOP: Passing Context

One thing I haven’t talked about yet is passing context from a join point to an advice. An advice often needs certain information about the join point. For example the arguments passed to the join point, the class the join point is declared in and so on. All this information is called context. There do exist special pointcuts to capture these context. ApsectJ provides the following: this(), target() and args(). Let’s directly step into it:

We have a package called org.swacker.geom. In this package are by now two classes, Rectangle and Circle. These two classes implement the interface Shape. This interface declares one method: fill(newColor:Color). What we want to do is logging the calls to any class implementing this interface and printing out the name of this class as well as the new color the shape shall be filled with. Our final ouput shall look like this:

  1. About to fill a ‘org.swacker.geom.Rectangle’ instance with the color ‘#000000′.

To achieve this we somehow must get down to the target of the call as well as the arguments passed to the method. What we need is the target() and args() pointcut. We have everything we need now. Thus let’s start coding:

  1. public aspect ShapeAspect {
  2.   before(Shape shape, Color color) :
  3.       call(void Shape+.fill(Color))
  4.       && target(shape)
  5.       && args(color) {
  6.     System.out.println("About to fill a ‘" + shape.getClass().getName() + "’ instance with the color ‘" + color + "’.");
  7.   }
  8. }

We’ll now walk through this step by step.
We have an advice specification: before(Shape shape, Color color). It’s a before advice that collects some context. An instance of type Shape and another of type Color. What we also have are three pointcuts that are connected by && operators. We firstly capture all calls to the method fill() that is implemented in the class Shape or any of its subclass: call(void Shape+.fill(Color)).
Then we say that the target of the call shall be mapped to the context named shape in the advice specification: target(shape).
What we also do is taking the first argument of the method call and say that it shall me mapped to the context named color. This mapping will now be done automatically and we can use the context to build our output: System.out.println(”About to fill a ‘” + shape.getClass().getName() + “‘ instance with the color ‘” + color + “‘.”);.

When we now write a little test which body looks similar to this:

  1. Rectangle r = new Rectangle();
  2. r.fill(new Color(#000000));
  3. Circle c = new Circle();
  4. c.fill(new Color(#0000FF));

and compile the whole thing together with the aspect ShapeAspect we will get the following output:

  1. About to fill a ‘org.swacker.geom.Rectangle’ instance with the color ‘#000000′.
  2. About to fill a ‘org.swacker.geom.Circle’ instance with the color ‘#0000FF’.