-------------------------------------------------------------------------- Software Development Fall 2003 CSU 670 --------------------------------------------------------------------------- Assignment 2 Due date: Sep. 25, 2003 -------------------------------------------------------------------------- This assignment is stored in file $SD/hw/2 in file assign.txt -------------------------------------------------------------------------- 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 electronic and hardcopy submission. This will allow the teaching assistant to run your programs and mark your printed copies. Please turn in your answers in hardcopy at one of the following places: (1) Bring it to the class room and hand it to me. (2) In 161 Cullinane Hall: Put it into the teaching assistant's mailbox. (3) In 161 Cullinane Hall: Put it into my mailbox. (4) If all those possibilities don't work for you, slide it under my office door. For electronic submission to Blackboard, the format for files should be: hw?_[lastname].[ext] lastname = your last name ext = zip, doc, ps, pdf ========= We reuse the abbreviations for $SD, $DemJ etc. already introduced in hw 1. ========= THEMES: Visitor Pattern, Automated Traversals using Strategies, Adaptive Programming in Java with DJ, Simulating an Automated Traversal Manually. Better separation of Structure, Navigation and Behavior 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. Read the section 27 (Metaprogramming) in the text book The Pragmatic Programmer (TPP). How do the tips 37:"Configure, Don't Integrate" and 38: "Put Abstractions in Code, Details in Metadata" apply to this homework? Read the section 7: The Evils of Duplication in TPP. How does the DRY tip: "Don't Repeat Yourself" apply to 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 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.6 The class graph is============================= Location = java.lang.UNKNOWN27 extends java.lang.Object. java.lang.Object : java.lang.String | Location | Main | Trip | edu.neu.ccs.demeter.dj.Visitor | java.util.AbstractCollection common . java.lang.String = extends java.lang.Object implements java.io.Serializable, java.lang.Comparable, java.lang.CharSequence. java.io.Serializable : java.lang.String | java.util.Vector common . java.lang.Comparable : java.lang.String common . java.lang.CharSequence : java.lang.String common . Main = extends java.lang.Object. Trip$1 = Trip extends edu.neu.ccs.demeter.dj.Visitor. Trip = java.util.UNKNOWN28 UNKNOWN30 int extends java.lang.Object. edu.neu.ccs.demeter.dj.Visitor : Trip$1 common extends java.lang.Object. java.util.AbstractList : java.util.Vector common extends java.util.AbstractCollection implements java.util.List. java.util.Vector = extends java.util.AbstractList implements java.util.List, java.util.RandomAccess, java.lang.Cloneable, java.io.Serializable. 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.util.RandomAccess : java.util.Vector common . java.lang.Cloneable : java.util.Vector common . edu.neu.ccs.demeter.dj.Collection = java.lang.Object. end class graph ============================= ---- TG begin Start set: [Trip: {0}] Copy 0: Nodes: UNKNOWN31 java.lang.Object java.util.Vector java.util.AbstractList java.util.AbstractCollection java.util.Collection java.io.Serializable Location edu.neu.ccs.demeter.dj.Visitor Trip$1 java.util.List java.util.RandomAccess 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,Trip => java.lang.Object,edu.neu.ccs.demeter.dj.Visitor => edu.neu.ccs.demeter.dj.Visitor,Trip$1 -> Trip$1,this$0,Trip => 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 Edges to other copies: Finish set: [Location: {0}] ---- TG done UNKNOWN35 departure 9 Zurich Chur St. Morit Pontresina arrival 17 UNKNOWN36 ================ Question 2 ------------------------------------------------------------------ Consider the following Java program in PART 2 that gathers information from A-objects. The output from the program is in PART 2. Do first PART 2 and then PART 1. PART 1: -------------------------------------------------------- Your task is to rewrite the following part of Main.java: String whereToGo = "from A to F"; Traversal tg = new Traversal(whereToGo ,cg); 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. 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(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 {} 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"); Traversal tg1 = new Traversal(sg, cg); tg1.traverse(a, new UNKNOWN7()); String whereToGo = "UNKNOWN8"; Traversal tg = new Traversal(whereToGo ,cg); System.out.println(whereToGo); List result1 = a.gather(tg); System.out.println("List size = " + result1.size()); whereToGo = "UNKNOWN35"; tg = new Traversal(whereToGo ,cg); System.out.println(whereToGo); result1 = a.gather(tg); System.out.println("List size = " + result1.size()); whereToGo = "{A -> X X ->F}"; // same as whereToGo = "from A through X to F" except // that X is also a target; // The following strategy correctly specifies source and target // whereToGo = "{source:A -> X X ->target:F}"; tg = new Traversal(whereToGo ,cg); System.out.println(whereToGo); result1 = a.gather(tg); System.out.println("List size = " + result1.size()); whereToGo = "{A ->F bypassing {X}}"; tg = new Traversal(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; } The output: Class graph A = B C extends java.lang.Object. java.lang.Object : B | C | A | D | E | X | F | Main | edu.neu.ccs.demeter.dj.Visitor common . B = D extends java.lang.Object. 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. 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 Start set: [A: {0}] 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: Finish set: [F: {0}] List size = 2 from A through X to F Traversal Graph Start set: [A: {0}] 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: Finish set: [F: {1}] List size = 1 {A -> X X ->F} Traversal Graph Start set: [A: {0}, X: {1}] 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: Finish set: [F: {1}, X: {0}] List size = 2 {A ->F bypassing {X}} Traversal Graph Start set: [A: {0}] 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: Finish set: [F: {0}] List size = UNKNOWN34 ========== The DJ documentation is at: http://www.ccs.neu.edu/research/demeter/software/docs/api/ ====================== Cut here and turn in the following for both questions. Question ?: ================================================== 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 =