EAOP by Example

This document is intended to demonstrate the characteristics of EAOP compared to other AOP systems, usage of the EAOP tool and salient technical issues in the context of a small example. (A more detailed discussion of this example can be found in the following publication:
R. Douence, M. Südholt: "A model and a tool for Event-based Aspect-Oriented Programming (EAOP)", TR 02/11/INFO, École des mines de Nantes, french version accepted at LMO'03, 2nd edition, Dec. 2002.)

Overview of the example

We consider an e-commerce example consisting of a toy e-shop application whose functionality is to be extended by different kinds of discounts. (Note that we see aspects as general structuring mechanisms which can be useful to introduction of so-called functional aspects into a base application, e.g. to extend a legacy application with new functionality.) Four aspects are used:
  1. Aspect Bingo (in file Aspects.java, see below): an aspect defining a lottery-style discount intended to improve customer fidelity: each 1000th customer pays only half of its purchase.
  2. Aspect Sicount: an aspect for regular discounts (10%, say) which are applied each time the accumulated value of purchases of a given customer exceeds a certain threshold (100 euro, say).
  3. Aspect Profiling: allowing the shop manager to count the number of discounts granted.
  4. Aspect Checkout: an abstract aspect factoring out common functionality of the lottery and regular aspects.
The e-shop example (sources located in directory examples/javazon/src) is composed of the following files:

EAOP characteristics

EAOP has the following main characteristics which sets it apart from other AOP systems:
  1. Expressive crosscuts: Once execution points have been materialized in terms of events arbitrary relations between them can be denoted on the crosscut level.
  2. Explicit aspect composition: Aspects may be combined using a (extensible) set of aspect composition operators.
  3. Aspects of aspects: Aspects may be applied to other aspects.
  4. Dynamic aspect management: Aspects may be instantiated, composed and destroyed at runtime.

Expressive crosscuts

In order to illustrate expressive crosscuts, have a look at an excerpt of the code of the method definition of the aspect defining regular discounts (class Discount):
	while (true) {
	    Order o = nextShip(c);
	    accPurchases += o.total();
	    System.out.println("\taspect discount: accumulated purchases of " 
			       + c + " is " + accPurchases);
	    if (accPurchases > Discount.discountThreshold) {
		Event e2 = nextCheckout(c);
		System.out.print("\taspect discount: ");
		float discount = computeDiscount(Discount.discountRate, c);
		Set tmp = new HashSet();
		tmp.add(new Product("discount", -discount));
		c.shoppingCart.add(tmp);
		accPurchases -= Discount.discountThreshold;
	    }
	}

The aspect accumulates the purchases of the customer c. This accumulation is performed when an order of this client is shipped. The method nextShip takes the client reference c as a parameter and waits for a call to method Order.ship of the base application for the client c. When the accumulated purchases exceed a threshold, a discount will be applied the next time this client calls the method buy. So, a discount is applied by this aspect only if the pattern ship();...;buy() corresponding to a sequence of two base method calls is matched in a context where the accumulated purchase value exceeds the threshold.

This last point illustrates how to express crosscuts representing relations between events using our approach. An aspect definition may wait for sequences of events, extract contextual information from these events and use this information to perform an action.

Explicit aspect composition

For an example of aspect composition, have a look at the initialization of the monitor in the method main of class Test:
	Monitor.monitor.aspects = 
	    new Root(new Seq(new Profiling(), 
			     new Fst(new Bingo(3,25), 
				     new Discount())));
This initialization defines a sequential composition of two aspects (Profiling and another composition of Bingo and Discount ) such that discounts are profiled (operator Seq and always - i.e., in particular, if both discount aspects interact - at most one discount is applied profiling crosscuts are matched (the composition operator Fst tries to apply its first argument and only applies the second if the first has not been applied). This term demonstrates that aspect composition can be controlled programmatically. Furthermore, it exemplifies dynamic aspect instantiated (even though it occurs only at program start in this example).

Aspects of aspects

Profiling of discounts is an example of an aspect which is applied to other aspects. Have a look at the definition of the aspect Profiling, an excerpt of which is shown here:
	while (true) {
	    Event e = nextComputeDiscount();
	    this.isCrosscutting = true;
	    n++;
	    System.out.println("\taspect profile: " 
			       + "number of discounts and bingos = " + n);
	}
In the loop, events of calls to method computeDiscount are counted, a method which is defined in the abstract aspect Checkout and inherited by the Bingo an Discount aspects.

Dynamic instiantiation and deletion of aspects

While we have already seen an example of dynamic aspect creation at program start time, the Discount aspects provides a more interested example of dynamic instantiation of aspects. Let's have a another look at an excerpt of this aspect:
    public void definition() {
	Customer c = newCustomer();
	insert(new Discount());
	while (true) {
	    Order o = nextShip(c);
	    accPurchases += o.total();
	    System.out.println("\taspect discount: accumulated purchases of " 
			       + c + " is " + accPurchases);
	    if (accPurchases > Discount.discountThreshold) {
		Event e2 = nextCheckout(c);
		System.out.print("\taspect discount: ");
		float discount = computeDiscount(Discount.discountRate, c);
		Set tmp = new HashSet();
		tmp.add(new Product("discount", -discount));
		c.shoppingCart.add(tmp);
		accPurchases -= Discount.discountThreshold;
	    }
	}
    }
In order to express that discounts are applied on a per-customer basis, we use dynamic instantiation of aspects. In the body of method definition, we therefore wait for the next customer creation (newCustomer), dynamically create a new instance of the discount aspect and insert it into the tree representing the collection of aspects associated to the monitor. This new instance is then ready to manage the next (a.k.a. future) new customer.

Compilation and execution

The e-shop example can be executed using the makefile: make javazon or the ant build system ant javazon. This executes the following tasks (all executables are generated/executed in directory examples/javazon/exec): :
  1. Compile the class TestInstrumentation which defines which classes and/or methods are to be instrumented with events.
  2. Instrument the classes in files {Javazon,Aspects}.java with event-generating statements.
  3. Compile the java-files in the exec-directory.
  4. Execute Test.
The execution of the example yields some illstrative output, part of which is shown below:
    Welcome to www.javazon.com
    ...
    shipping p2 to c2
            aspect discount: accumulated purchases of c1 is 40.0
    shipping p1 to c1
            aspect profile: number of discounts and bingos = 2
    apply discount of 10% to c2
            aspect profile: number of discounts and bingos = 3
    apply discount of 25% (i.e.5.0) to c1
    ...
This demonstrates that the different discounts crosscuts the execution of the base program, the profiling aspect applies to the discounting aspects and that the profiling action is performed before discounting.

Technical issues

EAOP tool is based on some interesting technical issues:

EAOP, version 1.0, 19 December 2002.