Answers: Sent: Monday, February 24, 2003 11:33 PM To: Johan Ovlinger; lieber@ccs.neu.edu Cc: john guthrie Subject: midterm with small adjustments by Karl Lieberherr Midterm COM 3360 Name: John Guthrie Account name: n/a (NTU student) Assignment number: Midterm Date: February 24, 2003 Question 1: ================================================== UNKNOWN1 = Input UNKNOWN2 = JPT UNKNOWN3 = JPT UNKNOWN4 = ID UNKNOWN5 = ID UNKNOWN6 = JPT UNKNOWN7 = ID UNKNOWN8 = a1 UNKNOWN9 = ID UNKNOWN10 = a2 UNKNOWN11 = JPT UNKNOWN12 = JPT UNKNOWN13 = ID UNKNOWN14 = r1 UNKNOWN15 = ID UNKNOWN16 = oid1 UNKNOWN17 = ID UNKNOWN18 = oid2 UNKNOWN19 = ID UNKNOWN20 = oid3 UNKNOWN21 = ID UNKNOWN22 = oid4 UNKNOWN23 = Basket UNKNOWN24 = Integer UNKNOWN25 = Foo UNKNOWN26 = Integer Question 2: ================================================== 1. public pointcut Check(Object thiz, Object target): call(* test..*.*(..)) && target(target) && this(thiz); this pointcut picks up every call to every method in every class in every package that has a root package name of "test" and passes the calling object and the called object as parameters "thiz" and "target" 2. public pointcut NonStaticMethod(Object target): call(* test..*.*(..)) && target(target); this pointcut picks up every non-static method call to every class in every package that has a root package name of "test" and passes the called object as parameter "target" - note that a static call would not have a called object (target). 3. public pointcut StaticMethod(Object thiz): call(static * test..*.*(..)) && this(thiz); this pointcut picks up every static method call to every class in every package that has a root package name of "test" and passes the calling object as parameter "thiz". 4. public pointcut Constructor(Object thiz, Object target): call(test..*.new(..)) && this(thiz) && target(target); this pointcut picks up every constructor call for object creation for every class in every package that has a root package name of "test" and passes the calling object and the called object as parameters "thiz" and "target" (it seems to me that the target here is null) YES: this pointcut is always empty because target(Object) and call(test..*.new(..)) have an empty intersection. 5. public pointcut Set(Object target, Object value): set(* test..*.*) && args(value) && target(target); this pointcut picks up any join point where an attribute of any object in any class in any package that has a root package name of "test" is modified and passes the target object (not the attribute, but the object containing the attriute) and the to-be-set-to value as parameters. declare parents: test..* implements Checked; this statement modifies every class in every package that has a root package name of "test" to implement the Checked interface (which is not defined in the code supplied) declare parents: test..* implements MethodSupplier; this statement modifies every class in every package that has a root package name of "test" to implement the MethodSupplier interface (which is not defined in the code supplied) declare parents: test..* implements FieldSupplier; this statement modifies every class in every package that has a root package name of "test" to implement the FieldSupplier interface (which is not defined in the code supplied) Question 3: ================================================== the tricky part of this is brought out in the example, where one of the D-objects is referenced through a C-declared variable. given that, i just let the execution pointcut specification introspect as to whether it is a D-object, and keep track as i go along of the calling parent for all objects (by updating a parent pointer at every call that does not include the aspect itself). my solution: aspect Solution { Object parent; pointcut all_calls (Object x2) : call(* *.*(..)) && this(x2) && !within(Solution); pointcut in_D (D d1) : execution(* D.t()) && target(d1); before (D d1) : in_D(d1) { System.out.println(d1); System.out.println(parent); } before (Object x2) : all_calls(x2) { parent = x2; } } =================== Karl Lieberherr // Plan: // to capture crossings from one object to another, // we rewrite the traversal so that a pointcut // call(void *.crossing*(..)) && this(s) && args(t) // captures edge crossings. If t is a D, we print s. aspect traversal1 { void A. t() { crossing_t_b(b); crossing_t_c(c) ; } void A.crossing_t_b(B b){b.t();} void A.crossing_t_c(C c){c.t();} void B.t() { crossing_t_d(d); crossing_t_e(e); } void B.crossing_t_d(D d){d.t();} void B.crossing_t_e(E e){e.t();} // void B.t() { // d.t(); e.t(); // } void C.t() {} void D.t() { System.out.println(" in D-object direct "); } void E.t() { System.out.println(" in E-object direct "); } } aspect visitor { // advising traversal traversal1 before() : execution(void D.t()) { // before() : call(void D.t()) { System.out.println(" in D-object "); } before() : execution(void E.t()) { // before() : call(void E.t()) { System.out.println(" in E-object "); } before() : call(void D.t()) { Object thiz = thisJoinPoint.getThis(); Object target = thisJoinPoint.getTarget(); System.out.println("target = " + target + "this =" + thiz); } pointcut crossing(Object s, Object t): call(void *.crossing*(..)) && this(s) && args(t); before(Object s, Object t) : crossing(s,t) { if (t instanceof D) { System.out.println("target = " + t + "source =" + s); } } } class A { B b; C c; A(B b, C c){ this.b = b; this.c = c;} } class B { D d; E e; B(D d, E e) {this.d = d; this.e = e;} } class C { } class D extends C { } class E extends C { } class Main { static public void main(String args[]) { A a_in = new A(new B(new D(), new E()), new D()); a_in.t(); } } output: target = D@31f71asource =B@5601ea target = D@31f71athis =B@5601ea in D-object in D-object direct in E-object in E-object direct target = D@7259dasource =A@6930e2 in D-object in D-object direct Ryan Culpepper's solution: aspect FoundD{ Object caller; void around():call(void *.t()) { caller = thisJoinPoint.getThis(); proceed(); } void around() : execution(void D.t()) { System.out.println(" ryan " + thisJoinPoint.getThis()); System.out.println(" ryan " + caller); } } Question 4: ================================================== Discuss how to simulate DJ in DAJ. How would you simulate this code in DAJ? cg = new ClassGraph(true, false); ClassGraph cgCommandsWithoutTail = new ClassGraph(Main.cg, "from Commands bypassing -> *,tail,* to *"); cs.process(new TraversalGraph ("from Commands to Simple",cgCommandsWithoutTail)); traversals are simulated in DAJ via aspects that DAJ creates. these aspects use DAJ-aware declarations ('strategy' and 'traversal') and visitor-style objects (although these have no inheritance structure that makes them DJ-vistors) to run the traversals. DAJ creates traversals based on static strategies... in DAJ, the above example would be something like: aspect notail { declare strategy: notail: "from Commands bypassing -> *,tail,* to *"; declare strategy: proc: "from Commands to Simple"; declare traversal: void traverse(): "intersect(proc,notail)" (SomeVisitor); } where SomeVisitor implements the visitor logic and calls to notail.traverse() do the traversal. -- john