+// TESTING: Very basics with a simple static factory method
import org.aspectj.lang.annotation.*;
public class CaseA {
public static void main(String[]argv) {
CaseA ca = new CaseA();
- ((I)ca).methodOne();
+ ((I)ca).methodOne(); // will only succeed if mixin applied
}
}
aspect X {
@DeclareMixin("CaseA")
- public I createImplementation() {
+ public static I createImplementation() {
+ System.out.println("Delegate factory invoked");
return new Implementation();
}
}
--- /dev/null
+import org.aspectj.lang.annotation.*;
+
+public class CaseB {
+ public static void main(String[]argv) {
+ CaseB cb = new CaseB();
+ ((I)cb).methodOne(); // will only succeed if mixin applied
+ }
+}
+
+aspect X {
+ // TESTING: non static factory method, will need aspectOf() calling on
+ // the aspect before the factory is called
+ @DeclareMixin("CaseB")
+ public I createImplementation() {
+ System.out.println("Delegate factory invoked");
+ return new Implementation();
+ }
+}
+
+interface I {
+ void methodOne();
+}
+
+class Implementation implements I {
+ public void methodOne() {
+ System.out.println("methodOne running");
+ }
+}
--- /dev/null
+// TESTING: factory method takes the object for which the delegate exists
+import org.aspectj.lang.annotation.*;
+
+public class CaseC {
+ public static void main(String[]argv) {
+ CaseC cc = new CaseC();
+ ((I)cc).methodOne(); // will only succeed if mixin applied
+ }
+
+ public String toString() {
+ return "CaseC instance";
+ }
+}
+
+aspect X {
+ @DeclareMixin("CaseC")
+ public static I createImplementation(Object o) {
+ System.out.println("Delegate factory invoked for "+o.toString());
+ return new Implementation();
+ }
+}
+
+interface I {
+ void methodOne();
+}
+
+class Implementation implements I {
+ public void methodOne() {
+ System.out.println("methodOne running");
+ }
+}
--- /dev/null
+// TESTING: factory method is non static and takes the object for which the delegate is being created
+import org.aspectj.lang.annotation.*;
+
+public class CaseD {
+ public static void main(String[]argv) {
+ CaseD cd = new CaseD();
+ ((I)cd).methodOne(); // will only succeed if mixin applied
+ }
+
+ public String toString() {
+ return "CaseD instance";
+ }
+}
+
+aspect X {
+ @DeclareMixin("CaseD")
+ public I createImplementation(Object o) {
+ System.out.println("Delegate factory invoked for "+o.toString());
+ return new Implementation();
+ }
+}
+
+interface I {
+ void methodOne();
+}
+
+class Implementation implements I {
+ public void methodOne() {
+ System.out.println("methodOne running");
+ }
+}
--- /dev/null
+// TESTING: multiple instances causing factory invocation multiple times (but is cached)
+import org.aspectj.lang.annotation.*;
+
+public class CaseE {
+ private String id;
+
+ public static void main(String[]argv) {
+ CaseE cea = new CaseE("a");
+ CaseE ceb = new CaseE("b");
+ ((I)cea).methodOne();
+ ((I)ceb).methodTwo();
+ ((I)cea).methodOne();
+ ((I)ceb).methodTwo();
+ }
+
+ public CaseE(String id) {
+ this.id=id;
+ }
+
+ public String toString() {
+ return "CaseE instance: "+id;
+ }
+}
+
+aspect X {
+ @DeclareMixin("CaseE")
+ public I createImplementation(Object o) {
+ System.out.println("Delegate factory invoked for "+o.toString());
+ return new Implementation(o);
+ }
+}
+
+interface I {
+ void methodOne();
+ void methodTwo();
+}
+
+class Implementation implements I {
+ Object o;
+
+ public Implementation(Object o) {
+ this.o = o;
+ }
+
+ public void methodOne() {
+ System.out.println("methodOne running on "+o);
+ }
+ public void methodTwo() {
+ System.out.println("methodTwo running on "+o);
+ }
+}
--- /dev/null
+// TESTING: Factory method directly takes the type specified in the Mixin target (strongly typed)
+import org.aspectj.lang.annotation.*;
+
+public class CaseF {
+ public static void main(String[]argv) {
+ CaseF cc = new CaseF();
+ ((I)cc).methodOne(); // will only succeed if mixin applied
+ }
+
+ public String toString() {
+ return "CaseF instance";
+ }
+}
+
+aspect X {
+ @DeclareMixin("CaseF")
+ public static I createImplementation(CaseF cf) {
+ System.out.println("Delegate factory invoked for "+cf.toString());
+ return new Implementation(cf);
+ }
+}
+
+interface I {
+ void methodOne();
+}
+
+class Implementation implements I {
+ public Implementation(CaseF cf) {}
+ public void methodOne() {
+ System.out.println("methodOne running");
+ }
+}
--- /dev/null
+// TESTING: targeting multiple types from the Mixin
+import org.aspectj.lang.annotation.*;
+
+public class CaseG {
+ public static void main(String[]argv) {
+ ((I)new A()).run();
+ ((I)new B()).run();
+ }
+
+}
+
+class A {
+}
+class B {
+}
+
+aspect X {
+ @DeclareMixin("A || B")
+ public I createImplementation(Object o) {
+ System.out.println("Delegate factory invoked for instance of "+o.getClass().getSimpleName());
+ return new Implementation(o);
+ }
+}
+
+interface I {
+ void run();
+}
+
+class Implementation implements I {
+ Object o;
+
+ public Implementation(Object o) {
+ this.o = o;
+ }
+
+ public void run() {
+ System.out.println("run() executing on behalf of "+o.getClass().getSimpleName());
+ }
+}
--- /dev/null
+// TESTING: null target for mixin
+import org.aspectj.lang.annotation.*;
+
+public class CaseH {
+ public static void main(String[]argv) { }
+}
+
+aspect X {
+ @DeclareMixin(null)
+ public static I createImplementation() {
+ return null;
+ }
+}
+
+interface I {}
+
--- /dev/null
+// TESTING: invalid entry in interfaces
+import org.aspectj.lang.annotation.*;
+
+public class CaseI {
+ public static void main(String[]argv) { }
+}
+
+aspect X {
+ @DeclareMixin(value="X",interfaces={String.class})
+ public static I createImplementation() {
+ return null;
+ }
+}
+
+interface I {}
+