Hi Johan: After reading your new terminology section in your thesis proposal, I started to write the following: I started to use your concern interaction terminology and it works well. AspectJ has a specific way to talk about the interaction points and you have a different way. How is your way better? Where is a precise definition of your interaction point language in English? How would the paper: Introduction to ACC from the Adaptive Programming Perspective look like? http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/check-with-AspectJ/aspectj-LoD.html will have an updated version of this paper. -- Karl
Introduction to AspectJ from the Adaptive Programming Perspective

We introduce AspectJ focussing on its adaptive programming capabilities
and we develop a highly adaptive AspectJ program that works with any
Java program. Adaptive Programming (AP) got started through the Law of Demeter (LoD),
AP influenced the AspectJ 
work and in this paper we close the loop and express the
Law of Demeter as an AspectJ program. We have the following 
relationships: LoD influenced AP; AP influenced AspectJ; in
this paper AspectJ is used
to formulate precisely the LoD as an adaptive program.
We formulate the
Object Form of the Law of Demeter
as an adaptive program.

AspectJ is a programming language from Xerox PARC developed
by Gregor Kiczales and his AspectJ team. AspectJ uses a language
feature, called pointcuts, to express interaction between concerns adaptively.
The pointcuts select the points where the interaction takes place.

A pointcut is formulated in terms of partial information about
a Java "base" program. A pointcut has two purposes: it defines a set
of constraints that the base program needs to satisfy and it selects
a set of points related to the base program that 
satisfy the constraints.

A pointcut is adaptive in that it works with an entire family
of base programs that satisfy the constraints expressed by the pointcut.
In AspectJ pointcuts may be formulated with various degrees of adaptiveness.

pointcut ce1(A a): this(a);
expresses the constraint that the base program has a class A 
and it defines the set of points where the currently executing
object is of class A.

// pce2
pointcut ce2(Object a): this(a);
expresses the constraint that the base program has a class Object
(every Java program has that!)
and it defines the set of points where the currently executing
object is of class Object (we capture all points).

ce2 is more adaptive than ce1 in that it works on a larger family
of base programs.

Pointcut ce2 works with any Java base program but it does 
not do any work for us. In AspectJ we can associate
code with a pointcut:

// afterpce2
after(Object a): ce2(a) {
  System.out.println("at " + a + "  " +
    thisJoinPoint.getSourceLocation().getFileName());
}

which prints something for each point selected by pointcut ce2.

The combination of pce2 and afterpce2 is an example of an adaptive program
that works with any Java base program.

This example demonstrates that AspectJ facilitates the formulation
of adaptive software. Adaptive software 
has the goal to separate concerns by minimizing dependencies
between the aspects (AP book 1996, page 78). This is achieved by using 
property-based specifications of sets rather than enumerating 
the sets element by element.
For example, the this pointcut is a property based specification
of a set of points namely all points where the currently executing
object is of some class.
As pointed out in (AP book 1996, page 79), adaptive software can
be realized in different ways and here we focus on the realization
in AspectJ.

A second useful pointcut is the target pointcut. The this pointcut
and the target pointcut combined can be used to talk about edges
in the dynamic call graph of the Java program.
In other words, we can talk about caller-callee relationships.

// pct2
pointcut ct2(Object a): target(a);
expresses the constraint that the base program has a class Object
(every Java program has that!)
and it defines the set of points where the current receiver
object is of class Object (we capture all points).

A useful pointcut is the call pointcut. For example,
call(void f(B)) talks about all points where a method called
f, returning void and with an argument of class B is called.

Pointcuts may be combined using the set operation && to take the intersection
of sets and the conjunction of constraints.

Consider now an interesting intersection of the three kinds of
pointcuts we introduced so far:

  pointcut callsite(Object caller, Object callee): this(caller) &&
	     target(callee) && call(* *(..));

The callsite pointcut is a very adaptive pointcut. It does not impose
constraints on the base program because any Java program uses
class Object. The pointcut selects all calls in the Java program
(irrespective of return type, method name and arguments) and it
makes the caller and callee available for each such point.
The pointcut is adaptive because both the this 
and the target pointcut are adaptive and because the call pointcut
uses the wildcard symbol * extensively not restricting the kind
of function that may be called.

