/* AOP solution to invariance aspect */ aspect invariance { // advice code to throw an error upon bad input before(int n) : (call(int base.fib(..)) || call(int base.fact(..))) && args(n,..) { if (n<0) { System.out.println("bad input "+n); System.exit(1); } } boolean around(int b) : call(boolean base.divisible(..)) && args(int,b) { return (b!=0) && proceed(b); } int around(int ax) : call(int base.fact(int,int)) && args(int,ax) && !withincode(int base.fact(int,int)) { return proceed(1); // note 1 arg to proceed, not 2. } } //invariance /* A "join point" is everywhere in the program where something "interesting" with respect to a certain aspect is happening. In other words, they represent points in the program where different concerns "crosscut". Here, the join points are right before either fib or fact is called, and when divisible is called with a boolean value expected. These joinpoints are identified using AspectJ's language of "pointcuts". The first before advice can be said to "crosscut" multiple sections of the base program, as it applies both to the calling of fib and fact The advice code is "weaved" into the execution of the program at the join points identified by the pointcuts predicating each advice Finally, the "concern" of invariance has been modularly seperated from the rest of the program (though the oop code may also be able to claim this for this small example). However, this invariance aspect is more loosely coupled from the rest of the program. Its use is entirely optional. Use it by compile it together with any program that uses the base class: ajc mathfuns.java invariance.java */