Title: Aspectual Components Part 2
1Aspectual ComponentsPart 2
2Composition example
- Use three aspects simultaneously with three
classes. - Three aspects
- ShowReadWriteAccess
- InstanceLogging
- AutoReset
- Three classes Point, Line, Rectangle
3Weaved Code
Shapes (Point, Line, Rectangle)
AutoReset
ShowReadWriteAccess
Point
Line
InstanceLogging
Rectangle
4Inheritance between components
- component ShowReadWriteAccess extends
ShowReadAccess - participant DataToAccess
- expect void writeOp(Object args)
- replace void writeOp(Object args)
- System.out.println(
- "Write access on "
- this.toString())
- expected(args)
-
5InstanceLogging component(first part)
- component InstanceLogging
- participant DataToLog
- expect public DataToLog(Object args)
- replace public DataToLog(Object args)
- expected(args)
- long time System.currentTimeMillis()
- try
- String class this.class.getName() "
" - logObject.writeBytes(""New instance of "
class - at "" " time "" " \n")
- catch (IOException e)
- System.out.println(e.toString())
-
-
6InstanceLogging component(second part)
- protected DataOutputStream logObject null
- public init()
- try logObject new DataOutputStream(
- new FileOutputStream(log))
- catch (IOException e)
- System.out.println(e.toString())
-
-
7AutoReset component
- component AutoReset
- participant DataToReset
- expect void setOp(Object args)
- expect void reset()
- protected int count 0
- replace void setOp(Object args)
- if ( count gt 100 )
- expected(args)
- count 0
- reset()
-
-
-
8Composition of components
- connector CompositionConn1
- Line, Point is ShowReadWriteAccess.DataToAcces
s with - readOp get writeOp set
- Point is AutoReset.DataToReset with
- setOp set
- void reset() x 0 y 0
-
- Line, Point, Rectangle is
- InstanceLogging.DataToLog
9Weaved Code
Shapes
AutoReset
ShowReadWriteAccesses
Point
Line
InstanceLogging
Rectangle
10Composition of components
- Connector graph CompositionConn1
- Line, Point,
Rectangle - ShowReadWriteAccess.DataToAccess
- AutoReset.DataToReset
- InstanceLogging.DataToLog
11Modified composition
- connector CompositionConn2 extends
CompositionConn1 - Line is AutoReset.DataToReset with
- setOp set
- void reset() init()
-
-
-
12Composition of components
- Connector graph CompositionConn1
- Line, Point,
Rectangle - ShowReadWriteAccess.DataToAccess
- AutoReset.DataToReset
- InstanceLogging.DataToLog
- Connector graph CompositionConn2
- Line, Point,
Rectangle - ShowReadWriteAccess.DataToAccess
- AutoReset.DataToReset
- InstanceLogging.DataToLog
13Modify existing connection statements
- connector CompositionConn3 extends
CompositionConn1 - Point is AutoReset.DataToReset with
- setOp set
- void reset()
- x 0 y 0
- setOp setX
- void reset() x 0
-
- setOp setY
- void reset() y 0
-
-
14Composition of components
- Connector graph CompositionConn3
- Line, Point,
Rectangle - ShowReadWriteAccess.DataToAccess
- AutoReset.DataToReset
- InstanceLogging.DataToLog
- overridden
15New example Feature-oriented Programming
- Dependent aspects
- Order of deployment is relevant
16DataWithCounter componentpairwise interaction
Data/Counter
- component DataWithCounter
- private participant Counter int i0
- void reset()i0 void inc() void
dec() - participant DataStructure
- protected Counter counter
- expect void initCounter()
- expect void make_empty()
- expect void push(Object a)
- expect void pop()
- replace void make_empty()counter.reset()e
xpected() - replace void push(Object a)counter.inc()
expected(a) - replace void pop() counter.dec()expected(
) -
-
17DataWithLock Componentpairwise interaction
Data/Lock
- component DataWithLock
- participant Data
- Lock lock
- expect void initLock()
- expect AnyType method_to_wrap(Object
args) - replace AnyType method_to_wrap(Object
args) - if (lock.is_unlocked())
- lock.lock()
- expected(Object args)
- lock.unlock()
- private participant Lock boolean l true
- void lock()
- void unlock()
- boolean is_unlocked()return l
18DataWithCounter
StackImpl
Counter
QueueImpl
Lock
DataWithLock
19First connector
- connector addCounterLock
- StackImpl is DataWithCounter.DataStructure
- with
- void initCounter() counter new Counter()
- void push(Object obj) push(obj)) // use
name map instead - Object top() return top()
- ...
- is DataWithLock.Data
- with
- method_to_wrap pop, push, top,
make_empty, initCounter -
- QueueImpl is DataWithCounter.DataStructure with
- ... is DataWithLock.Data with ...
-
20DataWithCounter
DataWithLock
DataWithCounterLock
21Create composed aspects prior to deployment
- component DataWithCounterAndLock
- participant Data
- DataWithCounter.DataStructure is
- DataWithLock.Data with
- method-to-wrap
- make_empty, pop, top, push
-
22Second connector Deploy composed component
- connector addCounterLock
- StackImpl is DataWithCounterAndLock.Data with
- void make_empty() empty()
- void initCounter()
- counter new Counter()
- void push(Object obj) push(obj)
- ...
-
- QueueImpl is DataWithCounterAndLock.Data with
... -
23Defining New Behavior The Publisher-Subscriber
Aspect
- an aspect can be multiply deployed with the same
application, each deployment with its own
mappings.
24Publisher
- component PublisherSubscriberProtocol
- participant Publisher
- expect void changeOp(Object args)
- protected Vector subscribers new
Vector() - public void attach(Subscriber subsc)
- subscribers.addElement(subsc)
- public void detach(Subscriber subsc)
- subscribers.removeElement(subsc)
- replace void changeOp()
- expected()
- for (int i 0 i lt subscribers.size()
i) - ((Subscriber)subscribers.elementAt(i)
). - newUpdate(this)
25Subscriber
- participant Subscriber
- expect void subUpdate(Publisher publ)
- protected Publisher publ
- public void newUpdate(Publisher aPubl)
- publ aPubl
- subUpdate(publ)
-
-
-
26Class for deployment
- class ChangePrinter
- void public printR()
- System.out.println("Printer "
this.toString() - " read access has occurred ..."
\n) -
- void public printW()
- System.out.println("Printer "
this.toString() - " write access has occurred
..." \n) -
- void public notifyChange() System.out.println(
"CHANGE ...") -
-
27Deployment 1
- connector PubSubConn1
- Point is Publisher with
- changeOp set, get
- ChangePrinter is Subscriber with
- void subUpdate(Publisher publ)
- notifyChange()
- System.out.println(on Point object "
- ((Point) publ).toString())
-
-
-
28Deployment 2
- connector PubSubConn2
- TicTacToe is Publisher with
- changeOp startGame, newPlayer, putMark,
- endGame
- BoardDisplay, StatusDisplay is Subscriber
with - void subUpdate(Publisher publ)
- setGame((Game) publ)
- repaint()
-
-
-
29Deployment/write
- connector PubSubConn3
- Point is Publisher with changeOp set
- ChangePrinter is Subscriber with
- void subUpdate(Publisher publ)
- printW()
- System.out.println("on point object "
- ((Point) publ).toString())
-
-
-
30Deployment/read
- connector PubSubConn4
- Point is Publisher with changeOp get
- ChangePrinter is Subscriber with
- void subUpdate(Publisher publ)
- printR()
- System.out.println("on point object "
- ((Point) publ).toString())
-
-
-
31Overlap between connectors
- The sets of operations of Point that are mapped
to different notification operations of the
subscriber participant need not be disjoint. For
instance, we may want to distinguish between set
operations that affect the x-coordinate,
respectively, the y-coordinate of a point. - The set(int, int), however, will then fall in
both categories. This is expressed by the
connectors PubSubConn3_1 and PubSubConn3_2
below.
32Deployment/write
- connector PubSubConn3_1
- Point is Publisher with changeOp
set,setX - ChangePrinter is Subscriber with
- void subUpdate(Publisher publ)
- printW()
- System.out.println("on point object "
- ((Point) publ).toString())
-
-
-
33Deployment/write
- connector PubSubConn3_2
- Point is Publisher with changeOp set,
setY - ChangePrinter is Subscriber with
- void subUpdate(Publisher publ)
- printW()
- System.out.println("on point object "
- ((Point) publ).toString())
-
-
-
34Mapping Participant Graphs
- Is the deployment of a component giving the
intended result? - Example Three participants A, B, C
- A has 0.. B B has 1.. C.
- Af(int x1)for each b f(x1)
- Bf(int x1)for each c f(x) // x a local data
member - Cf(int x1)print(at C number at previous B)
print(x1)
35Expected output
- at C number at previous B 78
- at C number at previous B 8
36Mapping
A
B
C
0..
1..
A
C
B
37Refinement
- This property must hold between a PG and a
corresponding CG or another PG. The intent of the
refinement relation is to ensure that the
behavior in the component will be properly
instantiated at the place of use without
surprising'' behavior.
38G1 refinement G2
F
F
D
D
E
E
B
B
C
C
G2
refinement connectivity of G2 is in pure form in
G1 Allows extra connectivity.
G1
A
A
39G1 refinement G2
F
F
D
D
E
E
B
B
C
C
G2
G1
refinement connectivity of G2 is in pure form in
G1
A
A
40G1 compatible G2
F
F
D
D
E
E
B
B
C
C
G2
Compatible connectivity of G2 is in G1
G1
A
A
41G1 strong refinement G2
F
F
D
D
E
E
B
B
C
C
G2
refinement connectivity of G2 is in pure form in
G1 and G1 contains no new connections in terms
of nodes of G2
G1
A
A
42Key concepts refinement
- Let G1(V1,E1) and G2(V2,E2) be directed graphs
with V2 a subset of V1. Graph G1 is a refinement
of G2 if for all u,v in V2 we have that (u,v) in
E2 implies that there exists a path in G1
between u and v which does not use in its
interior a node in V2. - Polynomial time.
43Refinement
- For each edge in G2 there must be a corresponding
pure path in G1. - Pure path in interior no nodes of G2.
- Refinement strong refinement with if and only
if replaced by implies.
44G1 refinement G2
F
F
D
D
E
E
B
B
C
C
G2
Implementation create strategy constraint map
bypassing all nodes
G1
A
A
45Refinement means no surprises
not G1 refinement G2
B
C
C
B
G2
A
G1
A
46Refinement means no surprises
G1 refinement G2
B
C
C
B
X
G2
A
G1
A
47Refinement means no surprises
not G1 refinement G2
B
C
B
C
G2
G1
A
A
48Alternative definition
- a graph G is a refinement of a graph S, if S is a
connected subgraph of the pure transitive closure
of G with respect to the node set of S.
49Pure transitive closure
- The pure transitive closure of G(V,E) with
respect to a subset W of V is the graph
G(V,E), where E(i,j) there is a W-pure
path from vertex i to vertex j in G. - A W-pure path from i to j is a path where i and j
are in W and none of the inner nodes of the path
are in W.
50Implementation issues
- Translate to AspectJ requires source code
access. - What if aspectual components only in binary?
- Want separate compilation of application and
aspectual components.
51Interfaces between components and application
- Usage interface
- expected in order to be used by participants
- Modification interface
- expected in order to be replaced by the aspect
52Writing components directly in Java
- Benefit no new language to learn
53Participants as abstract classes
- class AutoReset
- abstract class DataToReset
- abstract void reset()
- protected int count 0
- void replaced_setOp(Object thisObject, Class
thisClass, - Method expected_setOp,
Object args) - if ( count gt 100 )
- expected_setOp.invoke(thisObject, args)
- count 0
- reset()
-
-
-
-
54AutoReset component
- component AutoReset
- participant DataToReset
- expect void setOp(Object args)
- expect void reset()
- protected int count 0
- replace void setOp(Object args)
- if ( count gt 100 )
- expected(args)
- count 0
- reset()
-
-
-
55What about connectors in Java?
- Translation to Java not straight-forward
56Approach
- Methods in
- usage interface abstract methods
- modification interface x() translated to
replaced_x(). Expected implementation of x() will
be a parameter to replaced_x(). - xsetOp
- void replaced_setOp(Object thisObject, Class
thisClass, - Method expected_setOp,
Object args) - if ( count gt 100 )
- expected_setOp.invoke(thisObject, args)
57Approach
- Question Why is thisClass used as an argument?
Is not used in this example. - void replaced_setOp(Object thisObject, Class
thisClass, - Method expected_setOp,
Object args) - if ( count gt 100 )
- expected_setOp.invoke(thisObject, args)
58Binary Adaptation of Application Classes
- Application classes are turned into event
publishers by adding a field that stores a set of
subscribers (from connectors). - Any application operation op that is mapped to
expected operation in modification interface
renamed to expected_op - new implementation of op invokes notify on
subscribers
59Pseudo-code simulating binary adaptation
- class Point
- public static java.util.Vector
aspectSubscribers - // added variable
- public void addSubscriber(AspectSubscriber
sub) - // added operation
- aspectSubscribers.addElement((Object)
sub) - private int x 0
- private int y 0
60Pseudo-code simulating binary adaptation
- void expected_set(int x, int y) // renamed
- this.x x this.y y
- void set(int x, int y) //
reimplemented - Object args
- (Object) new Integer(x), (Object) new
Integer(y) - Class argTypes Integer.TYPE,
Integer.TYPE - Method expected_set
- thisClass.getMethod("expected_set",
argTypes) - Enumeration subscribers
aspectSubscribers.elements() - while (subscribers.hasElements())
- Object sub subscribers.next()
- sub.notify(this, this.getClass(),
expected_set, args)