Midterm CSG 260 Karl Lieberherr ======================================================== Please put the answers on the enclosed sheet. QUESTION 1: =============================================================== 14 UNKNOWNs: 2 points each = 28 points Consider the Java program and output below. The output contains several UNKNOWNs that you need to find. First draw the class graph in UNKNOWN1. import edu.neu.ccs.demeter.dj.*; import java.util.*; class A { A(B b, C c) { this.b = b; this.c = c; } B b; C c; List gather(Traversal what){ List result = what.gather(this); // System.out.println("Traversal Graph "); // System.out.println(what); return result; } } class B { B(D d) { this.d = d; } D d; } class C { C(U u) {this.u = u; } U u;} class D { D(E ei, X xi){ e = ei; x = xi;} E e; X x; } class E { E(F fi){ f = fi;} F f; } class F { F(int ii){ i = ii;} int i; } // classes U, R etc. below class Main { public static void main(String[] args) { ClassGraph cg = new ClassGraph(true,false); // constructed by reflection // System.out.println("Class graph"); // System.out.println(cg); // System.out.println("End of Class graph"); A a = new A ( new B( new D( new E( new F(7) ), new X( new F(9), null) ) ), new C(new S())); A a1111 = new A ( new B( new D( new E( new F(7) ), new X( new F(9), new D( new E(new F(27)), new X(new F(35), null) ) ) ) ), new C(new R(new X (new F(15), null), new F(20)) ));; Strategy sg = new Strategy("from A via X to F"); Traversal tg1 = new Traversal(sg, cg); tg1.traverse(a1111, new MyVisitor()); String whereToGo; Traversal tg; List result1; whereToGo = "from A via X to F"; tg = new Traversal(whereToGo ,cg); // System.out.println(whereToGo); result1 = a.gather(tg); System.out.println("List size = " + result1.size()); result1 = a1111.gather(tg); System.out.println("List size (a1111) = " + result1.size()); whereToGo = "from A to F"; tg = new Traversal(whereToGo ,cg); // System.out.println(whereToGo); result1 = a.gather(tg); System.out.println("List size = " + result1.size()); result1 = a1111.gather(tg); System.out.println("List size (a1111)= " + result1.size()); whereToGo = "from A to S"; tg = new Traversal(whereToGo ,cg); // System.out.println(whereToGo); result1 = a.gather(tg); System.out.println("List size = " + result1.size()); result1 = a1111.gather(tg); System.out.println("List size = (a1111) " + result1.size()); } } class MyVisitor extends Visitor { public void start() { System.out.println("begin"); } public void finish() { System.out.println("end"); } public void before(A o) { System.out.println("before A"); } public void after(A o) { System.out.println("after A"); } public void before(B o) { System.out.println("before B"); } public void after(B o) { System.out.println("after B"); } public void before(C o) { System.out.println("before C"); } public void after(C o) { System.out.println("after C"); } public void before(D o) { System.out.println("before D"); } public void after(D o) { System.out.println("after D"); } public void before(E o) { System.out.println("before E"); } public void after(E o) { System.out.println("after E"); } public void before(F o) { System.out.println("before F"); } public void after(F o) { System.out.println("after F"); } public void before(X o) { System.out.println("before X"); } public void after(X o) { System.out.println("after X"); } } class X { X(F fi, D di){ f = fi; d = di;} F f; D d; // part d is optional } abstract class U{ F f; } class R extends U { X x; R(X x, F f) { this.x = x; this.f = f; } } class S extends U { } begin before A before B before D before X before F after F before D before E before F after F after E before X before F after F after X after D after X after D after B UNKNOWN2 UNKNOWN3 UNKNOWN4 UNKNOWN5 UNKNOWN6 UNKNOWN7 UNKNOWN8 end List size = UNKNOWN9 List size (a1111) = UNKNOWN10 List size = UNKNOWN11 List size (a1111)= UNKNOWN12 List size = UNKNOWN13 List size = (a1111) UNKNOWN14 QUESTION 2: =============================================================== 9 UNKNOWNs: 2 points each = 18 points Consider the following sentence describing an object (program.input): A = call f1(A,B). B = call f2(C,A). C = 3. D = call f(A, B, C). D = F. The class dictionary is program.cd: EquationSystem = UNKNOWN1(UNKNOWN2). Equation = Variable UNKNOWN3 Exp UNKNOWN4 . Exp : UNKNOWN5 | Variable | Numbe. FunctionCall = UNKNOWN6 Function UNKNOWN7(Variable) . Variable = Ident. Function = Ident. Numbe = Integer. UNKNOWN8 CommaList(S) ~ UNKNOWN9. Question 3: ====================================================== 25 points Consider the object tree a_in representing an object of class A in the Java program below. We want to traverse this object in depth-first order as shown in the implementation below. Consider the method t. It's code is spread across several classes. 1. Write an aspect that localizes that code. 10 points 2. Write an aspect that prints the following for every D-object d1 that is found during some traversal t: a) d1.toString() b) x2.toString() for the object x2 visited immediately before the D-object d1 is visited. Your program should be generic and work for any application that has a method t() that is called on D-objects. 15 points The program: class A { B b; C c; A(B b, C c){ this.b = b; this.c = c;} void t() { b.t(); c.t(); } } class B { D d; E e; B(D d, E e) {this.d = d; this.e = e;} void t() { d.t(); e.t(); } } class C { void t() {} } class D extends C { void t() { System.out.println(" in D-object "); } } class E extends C { void t() { System.out.println(" in E-object "); } } class Main { static public void main(String args[]) { A a_in = new A(new B(new D(), new E()), new D()); a_in.t(); } } Question 4: ============================================================== 20 points Consider the following version of the Law of Demeter: Law of Demeter for Concerns (LoDC): Talk only to friends in the same concern. Consider the following universal_trv0 method that is the beginning method of a Molecule-object traversal. The method belongs to the traversal concern whose only purpose is to traverse, traverse, traverse. But the code is polluted with calls to an object that is not a friend in the same concern: the visitor object _v_. This is a violation of the Law of Demeter for concerns. Describe how an aspect can be used to clean those violations of the LoDC. Discuss the LoDC: Advantages and Disadvantages. class Molecule { protected MoleculeId moleculeid; protected Atoms atoms; protected Bonds bonds; // ... void universal_trv0(UniversalVisitor _v_) { universal_trv0_bef(_v_); ((UniversalVisitor) _v_).before_moleculeid(this, moleculeid); moleculeid.universal_trv0(_v_); ((UniversalVisitor) _v_).after_moleculeid(this, moleculeid); ((UniversalVisitor) _v_).before_atoms(this, atoms); atoms.universal_trv0(_v_); ((UniversalVisitor) _v_).after_atoms(this, atoms); ((UniversalVisitor) _v_).before_bonds(this, bonds); bonds.universal_trv0(_v_); ((UniversalVisitor) _v_).after_bonds(this, bonds); universal_trv0_aft(_v_); } void __trav_print_Molecule_trv(Print __v0) { __trav_print_Molecule_trv_bef(__v0); ((UniversalVisitor) __v0).before_atoms(this, atoms); atoms.__trav_print_Molecule_trv(__v0); ((UniversalVisitor) __v0).after_atoms(this, atoms); __trav_print_Molecule_trv_aft(__v0); } }