-------------------------------------------------------------------------- Software Design and Development Winter 2001 COM 1205 --------------------------------------------------------------------------- Assignment 2 Due date: Jan. 23, 2001 -------------------------------------------------------------------------- This assignment is stored in file $SD/hw/2 in file assign.txt -------------------------------------------------------------------------- Doug Orleans (dougo) is the key developer for DemeterJ and he also developed a good part of DJ. He maintains all Demeter software. You may turn in your hw for full credit up to two working days late. This means, if it is due on Thursday, you can turn it in the following Monday. If it is due on day x, it means 4.30 pm on that day. For late homework we will deduct 20% per day late, unless you present a very good reason to the teaching assistant. Please note that homework submission is hard copy either to the class room or to Jing Wang's mail box. ========= We reuse the abbreviations already introduced in hw 1: ========= On CCS Northeastern machines, SD=/home/lieber/.www/com1205/w01 DemJ=/proj/adaptive/www/DemeterJava DJ=/proj/adaptive/www/DJ D=/proj/adaptive/www/ On the WWW, SD = http://www.ccs.neu.edu/home/lieber/com1205/w01 DemJ = http://www.ccs.neu.edu/research/demeter/DemeterJava DJ = http://www.ccs.neu.edu/research/demeter/DJ D = http://www.ccs.neu.edu/research/demeter/ To browse the email messages sent to com1205@ccs.neu.edu, see http://www.ccs.neu.edu/home/lieber/com1205/w01/archive/ ========= THEMES: Visitor Pattern, Automated Traversals using Strategies, Adaptive Programming in Java with DJ, Simulating an Automated Traversal Manually. READING: Read chapters 5, 6 of the AP book. Read Java book as necessary to understand enough of the Java programs which you need to modify in this homework. This homework is a 100% Java homework. No Demeter syntax, except for the Demeter graphs (traversal strategies, class graphs, traversal graphs), is required. But a good understanding of DJ is necessary. Browse $DJ. Read about related tools which promote a traversal/visitor style to programming at: http://www.ccs.neu.edu/home/lieber/suntest.html A quote from the above URL: ==================== Visitor Support JJTree provides some basic support for the visitor design pattern. If the VISITOR option is set to true JJTree will insert an jjtAccept() method into all of the node classes it generates, and also generate a visitor interface that can be implemented and passed to the nodes to accept. ==================== The following two questions are designed so that you can find the unknowns without using the computer. You should find the unknowns without using the computer and at the end you may use the computer to check your answers. But remember that you get most of the educational value by studying the program and finding the unknowns manually. In the exams there will also be questions of this style. Question 1: ----------- Consider the following Java program and its output. The program solves the ITINERARY problem described in section 4.5 in the AP book at http://www.ccs.neu.edu/research/demeter/biblio/dem-book.html (see page 111 of Gnomon Copy package). Some simplifications have been made: A Trip-object has only three parts, a Location-object has only one part, a list is implemented as a vector. Find the UNKNOWNs below. // Location.java class Location { String name; Location(String n){ name = n ;} } // Main.java import edu.neu.ccs.demeter.dj.*; import java.UNKNOWN1.*; import edu.neu.ccs.demeter.*; class Main { public Main() { super(); } static public void main(String args[]) throws Exception { // Build Trip-object Vector v1 = new Vector(); Location l1 = new Location("UNKNOWN2"); v1.UNKNOWN3(l1); Location l2 = new Location("UNKNOWN4"); v1.UNKNOWN5(l2); Location l3 = new Location("UNKNOWN6"); v1.UNKNOWN7(l3); Location l4 = new Location("UNKNOWN8"); v1.UNKNOWN9(l4); Trip a = new Trip(UNKNOWN10,UNKNOWN11,UNKNOWN12); System.out.println("DJ start "); UNKNOWN13 cg = Main.UNKNOWN14(); System.out.println(); UNKNOWN15 allLocations = new UNKNOWN16( UNKNOWN17 ,cg); System.out.println("---- TG begin "); System.out.println(allLocations); System.out.println("---- TG done "); System.out.println(); System.out.println("UNKNOWN18"); a.UNKNOWN19(UNKNOWN20); System.out.println(" DONE"); } public static ClassGraph buildClassGraph() { ClassGraph cg=new ClassGraph(true,false); // true: include all fields // false: do NOT include all non-void no-argument methods System.out.println("The DJ version is: " + cg.getVersion()); System.out.println("The class graph is" + "============================="); System.out.println(cg); System.out.println("end class graph " + "============================="); return cg; } } // Trip.java import java.UNKNOWN21.*; import edu.neu.ccs.demeter.dj.*; class Trip { Trip(Vector it, int d, int a) { itinerary = it; departure = d; arrival = a; } Vector itinerary; int arrival; int departure; void printItinerary(UNKNOWN22 allLocations) { allLocations.traverse(this, new UNKNOWN23() { void before (UNKNOWN24 host) {System.out.println("departure " + host.departure);} void before (UNKNOWN25 host) { System.out.println(host.name);} void after (UNKNOWN26 host) {System.out.println("arrival " + host.arrival);} }); } } // The output of the above program follows: DJ start The DJ version is: DJ version 0.8.1 The class graph is============================= Location = java.lang.UNKNOWN27 extends java.lang.Object. java.lang.String = extends java.lang.Object implements java.io.Serializable, java.lang.Comparable. java.lang.Object : java.lang.String | Location | Main | java.util.AbstractCollection | Trip | edu.neu.ccs.demeter.dj.Visitor common . java.io.Serializable : java.lang.String | java.util.Vector common . java.lang.Comparable : java.lang.String common . Main = extends java.lang.Object. Trip = java.util.UNKNOWN28 UNKNOWN30 int extends java.lang.Object. java.util.Vector = extends java.util.AbstractList implements java.util.List, java.lang.Cloneable, java.io.Serializable. java.util.AbstractList : java.util.Vector common extends java.util.AbstractCollection implements java.util.List. java.util.AbstractCollection : java.util.AbstractList common extends java.lang.Object implements java.util.Collection. java.util.Collection : java.util.AbstractCollection | java.util.List common java.lang.Object. java.util.List : java.util.AbstractList | java.util.Vector common extends java.util.Collection. java.lang.Cloneable : java.util.Vector common . int = . edu.neu.ccs.demeter.dj.Visitor : Trip$1 common extends java.lang.Object. Trip$1 = extends edu.neu.ccs.demeter.dj.Visitor. edu.neu.ccs.demeter.dj.Collection = java.lang.Object. end class graph ============================= ---- TG begin Copy 0: Nodes: UNKNOWN31 java.util.Vector java.util.AbstractList java.util.AbstractCollection java.lang.Object java.util.Collection java.io.Serializable Location java.util.List java.lang.Cloneable Edges: -> UNKNOWN32,itinerary,java.util.UNKNOWN33 :> java.util.Vector,java.util.AbstractList :> java.util.AbstractList,java.util.AbstractCollection :> java.util.AbstractCollection,java.util.Collection -> java.util.Collection,elements,java.lang.Object => java.lang.Object,UNKNOWN34 => java.lang.Object,java.util.AbstractCollection => java.util.AbstractCollection,java.util.AbstractList => java.util.AbstractList,java.util.Vector :> java.util.Vector,java.util.List :> java.util.List,java.util.Collection :> java.util.AbstractList,java.util.List => java.lang.Object,Trip Edges to other copies: ---- TG done UNKNOWN35 departure 9 Zurich Chur St. Moritz Pontresina arrival 17 UNKNOWN36 ================ Question 2 ---------- Consider the following Java program that gathers information from A-objects. The output from the program is attached. PART 1: Your task is to rewrite the following part of Main.java: String whereToGo = "from A to F"; TraversalGraph tg = new TraversalGraph(whereToGo ,cg); System.out.println(whereToGo); List result1 = a.gather(tg); without using DJ classes by writing methods that satisfy the Law of Demeter and that return the same List result1. Your methods will be spread over several classes. Run your program to make sure it returns a list of the correct length. Turn in your modified Java files. PART 2: Find the UNKNOWNs below. Note that UNKNOWN 35 and 36 are out of order. For some unknowns there is a choice. Choose the simplest answer. Turn in your answers in the UNKNOWN list at the end. import edu.neu.ccs.demeter.dj.*; import java.UNKNOWN1.*; class A { A(B b, C c) { this.b = b; this.c = c; } B b; C c; List gather(TraversalGraph 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 {} class D { D(E ei, X xi){ e = ei; x = xi;} E e; X x; } class E { E(UNKNOWN2 fi){ f = fi;} UNKNOWN3 f; } class F { F(int ii){ i = ii;} int i; } import edu.neu.ccs.demeter.dj.*; import java.UNKNOWN4.*; 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 UNKNOWN5( new E( new F(7) ), new UNKNOWN6( new F(9)) ) ), new C()); Strategy sg = new Strategy("from A through X to F"); TraversalGraph tg1 = new TraversalGraph(sg, cg); tg1.traverse(a, new UNKNOWN7()); String whereToGo = "UNKNOWN8"; TraversalGraph tg = new TraversalGraph(whereToGo ,cg); System.out.println(whereToGo); List result1 = a.gather(tg); System.out.println("List size = " + result1.size()); whereToGo = "UNKNOWN36 "; tg = new TraversalGraph(whereToGo ,cg); System.out.println(whereToGo); result1 = a.gather(tg); System.out.println("List size = " + result1.size()); // same as whereToGo = "from A through X to F"; whereToGo = "{A -> X X ->F}"; tg = new TraversalGraph(whereToGo ,cg); System.out.println(whereToGo); result1 = a.gather(tg); System.out.println("List size = " + result1.size()); whereToGo = "{A ->F bypassing {X}}"; tg = new TraversalGraph(whereToGo ,cg); System.out.println(whereToGo); result1 = a.gather(tg); System.out.println("List size = " + result1.size()); } } import edu.neu.ccs.demeter.dj.Visitor; 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){ f = fi;} F f; } Class graph A = B C extends java.lang.Object. B = D extends java.lang.Object. java.lang.Object : B | C | A | D | E | X | F | Main | edu.neu.ccs.demeter.dj.Visitor common . C = extends java.lang.Object. D = E X extends java.lang.Object. E = F extends java.lang.Object. X = F extends java.lang.Object. F = int extends java.lang.Object. int = . Main = extends java.lang.Object. edu.neu.ccs.demeter.dj.Visitor : MyVisitor common extends java.lang.Object. MyVisitor = extends edu.neu.ccs.demeter.dj.Visitor. java.util.Collection = java.lang.Object. edu.neu.ccs.demeter.dj.Collection = java.lang.Object. End of Class graph begin before UNKNOWN9 before UNKNOWN10 before UNKNOWN11 before UNKNOWN12 before UNKNOWN13 after UNKNOWN14 after UNKNOWN15 after UNKNOWN16 after UNKNOWN17 after UNKNOWN18 end from A to F Traversal Graph Copy 0: Nodes: A B java.lang.Object D E F X Edges: -> A,b,B -> B,d,D -> D,e,E -> E,f,F -> D,x,X -> X,f,F Edges to other copies: List size = 2 UNKNOWN35 from A through X to F Traversal Graph Copy 0: Nodes: A B java.lang.Object D Edges: -> A,b,B -> B,d,D Edges to other copies: 1: -> D,x,X Copy 1: Nodes: java.lang.Object F X Edges: -> X,f,F Edges to other copies: List size = 1 {A -> X X ->F} Traversal Graph Copy 0: Nodes: A B java.lang.Object D X Edges: -> A,b,B -> B,d,D -> UNKNOWN19,UNKNOWN20,UNKNOWN21 Edges to other copies: 1: -> D,x,X Copy 1: Nodes: java.lang.Object F X Edges: -> X,f,F Edges to other copies: List size = 2 {A ->F bypassing {X}} Traversal Graph Copy 0: Nodes: A B java.lang.Object D E F Edges: -> UNKNOWN22,UNKNOWN23,UNKNOWN24 -> UNKNOWN25,UNKNOWN26,UNKNOWN27 -> UNKNOWN28,UNKNOWN29,UNKNOWN30 -> UNKNOWN31,UNKNOWN32,UNKNOWN33 Edges to other copies: List size = UNKNOWN34 ========== The DJ documentation is at: http://www.ccs.neu.edu/research/demeter/DJ/docs/api/edu/neu/ccs/demeter/dj/package-summary.html ====================== System help: http://www.ccs.neu.edu/research/demeter/course/f00/runningjava.html Cut here and turn in the following for both questions. Question 1: ================================================== UNKNOWN1 = UNKNOWN2 = UNKNOWN3 = UNKNOWN4 = UNKNOWN5 = UNKNOWN6 = UNKNOWN7 = UNKNOWN8 = UNKNOWN9 = UNKNOWN10 = UNKNOWN11 = UNKNOWN12 = UNKNOWN13 = UNKNOWN14 = UNKNOWN15 = UNKNOWN16 = UNKNOWN17 = UNKNOWN18 = UNKNOWN19 = UNKNOWN20 = UNKNOWN21 = UNKNOWN22 = UNKNOWN23 = UNKNOWN24 = UNKNOWN25 = UNKNOWN26 = UNKNOWN27 = UNKNOWN28 = UNKNOWN29 = UNKNOWN30 = UNKNOWN31 = UNKNOWN32 = UNKNOWN33 = UNKNOWN34 = UNKNOWN35 = UNKNOWN36 =