Question 1: ================================================== UNKNOWN1 = see .ppt file in directory UNKNOWN2 = C UNKNOWN3 = X UNKNOWN4 = F UNKNOWN5 = F UNKNOWN6 = X UNKNOWN7 = C UNKNOWN8 = A UNKNOWN9 = 1 UNKNOWN10 = 4 UNKNOWN11 = 2 UNKNOWN12 = 6 UNKNOWN13 = 1 UNKNOWN14 = 0 Question 2: ================================================== UNKNOWN1 = List UNKNOWN2 = Equation UNKNOWN3 = "=" UNKNOWN4 = "." UNKNOWN5 = FunctionCall UNKNOWN6 = "call" UNKNOWN7 = CommaList UNKNOWN8 = List(S) ~ {S}. UNKNOWN9 = "(" S {"," S} ")". Question 3: ==================================================== aspect traversal1 { void A. t() { b.t(); c.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()) { // does not work in general, // e.g., in A.c is a D System.out.println(" in D-object "); } before() : execution(void E.t()) { // before() : call(void E.t()) { System.out.println(" in E-object "); } } 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(); } } in D-object in D-object direct in E-object in E-object direct in D-object in D-object direct Question 3.2 ============================================ // 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); } } aspect Jeff{ before() : call(void *.t()){ Object thiz = thisJoinPoint.getThis(); Object target = thisJoinPoint.getTarget(); if(target instanceof D){ System.out.println("JEFF target = " + target + "this =" + thiz); } } } Question 4: The original form of the LoD was: Talk only to your friends. It forbids to talk to objects that are "not closely related". The LoDC is more selective in choosing friends than the LoD. The LoDC distinguishes between friends that are supportive of the main intent of the concern and "friends" that want to piggy back on the current concern. Those objects are no longer considered friends by the LoDC. Consider a base program that also wants to log some function calls. This will involve calls on a LogFile object. The LoD would consider the LogFile object a friend because it is a a global object. But logging is not supportive of the main intent of the base program; indeed logging wants to piggy back onto the base and watch what the base is doing. That is not what friends do and therefore LoDC disallows a call to the LogFile object. Following the LoDC requires new techniques to conform and those new techniques fall into the AOSD domain. We have two concerns C1 (e.g. base) and C2 (e.g. logging) and let's assume that they both are implemented in program P, violating LoDC. There is some inherent coupling between C1 and C2 but want to minimize that using an abstraction barrier B between C1 and C2. C1 will expose high-level information about itself in B and C2 will refer to C1 only through the abstraction barrier B. The abstraction barrier allows C2 to refer through B to places in the execution of C1 where additional behavior should be added. This technique allows us to remove the LODC offending calls from C1.