Presentation is loading. Please wait.

Presentation is loading. Please wait.

Demeter and Aspects1 AOSD 2002 Tutorial: Demeter Aspect-Oriented Programming of Traversal Related Concerns in Java Demeter Research Group.

Similar presentations


Presentation on theme: "Demeter and Aspects1 AOSD 2002 Tutorial: Demeter Aspect-Oriented Programming of Traversal Related Concerns in Java Demeter Research Group."— Presentation transcript:

1

2 Demeter and Aspects1 AOSD 2002 Tutorial: Demeter Aspect-Oriented Programming of Traversal Related Concerns in Java Demeter Research Group

3 Demeter and Aspects2 Overview DJ introduction AspectJ and DJ Aspect-oriented Programming in pure Java using the DJ library

4 Demeter and Aspects3 Problem addressed Encapsulation of traversal-related concerns –Those are concerns that involve a group of collaborating objects that are connected by has- a relationships or zero-argument methods. –Control scattering of traversal-related concerns and tangling with other concerns Construct useful programs without knowing exactly what data types are involved

5 Demeter and Aspects4 How is the problem solved? Need to talk about a traversal join point model: –sets of points (called join points) in the execution of a traversal where additional behavior is executed (called hooks or pointcuts). –the behavior to be executed (called an enhancement or advice).

6 Demeter and Aspects5 An AOP System has 3 critical elements –what are the join points in AspectJ –points in runtime –means of identifying join points in AspectJ –signatures (plus …) –means of specifying semantics at join points in AspectJ –advice –define members

7 Demeter and Aspects6 An AOP System (in more detail) what is the set of all join points (SJP) means of identifying join points (IJP) means of specifying semantics at join points (SJP) encapsulated units combining JPS and BJP (CSB) method of attachment of units (AU) JPS and BJP are sometimes overlapping. JPS might already define an initial behavior plus a set of join points in that behavior.

8 Demeter and Aspects7 AP Late binding of data structures Programming without accidental data structure details yet handling all those details on demand without program change Reducing representational coupling

9 Demeter and Aspects8 Concepts needed (DJ classes) ClassGraph Strategy Visitor TraversalGraph ObjectGraph ObjectGraphSlice important for advanced programming

10 Demeter and Aspects9 AOSD: not every concern fits into a component: crosscutting Goal: find new component structures that encapsulate “crosscutting” concerns

