How to define dot abbreviations for a sequence of method (s)?
For example, if I have 3 classes,
class A {
public void doA() {
/* do something */
}
}
class B {
public void doB() {
A a = new A();
a.doA();
}
}
class MyClass {
public static void main(String args[]) {
B b = new B();
b.doB();
}
}
Now I want to define a point abbreviation for the stream doB () -> doA (), for example if doB () calls doA (), grabs parameters from class A and class B and does something in the aspect. Can anyone help me.
source to share
Let me expand your example code a bit so that you understand what my solution does and what it cannot do:
class A {
public void doA() {}
}
class B {
public void doB() {
new A().doA();
new C().doC();
}
}
class C {
public void doC() {
new A().doA();
}
}
class MyClass {
public static void main(String args[]) {
new A().doA(); // should not be captured
new B().doB(); // should be captured
}
}
As you can see, there is now a new class C
and we now have three control flows:
-
MyClass.main -> A.doA
-
MyClass.main -> B.doB -> A.doA
-
MyClass.main -> B.doB -> C.doC -> A.doA
You want to eliminate # 1 and capture # 2, but what about # 3? In this case, it a.doA
is called indirectly from B.doB
through C.doC
. My solution also fixes this indirect case. If this is good for you, or if it doesn't happen in your codebase, you can use my solution. Otherwise, things will get a little more complicated and you will need to check the call stack. Tell me if you need to exclude # 2 and I'll continue with my answer, but the solution won't look as easy as this, I can promise.
Now here's the aspect:
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class ControlFlowInterceptor {
@Before("execution(void A.doA()) && target(a) && cflow(execution(void B.doB()) && target(b))")
public void advice(JoinPoint thisJoinPoint, A a, B b) {
System.out.println(thisJoinPoint);
System.out.println(" " + a);
System.out.println(" " + b);
}
}
The console output looks like this:
execution(void A.doA()) A@7b19f779 B@65c66812 execution(void A.doA()) A@4df2868 B@65c66812
Note that we have the same object IDs B
on both outputs, but because it C.doC
creates a new object A
, we have two different object IDs A
.
source to share