200 likes | 390 Views
Aspect-Oriented Software Development (AOSD) Tutorial #3. AspectJ - continued. Today: AspectJ - Continued. Additional pointcut types cflow cflowbelow Intertype declarations Compilation errors declarations Examples English – AspectJ phrase book (selected entries).
E N D
Aspect-Oriented Software Development (AOSD)Tutorial #3 AspectJ - continued
Today: AspectJ - Continued • Additional pointcut types • cflow • cflowbelow • Intertype declarations • Compilation errors declarations • Examples • English – AspectJ phrase book (selected entries) Aspect-Oriented Software Development (236608)
Task 1: Greeting before printing Public class Test { public static void main(String[] args) { f(); } static void f() { g(); } static void g() { System.out.println(“message from g”); } } Task: Before each printing operation, print a greeting message Aspect-Oriented Software Development (236608)
English – AspectJ Phrase Book (3) • “All the exceptions thrown by f()” pointcut exceptF(): withincode(void Test.f()); after() throwing : exceptF() { …} • “All the exceptions thrown while f() is executed:” pointcut exceptF2(): cflow(call(void Test.f())); after() throwing : exceptF2() { …} Aspect-Oriented Software Development (236608)
English – AspectJ Phrase Book (4) • “All the exceptions thrown by functions of class Test” pointcut exceptTest(): within (Test); after() throwing : exceptTest() { …} • What is the relationship between: (1) pointcut except1(): cflow(call(void Test.g())); (2) pointcut except2(): cflowbelow(call(void Test.f())); Equality! Aspect-Oriented Software Development (236608)
Task 1: Proposed solution-1 matched by printPC pointcut! public aspect Printing { pointcut fPC(): execution(void Test.f()); pointcut gPC(): execution(void Test.g()); pointcut printPC(): call(void java.io.PrintStream.println(String)); before(): cflow(fPC()) && cflow(gPC()) && printPC() { System.out.println("hello"); } before(): cflow(fPC() && gPC()) && printPC() { System.out.println("shalom"); } } matched by printPC pointcut! Aspect-Oriented Software Development (236608)
Task 1: Proposed solution-2 Output: hello message from g public aspect Printing { pointcut fPC(): execution(void Test.f()); pointcut gPC(): execution(void Test.g()); pointcut printPC(): call(void java.io.PrintStream.println(String)); before(): cflow(fPC()) && cflow(gPC()) && printPC() && !within(Printing) { System.out.println("hello"); } before(): cflow(fPC() && gPC()) && printPC() && !within(Printing) { System.out.println("shalom"); } } can not be matched! (f() and g() have no common join-points) Aspect-Oriented Software Development (236608)
Cflow Pointcuts Combination P cflow(P) Q cflow(Q) cflow(P) && cflow(Q) P && Q cflow(P && Q) Aspect-Oriented Software Development (236608)
Example Class: Point - reminder class Point { private int x, y; public Point(int x, int y) { this.x = x; this.y = y; } public void setX(int x) { this.x = x; } public void setY(int y) { this.y = y; } public void MoveTo(Point p) {setX(p.x); setY(p.y); } public int getX() { return x; } public int getY() { return y; } } Aspect-Oriented Software Development (236608)
Task 2: Named Points Task2: Every point should have a name, and each time the point is moved, the user should get a message with the name of the point and its new coordinates. • Pontcut = ? pointcut moved(Point pt): target(pt) && (call(void setX(int)) || call(void setY(int))); Aspect-Oriented Software Development (236608)
Task 2 – contd. inter-type declarations • Advice = ? • Add the “name” field to Point // Inside the aspect body! private String Point.name = ""; public String Point.getName() {return name;} public void Point.setName(String newName) {name = newName;} • Who can access the “name” field = ? Only the aspect! (private field of the aspect) • Who can access getName(), setName()? Everybody! (public access) Aspect-Oriented Software Development (236608)
Task 2 – version2. • Another way to add the “name” field to Point • Assume there is a class NamedObject in a base system: public class NamedObject { private String name; … public NamedObject() {this.name = "";} … public void setName(String newName) {this.name = newName;} public String getName() {return this.name;} } • Add to the aspect: declare parents: Point extends NamedObject; Aspect-Oriented Software Development (236608)
Task 2 – contd. • Advice = ? – contd. • Advice type = ? after returning The advice: after(Point pt) returning: moved (pt) { System.out.println("Point "+pt.getName()+" moved to ("+pt.getX()+","+pt.getY()+")"); } Aspect-Oriented Software Development (236608)
Task 2 – contd. • Is that enough to add the name? • Theoretically, yes. But we’d better have some initialization • For example: When point number “i” is created, give it the name “Pointi” • How? – Task 2-A • “around” constructor calls • generate the needed name • set the generated value to the name field Aspect-Oriented Software Development (236608)
Task 2-A • Pointcut = ? (reminder) pointcut createPoint(int x, int y): args(x,y) && call(Point.new(..)); • Advice = ? Point around(int x, int y): createPoint(x,y){ Point newPoint = proceed(x,y); … //generate name newPoint.setName(…); //update the “name” field return newPoint; } Aspect-Oriented Software Development (236608)
Task 2-A – contd. • Name generation: • - add points counter to the aspect! private int pointsCounter = 0; • Advice as a whole: Point around(int x, int y): createPoint(x,y){ Point newPoint = proceed(x,y); return newPoint; } pointsCounter ++; newPoint.setName("Point"+pointsCounter); Aspect-Oriented Software Development (236608)
Task 3: Contract Enforcement Example • Constraint : only the factory methods can add an element to the registry of figure elements. • Meaning: ensures that no figure element is added to the registry more than once. • Implementation: Not an elegant solution! Can be solved at compilation time, and not at runtime aspect RegistrationProtection { pointcut register(): call(void Registry.register(FigureElement)); pointcut canRegister(): withincode(static *FigureElement.make*(..)); before(): register() && !canRegister() { throw new IllegalAccessException("Illegal call " + thisJoinPoint); } } Aspect-Oriented Software Development (236608)
More to Inter-type Declarations Attention! Only static information will be used at the join-points! • New powerful types of compilation warnings and errors! • Syntax: For example, to identify method calls that should not exist in a correct program declare error: Pointcut: String; declare warning: Pointcut: String; • For the contract enforcement example: aspect RegistrationProtection{ pointcut register(): call(void Registry.register(FigureElement)); pointcut canRegister(): withincode(static *FigureElement.make*(..)); } declare error: register() && !canRegister(): "Illegal call" Aspect-Oriented Software Development (236608)
More to AspectJ: Subtypes at pointcuts Example base classes: public class NamedObject { …} public class NamedFigure extends NamedObject { …} Example aspect: public aspect NamedObjectsObserver { …} Aspect-Oriented Software Development (236608)
Subtypes at pointcuts – contd. class public aspect NamedObjectsObserver { //matches calls to functions ofNamedObject only pointcut publicCalled1(): call(public * NamedObject.*(..)); //matches calls to functions ofNamedObject and of NamedFigure pointcut publicCalled2(): call(public * NamedObject+.*(..)); //matches calls to functions ofNamedFigure only pointcut publicCalled3(): call(public * (NamedObject+ && !NamedObject).*(..)); after() : publicCalled1() { System.out.println("Public (1)"+thisJoinPoint); } after() : publicCalled2() { System.out.println("Public (2)"+thisJoinPoint); } after() : publicCalled3() { System.out.println("Public (3)"+thisJoinPoint); } } Aspect-Oriented Software Development (236608)