11 Demeter and Aspects10 a reusable aspect abstract public aspect RemoteExceptionLogging { abstract pointcut logPoint(); after() throwing (RemoteException e): logPoint() { log.println(“Remote call failed in: ” + thisJoinPoint.toString() + “(” + e + “).”); } public aspect MyRMILogging extends RemoteExceptionLogging { pointcut logPoint(): call(* RegistryServer.*.*(..)) || call(private * RMIMessageBrokerImpl.*.*(..)); } abstract

12 Demeter and Aspects11 DJ: Counting Pattern: Abstract Pointcut class BusRoute { int countPersons(TraversalGraph WP) { Integer result = (Integer) WP.traverse(this, new Visitor(){ int r ; public void before(Person host){ r++; } public void start() { r = 0;} public Object getReturnValue() {return new Integer ( r);} }); return result.intValue();} }

13 Demeter and Aspects12 DJ: Counting Pattern: Concrete Pointcut // Prepare the traversal for the current class graph ClassGraph classGraph = new ClassGraph(); TraversalGraph WPTraversal = new TraversalGraph (“from BusRoute via BusStop to Person”, classGraph); int r = aBusRoute.countPersons(WPTraversal);

14 Demeter and Aspects13 Example : Count Aspect Pattern collaboration Counting { Source role Source { in TraversalGraph getT(); public int count (){ // traversal/visitor weaving getT().traverse(this, new Visitor(){ int r; public void before(Target host){ r++; } public void start() { r = 0;} …) } } role Target {} } Base: Meta variable: bold Keywords: underscore

15 Demeter and Aspects14 AP history Programming with partial data structures = propagation patterns Programming with participant graphs = high-level class graphs Programming with object slices –partial objects = all the constraints imposed by visitors

16 Demeter and Aspects15 Collaborating Classes BusRoute BusStopList BusStop BusList BusPersonList Person passengers buses busStops waiting 0..* find all persons waiting at any bus stop on a bus route OO solution: one method for each red class

17 Demeter and Aspects16 Traversal Strategy BusRoute BusStopList BusStop BusList BusPersonList Person passengers buses busStops waiting 0..* from BusRoute through BusStop to Person find all persons waiting at any bus stop on a bus route

18 Demeter and Aspects17 Robustness of Strategy BusRoute BusStopList BusStop BusList BusPersonList Person passengers buses busStops waiting 0..* from BusRoute through BusStop to Person VillageList Village villages 0..* find all persons waiting at any bus stop on a bus route

19 Demeter and Aspects18 Writing Adaptive Programs with Strategies (DJ=pure Java) class BusRoute { int countPersons(TraversalGraph WP) { Integer result = (Integer) WP.traverse(this, new Visitor(){ int r ; public void before(Person host){ r++; } public void start() { r = 0;} public Object getReturnValue() {return new Integer ( r);} }); return result.intValue();} } String WPStrategy=“ from BusRoute through BusStop to Person”

20 Demeter and Aspects19 Writing Adaptive Programs with Strategies (DJ=pure Java) // Prepare the traversal for the current class graph ClassGraph classGraph = new ClassGraph(); TraversalGraph WPTraversal = new TraversalGraph (WPStrategy, classGraph); int r = aBusRoute.countPersons(WPTraversal); String WPStrategy=“ from BusRoute through BusStop to Person”

21 Demeter and Aspects20 Writing Adaptive Programs with Strategies (DJ=pure Java) class BusRoute { int countPersons(TraversalGraph WP) { Integer result = (Integer) WP.traverse(this, new Visitor(){...}); return result.intValue();} } String WPStrategy=“ from BusRoute through BusStop to Person” ObjectGraph objectGraph = new ObjectGraph(this, classGraph); ObjectGraphSlice objectGraphSlice = new ObjectGraphSlice(objectGraph, WP); objectGraphSlice.traverse(visitor); WP.traverse(this,visitor)

22 Demeter and Aspects21 ObjectGraph: in UML notation Route1:BusRoute :BusStopList busStops CentralSquare:BusStop :PersonList waiting Paul:PersonSeema:Person :BusList buses Bus15:Bus :PersonList passengers Joan:Person Eric:Person

23 Demeter and Aspects22 TraversalGraph BusRoute BusStopList BusStop BusList BusPersonList Person passengers buses busStops waiting 0..* from BusRoute through BusStop to Person find all persons waiting at any bus stop on a bus route

24 Demeter and Aspects23 ObjectGraphSlice Route1:BusRoute :BusStopList busStops CentralSquare:BusStop :PersonList waiting Paul:PersonSeema:Person BusList buses Bus15:Bus :PersonList passengers Joan:Person Eric:Person

25 Demeter and Aspects24 Applications of Traversal Strategies Program Kinds in DJ –AdaptiveProgram Traditional (ClassGraph) strategies are part of program: DemeterJ, Demeter/C++ –AdaptiveProgram Dynamic (Strategies, ClassGraph) strategies are a parameter. Even more adaptive. –AdaptiveProgram TraditionalOptimized (TraversalGraphs) strategies are a parameter. Reuse traversal graphs. –AdaptiveProgram DJ (ObjectGraphSlices) strategies are a parameter. Reuse traversal graph slices.

26 Demeter and Aspects25 Example For data member access: C c = (C) Main.cg.fetch(this, “from A via B to C”);

27 Demeter and Aspects26 Understanding the meaning of a strategy Classes involved: Strategy, ObjectGraph, ObjectGraphSlice, ClassGraph We want to define the meaning of a Strategy-object for an ObjectGraph-object as an ObjectGraphSlice-object (a subgraph of the ObjectGraph-object). Minimal attention necessary will be given to ClassGraph-object.

28 Demeter and Aspects27 Simple case: from A to B See lecture: Navigation in object graphs navig-object-graphs-1205-w02.ppt

29 Demeter and Aspects28 Graphs and paths Directed graph: (V,E), V is a set of nodes, E  V  V is a set of edges. Directed labeled graph: (V,E,L), V is a set of nodes, L is a set of labels, E  V  L  V is a set of edges. If e = (u,l,v), u is source of e, l is the label of e and v is the target of e.

30 Demeter and Aspects29 Graphs and paths Given a directed labeled graph: (V,E,L), a node-path is a sequence p = where v i  V and (v i-1,l i,v i )  E for some l i  L. A path is a sequence, where is a node-path and (v i-1, l i, v i )  E.

31 Demeter and Aspects30 Graphs and paths In addition, we allow node-paths and paths of the form (called trivial). First node of a path or node-path p is called the source of p, and the last node is called the target of p, denoted Source(p) and Target(p), respectively. Other nodes: interior.

32 Demeter and Aspects31 Strategy definition: embedded, positive strategies Given a graph G, a strategy graph S of G is any subgraph of the transitive closure of G. Source s, Target t. The transitive closure of G=(V,E) is the graph G*=(V,E*), where E*={(v,w): there is a path from vertex v to vertex w in G}.

33 A = s A BB C C D D E E F=t F G S S is a strategy for G pink edge must imply black path

34 Demeter and Aspects33 Transitive Closure BusRoute BusStopList BusStop BusList BusPersonList Person passengers buses busStops waiting 0..*

35 Demeter and Aspects34 Key concepts Strategy graph S with source s and target t of a base graph G. Nodes(S) subset Nodes(G) (Embedded strategy graph). A path p is an expansion of path p’ if p’ can be obtained by deleting some elements from p. Strategy graph and base graph are directed graphs

36 Demeter and Aspects35 A simple view of traversals When a traversal reaches a target node in the object graph, the path traversed from the source, with suitable substitution of subclasses by superclasses, must be an expansion of an s-t path in the strategy graph. s is the source and t is the target of the strategy. Each edge in the strategy graph corresponds to at least one edge in the object graph.

37 Demeter and Aspects36 A simple view of traversals When a traversal reaches a final node in the object graph without being at a target, the path traversed from the source, with suitable substitution of subclasses by superclasses, must be a prefix of an expansion of an s-t path in the strategy graph. The prefix is the longest prefix such that there is still a possibility of success as determined by the class graph.

38 Demeter and Aspects37 Example 1 strategy: {A -> B B -> C} A B C X x x b c class graph ABC Strategy s t c BOpt Empty Object graph OG : A X R X C OG’: A X B X C SG : A B C (CG: A X Bopt B X C) :A c2:C x1:X :R x2:X c1:C c3:C e1:Empty S R Only node paths shown for space reasons

39 Demeter and Aspects38 Example 1A strategy: {A -> S S -> C} A B C X x x b c class graph ASC Strategy s t c BOpt Empty Object graph OG : A X R X OG’: A X B X SG : A (CG: A X Bopt B X) :A c2:C x1:X :R x2:X c1:C c3:C e1:Empty S R Only node paths shown for space reasons early termination

40 Demeter and Aspects39 Example 2 BusRoute BusStopList BusStop BusList BusPersonList Person passengers buses busStops waiting 0..* S = from BusRoute through Bus to Person NGasPowered DieselPowered

41 Demeter and Aspects40 Example 2 Route1:BusRoute :BusStopList busStops CentralSquare:BusStop :PersonList waiting Paul:PersonSeema:Person BusList buses Bus15:DieselPowered :PersonList passengers Joan:Person Eric:Person OG : BR BL DP PL P OG’: BR BL B PL P SG : BR B P Only node paths shown for space reasons S = from BusRoute through Bus to Person

42 Demeter and Aspects41 Example 3 Route1:BusRoute :BusStopList busStops CentralSquare:BusStop :PersonList waiting Paul:PersonSeema:Person BusList buses Bus15:DieselPowered :PersonList passengers Joan:Person Eric:Person OG : BR BL OG’: BR BL SG : BR Only node paths shown for space reasons S = from BusRoute via NGasPowered to Person early termination

43 Demeter and Aspects42 Allow strategy: { A -> B B -> C} class graph: A : B. B : C. C =. object graph: C

44 Demeter and Aspects43 ObjectGraphSlice The object graph slice starting with o1 is the slice built by following the edges POSS(Class(o1), t, o1) starting at o1 and continuing until every path terminates (at an object of type t or it terminates prematurely).

45 Demeter and Aspects44 Example A R B X S D 0..1 C T A -> T T -> D A = [“x” X] [“r” R]. B = [“b” B] D. R = S. S = [“t” T] C C = D. X = B. T = R. D =. :A :R:S :C :D class graph strategy class dictionary object graph “r”

46 Demeter and Aspects45 Example A R B X S D 0..1 C T A -> T T -> D A = [“x” X] [“r” R]. B = [“b” B] D. R = S. S = [“t” T] C C = D. X = B. T = R. D =. a1:A r1:Rs1:S :C :D class graph strategy class dictionary object graph “r” POSS(A,T,a1) = 1 edge POSS(R,T,r1) = 1 edge POSS(S,T,s1) = 0 edges

47 Demeter and Aspects46 DJ An implementation of AP using only the DJ library (and the Java Collections Framework) All programs written in pure Java Intended as prototyping tool: makes heavy use of introspection in Java Integrates Generic Programming (a la C++ STL) and Adaptive programming

48 Demeter and Aspects47 Integration of Generic and Adaptive Programming A traversal specification turns an object graph into a list. Can invoke generic algorithms on those lists. Examples: contains, containsAll, equals, isEmpty, contains, etc. add, remove, etc. throws operation not supported exception. What is gained: genericity not only with respect to data structure implementations but also with respect to class graph

49 Demeter and Aspects48 Sample DJ code // Find the user with the specified uid List libUsers = classGraph.asList(library, "from Library to User"); ListIterator li = libUsers.listIterator(); // iterate through libUsers

50 Demeter and Aspects49 Methods provided by DJ On ClassGraph, ObjectGraph, TraversalGraph, ObjectGraphSlice: traverse, fetch, gather traverse is the important method; fetch and gather are special cases TraversalGraph –Object traverse(Object o, Visitor v) –Object traverse(Object o, Visitor[] v)

51 Demeter and Aspects50 Traverse method: excellent support for Visitor Pattern // class ClassGraph Object traverse(Object o, Strategy s, Visitor v); traverse navigates through Object o following traversal specification s and executing the before and after methods in visitor v ClassGraph is computed using introspection

52 Demeter and Aspects51 Fetch Method If you love the Law of Demeter, use fetch as your shovel for digging: –Part k1 = (K) classGraph.fetch(a,”from A to K”); The alternative is (digging by hand): –Part k1 = a.b().c().d().e().f().g().h().i().k(); DJ will tell you if there are multiple paths to the target (but currently only at run-time).

53 Demeter and Aspects52 Gather Method Returns a list of objects. Object ClassGraph.gather(Object o, String s) –List ks = classGraph.gather(a,”from A to K”); returns a list of K-objects.

54 Demeter and Aspects53 Using DJ traverse(…) returns the v[0] return value. Make sure the casting is done right, otherwise you get a run-time error. If “ public Object getReturnValue()” returns an Integer and traverse(…) casts it to a Real: casting error at run-time. Make sure all entries of Visitor[] array are non-null.

55 Demeter and Aspects54 Using multiple visitors // establish visitor communication aV.set_cV(cV); aV.set_sV(sV); rV.set_aV(aV); Float res = (Float) whereToGo. traverse(this, new Visitor[] {rV, sV, cV, aV});

56 Demeter and Aspects55 DJ binary construction operations

57 Demeter and Aspects56 Who has traverse, fetch, gather? (number of arguments of traverse)

58 Demeter and Aspects57 Methods returning an ObjectGraphSlice ClassGraph.slice(Object, Strategy) ObjectGraph.slice(Strategy) TraversalGraph.slice(Object) ObjectGraphSlice(ObjectGraph,Strategy) ObjectGraphSlice(ObjectGraph,TraversalGraph) Blue: constructors

59 Demeter and Aspects58 Traverse method arguments ClassGraph –Object, Strategy, Visitor TraversalGraph –Object, Visitor ObjectGraph –Strategy, Visitor ObjectGraphSlice –Visitor

60 Demeter and Aspects59 Traverse method arguments. Where is collection framework used? ClassGraph –gather(Object, Strategy) / asList(Object, Strategy) TraversalGraph –gather(Object) / asList(Object) ObjectGraph –gather(Strategy) / asList(Strategy) ObjectGraphSlice –gather() / asList()

61 Demeter and Aspects60 Where is collection framework used? ObjectGraphSlice.asList() –a fixed-size List backed by the object graph slice. Is write-through: modifying list will modify object and modifying object will modify list. (Similar to Arrays.asList() in Java.) gather copies the pointers to the objects.

62 Demeter and Aspects61 a:A u:U v:V c3:C c4:C x:X w:W c2:C c1:C gather() List v v.get(1).set_j(5); v.set(4, new C()); asList() List v c5:C

63 Demeter and Aspects62 Interfaces Interface List –ListIterator listIterator() –Object set(int index, Object element) Interface ListIterator –void set(Object o): replaces the last element returned by next or previous with the specified element.

64 Demeter and Aspects63 Why is asList useful? from Application to X: want to change all F-objects to D-objects. From Application to “predecessors” of D: put in a new object. –This is not structure-shy: all the predecessors of X also need to be mentioned.

65 Demeter and Aspects64 Why is asList useful? from Application to X: want to change all X-objects to D-objects. Application = List(E). E = X D. D = X F. X : F | D. F =. D = List(X). List(S) ~ {S}. Sketch: from Application to E: aE.set_x(new D()); aE.get_d().set_x(new D()); from E to D: update list elements from Application to X: set(new D())

66 Demeter and Aspects65 Why is asList useful? From A to B: want to change a B-object that satisfies some property. Does not matter whether it is in a list. A = B C. C = List(B).

67 Demeter and Aspects66 Some more theory Explaining paths in class graphs: –strategy S for a class graph G: S is subgraph of the transitive closure of G. –S defines path set in G as follows: PathSet st (S,G) is the set of all s-t paths in G that are expansions of any s-t path in S. –A path p is an expansion of path p’ if p’ can be obtained by deleting some elements from p.

68 Demeter and Aspects67 Relational Formulation From object o of class c1, to get to c2, follow edges in the set POSS(c1,c2,o)={e | c1 ( )* <= c2 } Can easily compute these sets for every c1, c2 via transitive-closure algorithms. POSS = abbreviation for: following these edges it is still possible to reach a c2-object. the following slides explain this view graph

69 Demeter and Aspects68 What is a path? If we only have concrete classes: no problem. Use the standard graph theoretic definition.

70 Demeter and Aspects69 A Path (A,B,E) A E B

71 Demeter and Aspects70 Traversals with Abstract Classes from A to E from A to B from A to C from A to D A E B DC

72 Demeter and Aspects71 Traversals to Abstract Classes from A to B = includes =>B,C and :>C,B etc. Motivation: –from A to E also includes subclasses of B A E B DC

73 Demeter and Aspects72 Path concept Path from A to B –include construction edges (forward) –inheritance edge implies subclass edge in opposite direction. –include inheritance edges (backward and forward). Backward inheritance edges are called subclass edges. –follow rule: after an inheritance edge, you are not allowed to follow a subclass edge.

74 Demeter and Aspects73 Path concept in flat class graphs Path from A to B: In flat class graph there is never a construction edge following an inheritance edge: (<=.C) = C From object o of class c1, to get to c2, follow edges in the set POSS(c1,c2,o)={e | c1 ( )* <= c2 }

75 Demeter and Aspects74 Requirements: for flat class graphs Paths in class graph turn into paths in object graph by deleting alternation edges and nodes and inheritance edges (Def. of corresponding path). A E B DC A -> B => C -> E A -> C -> E

76 Demeter and Aspects75 Requirements: for flat class graphs If there is a path in the class graph then there is a legal object of the class graph that has the same corresponding path. A E B DC A -> B => C -> E A -> C -> E Path in class graph => Exists object with path in object graph

77 Demeter and Aspects76 Requirements: for flat class graphs d1:D a1:Ab1:B A B C D Path in object graph => Exists corresponding path in class graph

78 Demeter and Aspects77 Requirements: for flat class graphs For a class graph G and legal object O, if there is a path p in the object graph then there is a path P in the class graph such that p corresponds to P. A E B DC A -> B => C -> E A -> C -> E

79 Demeter and Aspects78 More on semantics of DJ with abstract classes What is the meaning of a visitor on an abstract class?

80 Demeter and Aspects79 Traversals to Abstract Classes Class graph A E B DC visitor: before (B){p(“b”);} before (C){p(“c”);}

81 Demeter and Aspects80 Visitor Methods on Abstract Classes from A to E: b, c from A to B: b, c from A to C: b, c visitor: –before (B){p(“b”);} –before (C){p(“c”);} :A:A :E :C:C

82 Demeter and Aspects81 Visitor Methods on Abstract Classes from A to E: b from A to B: b from A to C: visitor: –before (B){p(“b”);} –before (C){p(“c”);} :A:A :E :D

83 Demeter and Aspects82 Visitor Rule When an object of class X is visited, all visitors of ancestor classes of X will be active. The before visitors in the downward order and the after visitors in the upward order.

84 Demeter and Aspects83 Traversals to Abstract Classes From A to C A E B DC visitor: void before (X host){p(“x”);} void before (B host){p(“b”);} void before (C host){p(“c”);} X

85 Demeter and Aspects84 Example in DemeterJ class graph in program.cd: A = B. X : B. B : C | D common E. C = “c”. D = “d”. E =.

86 Demeter and Aspects85 Behavior basically in DJ program.beh: Main { {{ // all Java code public static void main(Sring args[] … { A c = A.parse(“c”); A d = A.parse(“d”); ClassGraph cg = new ClassGraph(true,false); Visitor v = new Visitor() { void before (X host) {System.out.println(“x”);} void before (B host) {System.out.println(“b”);} void before (C host) {System.out.println(“c”);} }; System.out.println(“C-object:”); cg.traverse(c,”from A to C”,v); System.out.println(“D-object:”); cg.traverse(d,”from A to C”,v); } System.out.println(“Done.”); }} // end all Java code }

87 Demeter and Aspects86 Output C-object: x b c D-object: Done.

88 Demeter and Aspects87 Alternative Visitor Rule: not what programmers want When an object of class X is visited, all visitors of ancestor classes of X and in the path set of the current traversal will be active. The before visitors in the downward order and the after visitors in the upward order.

89 Demeter and Aspects88 Guidelines IF you use the combination of the following pairs and triples for multiple traversals, fetch or gather, introduce the following computation saving objects: (cg,s,o)->ogs (cg,s)->tg (cg,o)->og (tg,o)->ogs cg class graph sstrategy tgtraversal graph oobject ogobject graph ogs object graph slice v visitor Abbreviations In principle can express programs only with ClassGraph and Strategy and Visitor: cg.traverse(o,s,v); cg.fetch(o,s); cg.gather(o,s); cg.asList(o,s);

90 Demeter and Aspects89 DJ unary construction operations Class graph from Strategy –ClassGraph(Strategy): make a class graph with just the classes and edges in traversal graph determined by strategy. Interpret path set as a graph. Maintain several class graphs cg1, cg2, cg3 that are suitable for expressing what you need. Class graph from all classes in package

91 Demeter and Aspects90 ClassGraph construction make a class graph from all classes in default package –ClassGraph() include all fields and non-void no-argument methods. Static members are not included. –ClassGraph(boolean f, boolean m) If f is true, include all fields; if m is true, include all non-void no-argument methods.

92 Demeter and Aspects91 Dynamic features of DJ ClassGraph construction When a class is defined dynamically from a byte array (e.g., from network) ClassGraph.addClass(Class cl) has to be called explicitly. Class cl is returned by class loader. ClassGraph() constructor examines class file names in default package and uses them to create class graph.

93 Demeter and Aspects92 Dynamic features of DJ ClassGraph construction ClassGraph.addPackage(String p) –adds the classes of package p to the class graph. The package is searched for in the CLASSPATH. How can we control (f,m) options? Uses the same rule as used for the original class graph construction. Java has no reflection for packages. Motivates above solution.

94 Demeter and Aspects93 Adding Nodes and Edges to ClassGraph addClass(Class cl) –add cl and all its members to the class graph, if it hasn’t already been added. addClass(Class cl, boolean aF, boolean aM) –add cl to the class graph. If aF, add all its non- static fields as construction edges. If aM, add all its non-static non-void methods with no arguments as derived construction edges.

95 Demeter and Aspects94 Adding Nodes and Edges to ClassGraph Part addConstructionEdge(Field f) –add f as a construction edge. Part addConstructionEdge(Method m) –add a no-args method as a construction edge. addConstructionEdge may have in addition a String argument called source. For Impl. And also a Class argument called target. Also for Impl. Should not be public.

96 Demeter and Aspects95 Add other repetition edges void ClassGraph.addRepetitionEdge(String source, String target) –add a repetition edge from source to target Questions –what about subclass and inheritance edges –what happens if class graph contains edges not in program. Error will occur.

97 Demeter and Aspects96 Design and Implementation Until summer 1999: Josh Marshall Since then: Doug Orleans Available on the Web from DJ home page Quite complex Viewing an object as a list is done through coroutines to simulate continuation

98 Demeter and Aspects97 Problem with DJ What is coming is not about a problem of DJ but about a problem with Java: the lack of parameterized classes. The lack of parameterized classes forces the use of class Object which, as the mother of all classes, is too well connected. This leads to unnecessary traversals and traversal graphs that are too big.

99 Demeter and Aspects98 Lack of parameterized classes in Java makes DJ harder to use Consider the traversal: from A to B Let’s assume that in the class graph between A and B there is a Java collection class. The intent is: A = List(B) which we cannot express in Java. Instead we have: A = Vector(Object). Object : A | B. Let’s assume we also have a class X=B.

100 Demeter and Aspects99 Lack of parameterized classes in Java makes DJ harder to use We have: A = Vector(Object). Object : A | B | X. X = B. If the vector contains an X object it will be traversed!!! A X Object B Vector *

101 Demeter and Aspects100 A X Object B Vector * A XB * No X-object is allowed to be in vector

102 Demeter and Aspects101 Moral of the story If the Collection objects contain only the objects advertised in the nice class graph of the application the traversal done by DJ will be correct. But unecessary traversals still happen. However, if the Collection objects contain additional objects (like an X-object) they will be traversed accidentally.

103 Demeter and Aspects102 Moral of the story Java should have parameterized classes. Workaround: Use a JSR (Java Specification Request) 31 approach: use a schema notation with parameterization to express class graph and generate Java code from schema. For traversal computation, the schema will be used.

104 Demeter and Aspects103 Size of traversal graph DJ might create big traversal graphs when collection classes are involved. DJ will plan for all possibilities even though only a small subset will be realized during execution. To reduce the size of the traversal graph, you need to use bypassing. In the example: from A bypassing {A,X} to B.

105 Demeter and Aspects104 Technical Details Using DJ and DemeterJ

106 Demeter and Aspects105 Combining DJ and DemeterJ DJ is a 100% Java solution for adaptive programming. DemeterJ has –XML style data binding facilities: code generation from schema (class dictionary). –Its own adaptive programming language. We attempt an optimal integration giving us the strong advantages of both and only few small disadvantages.

107 Demeter and Aspects106 Optimal DJ and DemeterJ Integration Take all of DJ Take all of DemeterJ class dictionary notation Take a very tiny bit of DemeterJ adaptive programming language (basically only part that allows us to weave methods).

108 Demeter and Aspects107 Combining DJ and DemeterJ Pros (advantages) –Java class generation from class dictionary (getters, setters, constructors). –Parser generation. –Better packaging of Java code into different files. –MUCH MORE POWERFUL. Cons (disadvantages) –No longer pure Java solution. –need to learn Demeter notation for class dictionaries (similar to XML DTD notation). –need to learn how to call DemeterJ and how to use project files.

109 Demeter and Aspects108 Combining DJ and DemeterJ What do we have to learn about DemeterJ? –Class dictionaries: *.cd files –Behavior files: *.beh files. Very SIMPLE! A { {{ … }} } defines methods … of class A –Project files: *.prj list behavior files *.beh that you are using –Commands: demeterj new, demeterj test, demeterj clean

110 Demeter and Aspects109 Combining DJ and DemeterJ What you might forget in class dictionaries that are used with DJ: –import edu.neu.ccs.demeter.dj.*; –visitors need to inherit from Visitor –parts of visitors need to be defined in class dictionary

111 Demeter and Aspects110 Combining DJ and DemeterJ Structuring your files –put reusable visitors into separate behavior files. –put each new behavior into a separate behavior file. Visitors that are not planned for reuse should also go into same behavior file. Update the class dictionary with required structural information for behavior to work. –List all *.beh files in.prj file.

112 Demeter and Aspects111 End

113 Demeter and Aspects112 Hierarchical Traversals Computation : SimpleC | CompoundC. CompoundC = [ Object] [ StrategyString] [Kind] List(Computation). Kind : Ordered | Unordered. SimpleC = [what> Object] [ StrategyString] Object Visitor.

114 Demeter and Aspects113 traversal-related concerns with AC traversal AC –participants: ClassGraph, Strategy, TraversalGraph –provides a traversal following strategy –expects traversal strategy –expects class graph compatible with traversal strategy

115 Demeter and Aspects114 collaboration GEN_TRAV ClassGraph expects.class provides ClassGraph() provides traverse(Object this, String where) collaboration SUM int s = 0; Source Target replace traverse(…) {s++; next()} provide Object getReturnValue() DifferenceVisitorDJ { {{ // stack handling public void start() { stack = new Stack(); } public void before(Container o) { stack.push(sV.getReturnValue()); } public void after(Container o) { difference = ((Integer) sV.getReturnValue()).intValue() - ((Integer) stack.pop()).intValue(); } public Object getReturnValue() {return new Integer(difference);} }} collaboration DIFF Stack s = new Stack(); Target replace traverse(…) { stack.push(get_sb()); next(); diff =((Integer) get_se().intValue()- ((Integer) s.pop()).intValue; } expect Integer getsb(); expect Integer getse(); cd GEN_TRAV SUM need instances of collaborations

116 Demeter and Aspects115 collaboration GEN_TRAV ClassGraph expects.class provides ClassGraph() provides traverse(Object this, String where) collaboration SUM int s = 0; Source Target replace traverse(…) {s++; next()} Object getReturnValue() DifferenceVisitorDJ { {{ // stack handling public void start() { stack = new Stack(); } public void before(Container o) { stack.push(sV.getReturnValue()); } public void after(Container o) { difference = ((Integer) sV.getReturnValue()).intValue() - ((Integer) stack.pop()).intValue(); } public Object getReturnValue() {return new Integer(difference);} }} collaboration DIFF expect Collaboration sum; int difference; Stack s = new Stack(); Source replace traverse(…) { stack.push(sum.getReturnValue()); next(); difference =((Integer) sum.getReturnValue().intValue()- ((Integer) s.pop()).intValue; } Object getReturnValue() {return new Integer(difference);} cd GEN_TRAV sum:SUM CheckingVisitorDJ { {{ public void start() { violations=0; System.out.println("begin"); } public void before(Container o) { System.out.println(" start new container ");} public void after(Container host) { int cap = host.get_capacity().get_i().intValue(); int diff = ((Integer) iV.getReturnValue()).intValue(); if (diff > cap) { this.set_violations(get_violations() + 1); System.out.println(" total weight " + diff + " but limit is = " + cap + " OVER CAPACITY "); }; System.out.println(" end container "); } public Object getReturnValue() {return new Integer(violations);} }} } collaboration CHECK expect Collaboration diff; int violations = 0; Source expect int get_capacity(); replace traverse(…) {next(); cap = host.get_capacity().get_i().intValue(); int d = ((Integer) diff. getReturnValue()).intValue(); if (d > cap) violations++; } in all: traverse: from Source to Target collaboration CHECKC Container = … Weight = … adapt GEN_TRAV from Container to Weight adapt SUM export as sumA Source : Container Target : Container adapt DIFF as diffA Source : Container sum : sumA adapt CHECK Source : Container diff : diffA export traverse as check

117 Demeter and Aspects116 Traversal Summing before Weight Difference before Container after Container Checking after Container before Weight before Container after Container before Container after Container Event based view of traversals and visitors sdv Summary of code Summary of data flow Summary of event flow

118 Demeter and Aspects117 Traversal Summing before Weight return s Difference before Container after Container return d Checking after Container return v before Weight before Container after Container before Container after Container Event based view of traversals and visitors sdv Summary of code Summary of data flow Summary of event flow

119 Demeter and Aspects118 Visitor classes as components Summing DifferenceChecking total diff s sum what? get_value check what? get_capacity return strategy class graph visitor class return

120 Demeter and Aspects119 Container capacity problem traversal allWeights(CheckingVisitor cV, DifferenceVisitor dV, SummingVisitor sV) {to Weight;} int checkCapacity() {{ CheckingVisitor cV = new CheckingVisitor(); DifferenceVisitor dV = new DifferenceVisitor(); SummingVisitor sV = new SummingVisitor(); cV.set_dV(dV); dV.set_sV(sV); //link behaviors this.allWeights(cV, dV, sV); // call traversal with visitors return (cV.get_return_val()); }} cannot avoid all tangling, but can localize it. No longer spread over several classes.

121 Demeter and Aspects120 abstract aspect CapabilityChecking { pointcut invocations(Caller c): this(c) && call(void Service.doService(String)); pointcut workPoints(Worker w): target(w) && call(void Worker.doTask(Task)); pointcut perCallerWork(Caller c, Worker w): cflow(invocations(c)) && workPoints(w); before (Caller c, Worker w): perCallerWork(c, w) { w.checkCapabilities(c); }

122 Demeter and Aspects121 Declarative Techniques for Improving Aspect Orthogonality Karl Lieberherr

123 Demeter and Aspects122 Why improve orthogonality of aspects? Crucial for Aspect Libraries: otherwise aspects require too many modifications for reuse. Danger of being too orthogonal? Not really, if the actual parameters are checked carefully for applicability: need good type systems for AOP. Improve orthogonality by parameterization.

124 Demeter and Aspects123 How we got to Aspect-Oriented Programming Started simple: traversal-seeded programs: Law of Demeter dilemma. Talk generically about points in the execution of a traversal program. Generically means: parameterize program by an abstraction of its execution. Some type checking when actual parameter is known.

125 Demeter and Aspects124 Modularization of crosscutting concerns Write this public class Shape { protected double x_= 0.0, y_= 0.0; protected double width_=0.0, height_=0.0; double get_x() { return x_(); } void set_x(int x) { x_ = x; } double get_y() { return y_(); } void set_y(int y) { y_ = y; } double get_width(){ return width_(); } void set_width(int w) { width_ = w; } double get_height(){ return height_(); } void set_height(int h) { height_ = h; } void adjustLocation() { x_ = longCalculation1(); y_ = longCalculation2(); } void adjustDimensions() { width_ = longCalculation3(); height_ = longCalculation4(); } coordinator Shape { selfex adjustLocation, adjustDimensions; mutex {adjustLocation, get_x, set_x, get_y, set_y}; mutex {adjustDimensions, get_width, get_height, set_width, set_height}; } portal Shape { double get_x() {} ; void set_x(int x) {}; double get_y() {}; void set_y(int y) {}; double get_width() {}; void set_width(int w) {}; double get_height() {}; void set_height(int h) {}; void adjustLocation() {}; void adjustDimensions() {}; } Instead of writing this public class Shape implements ShapeI { protected AdjustableLocation loc; protected AdjustableDimension dim; public Shape() { loc = new AdjustableLocation(0, 0); dim = new AdjustableDimension(0, 0); } double get_x() throws RemoteException { return loc.x(); } void set_x(int x) throws RemoteException { loc.set_x(); } double get_y() throws RemoteException { return loc.y(); } void set_y(int y) throws RemoteException { loc.set_y(); } double get_width() throws RemoteException { return dim.width(); } void set_width(int w) throws RemoteException { dim.set_w(); } double get_height() throws RemoteException { return dim.height(); } void set_height(int h) throws RemoteException { dim.set_h(); } void adjustLocation() throws RemoteException { loc.adjust(); } void adjustDimensions() throws RemoteException { dim.adjust(); } class AdjustableLocation { protected double x_, y_; public AdjustableLocation(double x, double y) { x_ = x; y_ = y; } synchronized double get_x() { return x_; } synchronized void set_x(int x) {x_ = x;} synchronized double get_y() { return y_; } synchronized void set_y(int y) {y_ = y;} synchronized void adjust() { x_ = longCalculation1(); y_ = longCalculation2(); } class AdjustableDimension { protected double width_=0.0, height_=0.0; public AdjustableDimension(double h, double w) { height_ = h; width_ = w; } synchronized double get_width() { return width_; } synchronized void set_w(int w) {width_ = w;} synchronized double get_height() { return height_; } synchronized void set_h(int h) {height_ = h;} synchronized void adjust() { width_ = longCalculation3(); height_ = longCalculation4(); } interface ShapeI extends Remote { double get_x() throws RemoteException ; void set_x(int x) throws RemoteException ; double get_y() throws RemoteException ; void set_y(int y) throws RemoteException ; double get_width() throws RemoteException ; void set_width(int w) throws RemoteException ; double get_height() throws RemoteException ; void set_height(int h) throws RemoteException ; void adjustLocation() throws RemoteException ; void adjustDimensions() throws RemoteException ; }

126 Demeter and Aspects125 Scattering: count number of components to which color goes ordinary program structure-shy functionality object structure synchronization aspect-oriented prog. Concern 1 Concern 2 Concern 3 COM1 COM2 COM3

127 Demeter and Aspects126 Language for Examples: AspectJ Xerox PARC: Gregor Kiczales et al.: lingua franca of AOP. First version: Crista Lopes (member of Demeter group): implementing both COOL and RIDL in a general purpose AO language (early AspectJ version). Model: join points, pointcuts, advice.

128 Demeter and Aspects127 Pointcut –set of execution points of any method, … –rich set of primitive pointcuts: this, target, call, … + set operations –where to enhance Advice –how to enhance Visitor method sig. –set of execution points of traversals –specialized for traversals (nodes, edges) –where to enhance Visitor method bodies –how to enhance Demeter (for C++ or Java)AspectJ From Demeter to AspectJ

129 Demeter and Aspects128 Java+DJ AspectJ aspect Traversal { // t() //declare traversal t : // “from S” + c + “to T”; … } aspect Collecting { pointcut start() : … ; pointcut visitingT(T h): call(void t()) && target(h); before():start(){ … } before():visitingT(){ … } } class S{ HashSet collect(ClassGraph cg, String constraint){ String s = “from S” + constraint + “to T”; return (HashSet) cg.traverse(this, s, new Visitor(){ … ; public void before (T h) { … } public void start() {…}}); } green: pointcut purple: advice red = aspect name From Demeter to AspectJ

130 Demeter and Aspects129 AspectJ Java+DJ aspect SimpleTracing { pointcut traced(): call(void D.update()}|| call(void D.repaint(); before():traced(){ println(“Entering:”+ thisJoinPoint);} } class Source{ HashSet collect(ClassGraph cg, String constraint){ String s = “from Source” + constraint + “to Target”; return (HashSet) cg.traverse(this, s, new Visitor(){ … ; public void before (Target h) { … } public void start() {…}}); } AspectJ: refers to existing join points Demeter: defines new join points in traversal green: pointcut purple: advice red = aspect name

131 Demeter and Aspects130 Parameterization by abstraction of program execution pointcut AaB(A a1, B b1): cflow(vis_A(a1)) && vis_B(b1); pointcut vis_A(A a1): call(void t (..)) && target(a1); pointcut vis_B(B b1): … Pointcut AaB can be used with many different base programs. Parameterization is implicit.

132 Demeter and Aspects131 Parameterization by abstraction of program execution pointcut AaBaC(A a1,B b1,C c1): cflow(cflow(vis_A(a1)) && vis_B(b1)) && vis_C(c1); pointcut vis_A(A a1): call(void t (..)) && target(a1); pointcut vis_B(B b1): … pointcut vis_C(C c1): … A=CompilationUnit B=MetaSetRule C=Name: Verizon 24*7 app.

133 Demeter and Aspects132 Equation System usedThings = from EquationSystem through Expression to Variable EquationSystem Equation_List Equation Variable equations * lhs rhs Expression Simple Compound Numerical Expression_List * Add op args Ident S D T B

134 Demeter and Aspects133 Adding Demeter to AspectJ Adding more flow constructs; Demeter traversals flow construct for object graphs: –declare traversal t = … flow construct for class graphs: type patterns: –nodes(t): all nodes in scope of t Adding grammar aspect … (a la JAXB)

135 Demeter and Aspects134 Adding Demeter Traversals to AspectJ Because the AspectJ join point model is a generalization of Demeter’s join point model, we can use the AspectJ pointcuts to express the traversal pointcuts. However, this would expose the traversal implementation. Extend AspectJ with two new pointcut primitives: traversal(t) and crossing(e).

136 Demeter and Aspects135 New pointcuts Traversal(t = from A via B to C): The set of all join points in the traversal that finds all C-objects contained in a B-object contained in an A-object. pointcut visiting_C(C c1): traversal(t) && target(c1); pointcut visiting_e(S s,T t): traversal(t) && && crossing(e) && this(s) && target(t);

137 Demeter and Aspects136 Traversal(t) pointcut picks out all join points between the start and the end of the traversal that are needed for the traversal only, i.e. the node visits and the edge visits.

138 Demeter and Aspects137 How to define a traversal AspectJ declare form declare traversal t: traversal specification; traversal specification: an automaton

139 Demeter and Aspects138 Conclusions AspectJ is well-aligned with Demeter. Need only a small extension to add the Demeter traversals. Pointcuts become more verbose. Could also use traversals with visitors and extend them with AspectJ (use the args pointcut).

140 Demeter and Aspects139 more integration traversal(t) && crossing(“xyz”) && this(a) && target(b) && args(v1, tS) explanation: traversal t through edge xyz with source a and target b. The visitor is v1 and the token set is tS. tS allows us to query the state of the traversal: we can ask which strategy graph edges are currently active.

141 Demeter and Aspects140 traversal(t) && cflow(call( * f(..)): all join points join(traversal(t1), traversal(t2)) traversal(t1) || traversal(t2) traversal(t1) && !traversal(t2) traversal(“from A to B”) && !traversal( “from A via X to B”) = from A bypassing X to B

142 Demeter and Aspects141 cflow is traversal the only pcd where we want nesting with advice?

143 Demeter and Aspects142 difference between visiting(a) and this(a) and target(a) traversal(t): target(a) = visiting(a) this(a) where traversal was before getting to a-object

144 Demeter and Aspects143 dynamic call graph aCompany.t() aCompany.t_domesticDivisions() aCompany.t_foreignDivisions() aCompany.domesticDivisions a_d_DivisionList.t() aCompany.foreignDivisions a_f_DivisionList.t() 1 2 1 2 1 2

145 Demeter and Aspects144 dynamic call graph a_d_DivisionList.t() a1Division.t () a1Division.departments aDepartmentList.t() 1 2 a1Division.t_departments () a2Division.t () etc. 21

146 Demeter and Aspects145 From Adaptive to Aspect- Oriented Programming Object-graphs are turned into dynamic call graphs by traversal methods produced from the class graph and a traversal specification. As we go through dynamic call graph, we want to collect information from arguments and return values of method calls. Exploit regularities in call graphs.

147 Demeter and Aspects146 Motivation Declarative techniques used in existing AOP systems Look at a family of declarative techniques: use one uniform syntax and three different semantics.

148 Demeter and Aspects147 Flow Expressions D ::= [A,B] | join(D1,D2) | merge(D1,D2) We can use them in three different graphs relevant to programming: –call trees: subset of nodes –class graphs: subset of nodes –object trees: subgraph

149 Demeter and Aspects148 Flow Expressions and AOP They are a basic cross-cutting construct for defining subgraphs. merge(join([A,X],[X,C]), join([A,Y],[Y,C])) defines a subgraph of a larger graph whose ad-hoc description cuts across many nodes or edges. succinct encapsulations of subgraphs related to some aspect. A C X Y

150 Demeter and Aspects149 Flow expressions are abstractions of some aspect whose ad-hoc description would cut across many nodes or edges of a graph. define sets of join points based on connectivity in graph. offer pointcut designator reduction (high-level pointcut designator): free programmer from details of some graph representing some aspect.

151 Demeter and Aspects150 Definitions for Flow Expressions D ::= [A,B] | join(D1,D2) | merge(D1,D2) Source([A,B]) = A Target([A,B]) = B Source(join(D1,D2) )=Source(D1) Target(join(D1,D2) )=Target(D2) Source(merge(D1,D2) )=Source(D1) Target(merge(D1,D2) )=Target(D1)

152 Demeter and Aspects151 Well-formed Flow Expressions D ::= [A,B] | join(D1,D2) | merge(D1,D2) WF([A,B]) = true // well-formed WF(join(D1,D2) )=WF(D1) && WF(D2) && Target(D1) = Source(D2) WF(merge(D1,D2) )= WF(D1) && WF(D2) && Source(D1)=Source(D2) && Target(D1)=Target(D2)

153 Demeter and Aspects152 Dynamic call tree nodes are operation calls: labeled by operation name and arguments edges: a operation calls another operation nodes = join points

154 Demeter and Aspects153 abstract aspect CapabilityChecking { pointcut invocations(Caller c): this(c) && call(void Service.doService(String)); pointcut workPoints(Worker w): target(w) && call(void Worker.doTask(Task)); pointcut perCallerWork(Caller c, Worker w): cflow(invocations(c)) && workPoints(w); before (Caller c, Worker w): perCallerWork(c, w) { w.checkCapabilities(c); } context-passing aspects

155 Demeter and Aspects154 Interpretation of traversal strategies D ::= [A,B] | join(D1,D2) | merge(D1,D2) A and B are pointcut designators. [A,B]: the set of B-nodes reachable from A- nodes. join(D1,D2): the set of Target(D2)-nodes reachable from Source(D1)-nodes following D1 and then following D2.

156 Demeter and Aspects155 Interpretation of traversal strategies merge(D1,D2): the union of the set of Target(D1)-nodes reachable from Source(D1)-nodes following D1 and the set of Target(D2)-nodes reachable from Source(D2)-nodes following D2.

157 Demeter and Aspects156 Translation Rules t(D1) flow(A) && B t(D1) || t(D2) flow(t(D1)) && t(D2) D1 from A to B merge(D1,D2) join(D1,D2)

158 Demeter and Aspects157 Class graph D [A,B] join(D1,D2) merge(D1,D2) PathSet(D) Paths(A,B) PathSet(D1).PathSet(D2) PathSet(D1) || PathSet(D2) we are only interested in the set of nodes touched by the path sets -> subgraph of class graph flow expressions are called traversal strategies Demeter/C++ DJ Type patterns in AspectJ

159 Demeter and Aspects158 Object tree D [A,B] subgraph of O subgraph of O consisting of all paths from an A-node to a B-node, including prematurely terminated paths. flow expressions are called traversal strategies Demeter/C++ DemeterJ DJ generate traversals in AspectJ

160 Demeter and Aspects159 Object tree D join(D1,D2) subgraph of O subgraph of O consisting of all paths following D1 and those reaching Target(D1) concatenated with all paths following D2.

161 Demeter and Aspects160 Object tree D merge(D1,D2) subgraph of O subgraph of O consisting of all paths following D1 or following D2.

162 Demeter and Aspects161 Purposes of strategies DJ Traversal –strategy graph –class graph –object graph Purposes –select og with sg extract node labels –select cg with sg AspectJ General computation –strategy call graph –static call graph –dynamic call graph Purposes –select dcg with sycg extract node labels –select scg with sycg

163 Demeter and Aspects162 Purposes of strategies DJ + method edges Traversal –strategy graph –class graph –object graph –argument map Purposes –select dcg with sg + am extract node labels

164 Demeter and Aspects163 Correspondences t(D1) flow(A) && B flow(A) flow(flow(A) && B) && C flow(flow(flow(A) && B) && C) && E (flow(flow(A) && B1) && C) || (flow(flow(A) && B2) && C) t(D1) || t(D2) flow(t(D1)) && t(D2) flow(flow(A) && B) && (flow(B) && C) = flow(flow(A) && B) && C D1 from A to B from A to * from A via B to C from A via B via C to E merge(from A via B1 to C, from A via B2 to C) merge(D1,D2) join(D1,D2) join (from A to B, from B to C) subset(flow(B)) && flow(B) = subset(flow(B))

165 Demeter and Aspects164 Theme Defining high-level artifact in terms of a low-level artifact without committing to details of low-level artifact in definition of high-level artifact. Low-level artifact is parameter to definition of high-level artifact. Exploit structure of low-level artifact.

166 Demeter and Aspects165 AspectJ adds Generalizes from join points of specialized methods to join points of any method, field access, field modification, etc. Uses set operations && and ! combined with a rich set set of primitive pointcuts. Generalizes from a flow construct for traversals to a flow construct for arbitrary join points.

167 Demeter and Aspects166 Discussion with Gregor Kiczales at UBC Ontology of AOP Ontology is the study of what there is, an inventory of what exists. An ontological commitment is a commitment to an existence claim for certain entities.

168 Demeter and Aspects167 basis of crosscutting a join point model (JPM) has 3 critical elements –what are the join points in AspectJ –points in runtime –means of identifying join points in AspectJ –signatures (plus …) –means of specifying semantics at join points in AspectJ –advice –define members

169 Demeter and Aspects168 Range of AOP languages means of … join points add memberssignaturesclass members static JPM DemeterJ, Demeter/C++ dynamic JPM 1 static JPM 1 static JPM 2 static JPM 3 AspectJ dynamic JPM JPM when traversal reaches object or edge class members points in execution call, get, set… join points visitor method signatures traversal spec. s class graph g class names class graph signatures w/ wildcards & other properties of JPs identifying visitor method bodies s + g (result = traversal implementation) add members class graph with tokens=grammar (result = parsing and printing implementation) advice specifying semantics at

170 Demeter and Aspects169 Range of AOP languages means of … join points add memberssignaturesclass members static JPM DJ dynamic JPM 1 dynamic JPM 2 static JPM 4 AspectJ dynamic JPM JPM when traversal reaches object or edge (method traverse) when traversal reaches object (methods fetch, gather, asList) nodes in object graph o points in execution call, get, set… join points visitor method signatures source and targets of traversal trav. spec. s class graph g signatures w/ wildcards & other properties of JPs identifying visitor method bodies method name (fetch, gather, asList) s+g (result = traversal impl. = edges to traverse at nodes in object graph o) advice specifying semantics at

171 Demeter and Aspects170 Combining two join point models Static JPM 1: In Demeter we use traversal specifications and the class graph to define a traversal implementation (either static or dynamic) Visitor JPM 1: The result of static JPM 1 is used to define a second JPM: –The traversal implementation defines nodes and edge visits. –Visitor signatures define the nodes and edges where additional advice is needed: they are the means of identifying join points. –The means of specifying semantics at join points are the visitor bodies.

172 Demeter and Aspects171 DJ: static JPM 4 The join points are nodes in object graphs. They are not dynamic call graph join points nor class members! The means of identifying the join points for a given object graph o are a strategy s and the class graph g. o must conform to g. The means of specifying the semantics at the join points are again s and g. See paper with Mitch Wand for the formal details behind this JPM.

173 Demeter and Aspects172 DemeterJ: static JPM 1 The means of identifying the join points and of specifying the semantics at the join points are the same. The reason is that s+g both –select the classes that will get traversal semantics –determine the details of the traversal semantics

174 Demeter and Aspects173 DemeterJ: static JPM 3 The means of identifying the join points (class members) is done by the class graph. When we add tokens to the class graph we get a grammar that contains instructions for parsing and printing behavior. A grammar is an aspect (external representation aspect): the adhoc implementation cuts across all classes.

175 Demeter and Aspects174 Software Design and Development with DJ (very brief) Functional decomposition into generic behavior –Decomposition into methods Decomposition into strategies Decomposition into visitors Adaptation of generic behavior –Identify class graph –Refine strategies


Download ppt "Demeter and Aspects1 AOSD 2002 Tutorial: Demeter Aspect-Oriented Programming of Traversal Related Concerns in Java Demeter Research Group."

Similar presentations


Ads by Google