// difference between call and execution class Speaker { void f(){System.out.println("speaker");} } class Lecturer extends Speaker { void f(){System.out.println("lecturer");}} class ArrogantLecturer extends Lecturer { void f(){System.out.println("arrogant lecturer");}} aspect ExecutionDifference { /* why is execution not shown if this comment is removed void around() : call(void f()) { System.out.println(thisJoinPoint.toLongString()); System.out.println(thisJoinPoint.getKind()); System.out.println("Target = " + thisJoinPoint.getTarget()); System.out.println(thisJoinPoint.getThis()); } */ void around() : execution(void f()) { System.out.println(" around() : execution(void f())"); System.out.println(thisJoinPoint.toLongString()); System.out.println(thisJoinPoint.getKind()); System.out.println("Target = " + thisJoinPoint.getTarget()); System.out.println(thisJoinPoint.getThis()); System.out.println("line = " + thisJoinPoint.getSourceLocation().getLine()); } } aspect MainBehavior { // (define-msg say) void Speaker.say(Object stuff) { } // (define-method say ((arrogant-lecturer? x) stuff) ...) // This has to come first so that it takes precedence when it // overlaps with the next around advice! void around(ArrogantLecturer x, Object stuff) : call(* say(*)) && target(x) && args(stuff) { System.out.println(" around(ArrogantLecturer x, Object stuff)"); System.out.println(thisJoinPoint.toLongString()); System.out.println(thisJoinPoint.getKind()); System.out.println("Target = " + thisJoinPoint.getTarget()); System.out.println(thisJoinPoint.getThis()); // System.out.println(thisJoinPoint.getSourceLocation().getLine()); proceed(x, "it is obvious that " + stuff); } // (define-method say ((speaker? x) stuff) ...) void around(Speaker x, Object stuff) : call(* say(*)) && target(x) && args(stuff) { System.out.println(" around(Speaker x, Object stuff)"); System.out.println(thisJoinPoint.toLongString()); System.out.println(thisJoinPoint.getKind()); System.out.println("Target = " + thisJoinPoint.getTarget()); System.out.println(thisJoinPoint.getThis()); // System.out.println(thisJoinPoint.getSourceLocation().getLine()); System.out.println(stuff); } // (define-msg lecture) void Lecturer.lecture(Object stuff) { } // (define-method lecture ((lecturer? x) stuff) ...) void around(Lecturer x, Object stuff) : call(* lecture(*)) && target(x) && args(stuff) { x.say(stuff); x.say("you should be taking notes"); } } public class Main { public static void main(String args[]) { Speaker George = new Speaker(); George.say("the sky is blue"); System.out.println("----------- done Speaker George.say"); George.f(); Lecturer Gerry = new Lecturer(); Gerry.say("the sky is blue"); System.out.println("----------- done Lecturer Gerry.say"); Speaker s = Gerry; System.out.println("difference???"); s.f(); Gerry.lecture("the sky is blue"); System.out.println("----------- done Lecturer Gerry.lecture"); ArrogantLecturer Albert = new ArrogantLecturer(); Albert.say("the sky is blue"); System.out.println("----------- done ArrogantLecturer Albert.say"); Albert.lecture("the sky is blue"); System.out.println("----------- done ArroganLecturer Albert.lecture"); } } /* output: the sky is blue ----------- done Speaker George.say the sky is blue ----------- done Lecturer Gerry.say the sky is blue you should be taking notes ----------- done Lecturer Gerry.lecture it is obvious that the sky is blue ----------- done ArrogantLecturer Albert.say it is obvious that the sky is blue it is obvious that you should be taking notes ----------- done ArroganLecturer Albert.lecture */