4th International Conference on Principles and Practices ... - MADOC
4th International Conference on Principles and Practices ... - MADOC
4th International Conference on Principles and Practices ... - MADOC
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
UI as a state machine in Spring Web Flow [18] <strong>and</strong> domaindriven<br />
design as implemented in Ruby <strong>on</strong> Rails [16] or<br />
RIFE/Crud [15]. This often requires framework support<br />
for dynamic compositi<strong>on</strong> <strong>and</strong> comp<strong>on</strong>ent run-time c<strong>on</strong>figurati<strong>on</strong>.<br />
3. CORE ABSTRACTIONS<br />
Aranea framework is based <strong>on</strong> the abstracti<strong>on</strong> of comp<strong>on</strong>ents<br />
arranged in a dynamic hierarchy <strong>and</strong> two comp<strong>on</strong>ent<br />
subtypes: services that model reentrant c<strong>on</strong>trollers <strong>and</strong> widgets<br />
that model n<strong>on</strong>-reentrant stateful c<strong>on</strong>trollers. In this<br />
secti<strong>on</strong> we examine their interfaces <strong>and</strong> core implementati<strong>on</strong><br />
ideas. We omit some n<strong>on</strong>-essential details for brevity.<br />
3.1 Comp<strong>on</strong>ents<br />
At the core of Aranea lies a noti<strong>on</strong> of comp<strong>on</strong>ents arranged<br />
into a dynamic hierarchy that follows the Composite pattern<br />
extended with certain mechanisms for communicati<strong>on</strong>. This<br />
abstracti<strong>on</strong> is captured by the following interface:<br />
interface Comp<strong>on</strong>ent {<br />
void init(Envir<strong>on</strong>ment env);<br />
void enable();<br />
void disable();<br />
void propagate(Message msg);<br />
void destroy();<br />
}<br />
A comp<strong>on</strong>ent is an entity that<br />
• Has a life-cycle that begins with an init() call <strong>and</strong><br />
ends with a destroy() call.<br />
• Can be signaled to be disabled <strong>and</strong> then enabled again.<br />
• Has an Envir<strong>on</strong>ment that is passed to it by its parent<br />
or creator during initializati<strong>on</strong>.<br />
• Can propagate Messages to its children.<br />
We imply here that a comp<strong>on</strong>ent will have a parent <strong>and</strong> may<br />
have children. Aranea actually implies that the comp<strong>on</strong>ent<br />
would realize a certain flavor of the Composite pattern that<br />
requires each child to have a unique identifier in relati<strong>on</strong> to<br />
its parent. These identifiers can then be combined to create<br />
a full identifier that allows finding the comp<strong>on</strong>ent starting<br />
from the hierarchy root. Note that the hierarchy is not static<br />
<strong>and</strong> can be modified at any time by any parent.<br />
The hierarchy we have arranged from our comp<strong>on</strong>ents so<br />
far is inert. To allow some communicati<strong>on</strong> between different<br />
comp<strong>on</strong>ents we need to examine in detail the noti<strong>on</strong>s of<br />
Envir<strong>on</strong>ment <strong>and</strong> Message.<br />
Envir<strong>on</strong>ment is captured by the following interface:<br />
interface Envir<strong>on</strong>ment {GUI abstracti<strong>on</strong>s<br />
Object getEntry(Object key);<br />
}<br />
Envir<strong>on</strong>ment is a discovery mechanism allowing children to<br />
discover services (named c<strong>on</strong>texts) provided by their parents<br />
without actually knowing, which parent has provided<br />
it. Looking up a c<strong>on</strong>text is d<strong>on</strong>e by calling the envir<strong>on</strong>ment<br />
getEntry() method passing some well-known c<strong>on</strong>text name<br />
as the key. By a c<strong>on</strong>venti<strong>on</strong> this well-known name is the interface<br />
class realized by the c<strong>on</strong>text. The following example<br />
illustrates how envir<strong>on</strong>ment can be used:<br />
L10nC<strong>on</strong>text locCtx = (L10nC<strong>on</strong>text)<br />
getEnvir<strong>on</strong>ment().getEntry(L10nC<strong>on</strong>text.class);<br />
String message = locCtx.localize("message.key");<br />
Envir<strong>on</strong>ment may c<strong>on</strong>tain entries added by any of the current<br />
comp<strong>on</strong>ent ancestors, however the current comp<strong>on</strong>ent<br />
direct parent has complete c<strong>on</strong>trol over the exact entries<br />
that the current comp<strong>on</strong>ent can discover. It can add new<br />
entries, override old <strong>on</strong>es as well as remove (or rather filter<br />
out) entries it does not want the child comp<strong>on</strong>ent to access.<br />
This is d<strong>on</strong>e by wrapping the gr<strong>and</strong>parent Envir<strong>on</strong>ment into<br />
a proxy that will allow <strong>on</strong>ly specific entries to be looked up<br />
from the gr<strong>and</strong>parent.<br />
Message is captured in the following interface:<br />
interface Message {<br />
void send(Object key, Comp<strong>on</strong>ent comp);<br />
}<br />
While the envir<strong>on</strong>ment allows communicating with the comp<strong>on</strong>ent<br />
parents, messages allow communicating with the<br />
comp<strong>on</strong>ent descendants (indirect children). Message is basically<br />
an adaptati<strong>on</strong> of the Visitor pattern to our flavor<br />
of Composite. The idea is that a comp<strong>on</strong>ent propagate(m)<br />
method will just call message m.send(...) method for each<br />
of its children passing the message both their instances <strong>and</strong><br />
identifiers. The message can then propagate itself further or<br />
call any other comp<strong>on</strong>ent methods.<br />
It is easy to see that messages allow c<strong>on</strong>structing both<br />
broadcasting (just sending the message to all of the comp<strong>on</strong>ents<br />
under the current comp<strong>on</strong>ent) <strong>and</strong> routed messages<br />
that receive a relative “path” from the current comp<strong>on</strong>ent<br />
<strong>and</strong> route the message to the intended <strong>on</strong>e. The following<br />
example illustrates a comp<strong>on</strong>ent broadcasting some message<br />
to all its descendants (BroadcastMessage will call execute<br />
for all comp<strong>on</strong>ent under current):<br />
Message myEvent = new BroadcastMessage() {<br />
public void execute(Comp<strong>on</strong>ent comp) {<br />
if (comp instanceof MyDataListener)<br />
((MyDataListener) comp).setMyData(data);<br />
}<br />
}<br />
myEvent.send(null, rootComp<strong>on</strong>ent);<br />
3.2 Services<br />
Although comp<strong>on</strong>ent hierarchy is a very powerful c<strong>on</strong>cept<br />
<strong>and</strong> messaging is enough to do most of the communicati<strong>on</strong>,<br />
it is comfortable to define a specialized comp<strong>on</strong>ent type that<br />
is closer to the C<strong>on</strong>troller pattern. We call this comp<strong>on</strong>ent<br />
Service <strong>and</strong> it is captured by the following interface:<br />
interface Service extends Comp<strong>on</strong>ent {<br />
void acti<strong>on</strong>(<br />
Path path,<br />
InputData input,<br />
OutputData output<br />
);<br />
}<br />
Service is basically an abstracti<strong>on</strong> of a reentrant c<strong>on</strong>troller<br />
in our hierarchy of comp<strong>on</strong>ents. The InputData<br />
<strong>and</strong> OutputData are simple generic abstracti<strong>on</strong>s over, corresp<strong>on</strong>dingly,<br />
a request <strong>and</strong> a resp<strong>on</strong>se, which allow the c<strong>on</strong>troller<br />
to process request data <strong>and</strong> generate the resp<strong>on</strong>se.<br />
The Path is an abstracted representati<strong>on</strong> of the full path to<br />
3<br />
165