AspectJ pointcuts are about expressing the interaction between 
concerns. In this paper we are interested in the following two
concerns:
(1) The composite concern expressed by the programmer in a Java program;
(2) The maintainability concern that is concerned about the programmer
overextending him or herself by having to think about too many
methods when studying a given method. The maintainability concern
crosscuts the Java program (representing a composite concern)
in that we need to reason about all method calls occurring in the
Java program.

AspectJ programs may be written in a structure-shy style. "structure-shy"
is here used as a synonym for "adaptive". Pointcut callsite is an example
of a structure-shy pointcut that is composed of three simpler
structure-shy pointcuts. AspectJ programs may be written in
a crosscutting style. Again pointcut callsite is an example
of a crosscutting pointcut that is composed of three simpler
crosscutting pointcuts: this, target and call.
The AspectJ literature typically talks about crosscutting
and plays down the fact that crosscutting and structure-shy are tightly linked.

AspectJ also supports the within pointcut which talks about all points
within some class or aspect. And we can use the complement operator
(negation from the constraint view) to combine pointcuts.
The pointcuts that we consider here live in an aspect 
(similar to a class) called Check and we don't want to
include points within Check. This is expressed by the following
pointcut:

  pointcut callsite(Object caller, Object callee): this(caller) &&
	     target(callee) && call(* *(..)) && !within(Check);

The callsite pointcut will be used in the LoD checker to verify
whether all the call sites satisfy the LoD, i.e., the callee object
must be of a restricted type.

One restricted type that is allowed by LoD is that we may send a message
to an immediate part of the current object.
AspectJ uses the set pointcut to talk about setting of immediate parts
of an object. We capture all those part-immediate-part relationships
in a hash table. Besides the set pointcut, we also need the args
pointcut.

  java.util.HashMap map=new java.util.HashMap();
  before (Object a, Object b): 
    set(* *.*) && 
    args(b) && this(a) && !within(Check)   {
        if(!map.containsKey(a))
           map.put(a,new java.util.Vector());
        java.util.Vector v = (java.util.Vector)map.get(a);
        v.add(b);
    }

To be continued
THE END

aspect Check {
  java.util.HashMap map=new java.util.HashMap();
  java.util.HashMap map2=new java.util.HashMap();
  java.util.HashMap global = new java.util.HashMap();
  java.util.Stack method_args = new java.util.Stack();

  pointcut callsite(Object caller,Object callee): this(caller) &&
           target(callee) && call(* *(..)) && !within(Check);

  pointcut inmethodbody(Object a): this(a) && withincode(* *.*(..)) && !within(Check) && call(*.new(..));


  after() returning (Object o): get(static * *.*) && !within(Check) {
          global.put(o,null);  
  }

  before(Object a,Object b): set(* *.*) && args(b) && this(a) && !within(Check)   {
        
        if(!map.containsKey(a))
           map.put(a,new java.util.Vector());

        java.util.Vector v = (java.util.Vector)map.get(a);
        v.add(b);
  }

  after(Object o) returning(Object a): inmethodbody(o) {
        if(!map2.containsKey(o))
            map2.put(o,new java.util.Vector());
        
        java.util.Vector v = (java.util.Vector)map2.get(o);

        v.add(a);
  }

  before(): execution(* *.*(..)) {
        method_args.push(thisJoinPoint.getArgs());
  }

  after(): execution(* *.*(..)) {
        method_args.pop();
  }

  after(Object caller,Object callee): callsite(caller,callee) {
 
        if(caller==callee || global.containsKey(callee))
            return;     

        Object[] arguments = (Object[])method_args.peek(); 

        for(int i=0; i< arguments.length; i++) {
           if(callee==arguments[i])
               return;
        } 
        if(map.containsKey(caller)) {
             java.util.Vector v = (java.util.Vector)map.get(caller);
             for(int i=0;i