Join point interfaces (JPIs) are contracts between aspects and advised code. JPIs support a programming methodology where aspects only specify the types of join points they advise based on a JPI, not on concrete pointcuts. JPI definition looks like a method signature (except for the extends clause, used for join point subtyping). It has return type, name, arguments and checked exceptions.

Motivation

In order to validate our first proposal of Join Point Interfaces, we migrate two applications: AJHotDraw and LawOfDemeter. AJHotDraw uses aspects to implement commands functionality such as: UndoCommand, PasteCommand, among others. LawOfDemeter uses aspects to capture every single activity that occurs in the base code, such as: Method call, field write, object initialization, among others.

In the migration of AJHotDraw, we detect the necessity to have a mechanism that allows to have JPI definitions with the same name but with different parameter types. An extract of AJHotDraw JPI definitions are shown below:

...
jpi void CommandExecuteInitUndo_AlignCommandUndo(AlignCommand ac);
jpi void CommandExecuteInitUndo_BringToFrontCommandUndo(BringToFrontCommand ac);
jpi void CommandExecuteInitUndo_ChangeAttributeCommandUndo(ChangeAttributeCommand ac); 
jpi void CommandExecuteInitUndo_CutCommandUndo(CutCommand ac); 
jpi void CommandExecuteInitUndo_DeleteCommandUndo(DeleteCommand ac); 
jpi void CommandExecuteInitUndo_DuplicateCommandUndo(DuplicateCommand ac);
jpi void CommandExecuteInitUndo_GroupCommandUndo(GroupCommand ac);
jpi void CommandExecuteInitUndo_GroupFigures(Figure figure);
jpi void CommandExecuteInitUndo_PasteCommandUndo(PasteCommand ac);
...

As you might see, in absence of such mechanism programmers must define JPIs with a special suffix on their names. We think that fact is at least awkward when the number of JPI definitions are increased. In fact, in AJHotDraw 32% (8 of 25) of JPI definitions will be favored with this feature.

Solution

We propose to use static overloading in order to use the same symbol (name) to represents different JPI definitions. With this feature we can define JPI definitions with the same name but with different parameter types. Notice that each JPI definition will represent a different kind of join point. We can write now the JPI definitions above in the following manner:

...
jpi void CommandExecuteInitUndo(AlignCommand ac);
jpi void CommandExecuteInitUndo(BringToFrontCommand ac);
jpi void CommandExecuteInitUndo(ChangeAttributeCommand ac); 
jpi void CommandExecuteInitUndo(CutCommand ac); 
jpi void CommandExecuteInitUndo(DeleteCommand ac); 
jpi void CommandExecuteInitUndo(DuplicateCommand ac);
jpi void CommandExecuteInitUndo(GroupCommand ac);
jpi void CommandExecuteInitUndo(Figure figure);
jpi void CommandExecuteInitUndo(PasteCommand ac);
...

Implementation

To implement static overloading in JPI definition we will introduce the concept of jpi-signature. A jpi-signature is the name and types of formal arguments of a JPI definition. Return type and checked exceptions are out of this definition. For example:

jpi void CommandExecuteInitUndo(Figure figure) throws IOException

The jpi-signature for the above JPI definition is CommandExecuteInitUndo(Figure).

Also, we need to modify our compiler extension in the following ways:

  • JPITypeDecl
    • nameCheck : It will compare jpi-signatures to detect duplicate JPI definitions.
    • typeCheck : It will need do additional checks in the jpi parent definition (extends).
  • CJPAdviceDecl
    • PointcutCombination : It will need to select the correct JPITypeDecl in order to calculate PointcutPolymorphism and PointcutOverriding properly.
  • ExhibitClause
    • typeCheck : It will need to select the correct JPITypeDecl in order to typecheck properly the exhibit signature.