The following project was completed by Reehan Shaikh in 2007. Eric Bodden and him published this work at the AOSD 2008 conference.
Implementing relational aspects using tracematches
Problem statement
There has been previous work on so-called relationship aspects or association aspects. A
relational aspect generally implements a n-ary relation between
multiple objects (not classes!). For example, consider the following
scenario of a source code versioning system.
The system allows for multiple user groups: programmers, code reviewers
and documentation people. The software that is to be developed in
different modules. Each module has its own group of programmers,
reviewers and documenters. The source code versioning system could now
implement the fiollowing business rules:
- Always, when a source file is checked in by a programmer p, then send a notification to a
code reviewer r working on
the same module as p.
- Always, when a code reviewer r
accepts a module written by p,
send this code on to a documenter d
for the same module.
- Always, when a code reviewer r
rejects a module written by p,
send this code back to p and
have him implement the proposed changes.
Implementing such associations in plain AspectJ is very tedious. Using
a relational aspect syntax, one could do something like the following:
VersionManagementAspect.associate(p,r,d);
This would associate the three people with each other in this relation.
The aspect could then for example implement rule 1 as follows:
VersionManagementAspect(Programmer p, Reviewer r, Documenter d) {
after(SourceChange s) returning:
call(* SourceChange.checkin()) && this(p)
&& target(s) {
r.sendChangeForReview(s);
}
...
}
The important detail is here that the advice that implements the
functionality will only be invoked when this points to p. At the same time, r can immediately be accessed from
within the advice.
Implementation via tracematches
Existing implementations of relational aspects are all either not very
flexible (e.g. one implementation based on AJ5 generics only allows for
binary relations) or they are slow. As a matter of fact, it is possible
to implement such aspects (in the backend) using tracematches.
In the example, one would have something like the following:
tracematch(Programmer p, Reviewer r, Documenter d, SourceChange s) {
sym associate after returning:
call(VersionManagementAspect.associate(..)) && args(p,r,d);
sym disassociate after returning:
call(VersionManagementAspect.disassociate(..)) && args(p,r,d);
sym action after returning:
call(* SourceChange.checkin()) && this(p) && target(s);
associate action { //if associate happened, followed by action (but no disassociate in between)
//here, all variables (p,r,d,s) can be used
r.sendChangeForReview(s);
}
}
This tracematch executes the body (blue) whenever "associate" is called
and then "checkin", on the same
objects (!). Trace matching is very efficiently implemented
within abc and we have many optimizations for it. Hence, this approach
would combine flexibility with efficiency.
Task
For this project, the student should develop an extension to the
tracematch implementation in abc which implements relational aspects by
reducing them to a tracematch. The student should...
- Derive a plausible syntax for relational aspects by applying them
mentally to several real-life examples.
- Implement this syntax and tyoe checking for it using the abc
frontend.
- Implement the intended semantics via a reduction to tracematches
in the abc backend (as AspectInfo).
If done properly, such a project could well lead to a publication at a
major conference like AOSD.
The project would be supervised by Eric Bodden.