Transcript Slide 1
University of Alabama
at Birmingham
Vanderbilt
University
An Approach for Supporting
Aspect-Oriented Domain Modeling
GPCE 2003 – Erfurt, Germany
September 24, 2003
Jeff Gray, Ted Bapty, Sandeep Neema,
Doug Schmidt, Andy Gokhale and Bala Natarajan
gray (at) cis.uab.edu
http://www.gray-area.org
This research is funded by DARPA/IXO, under the PCES program.
Motivating Problem –
Crossccuting Constraints in Real-Time/Embedded Models
Changeability???
Base models become
constrained to capture a
particular design
Multiple
Levels
of Hierarchy
c
A
B
d
Replicated
Structures
F
e
B
Constraints that are
related to some global
property are dispersed
across the model
c
d
B
e
Context
Sensitive
Crosscutting Constraints
c
d
e
Importance of Changeability in Modeling
Modeling’s key advantage:
Ability to rapidly explore “what-if” design alternatives
Changeability a metric for modularity:
“The way to evaluate a modular decomposition…is to ask
what changes it accommodates.”
David Weiss, chapter preface in Software Fundamentals
Ensure benefit of model-driven approach:
“Small changes in requirements entail large changes in
the structure and configuration”
Gerald Jay Sussman, “Robust Design through Diversity,”
DARPA Amorphous Computing Workshop, 1999.
Motivation Summary
Key Problems:
Difficult to specify and manage cross-cutting
concerns (e.g., constraints) in model-based
systems
Lack of tool support for automatically
weaving concerns into models
Our Solution:
A meta framework that assists in the
construction of model weavers, capable of
rapidly dispersing global concerns across a
design space; not just notational
Constraint-Specification Aspect Weaver
http://www.gray-area.org/Research/C-SAW
Modeling Context: MIC/GME
Meta-Model of Stateflow using
UML/OCL as meta-modeling language.
META-MODEL
Model interpreter 1
Model interpreter 2 Matlab
Key focus of this paper:
DOMAIN-MODEL
C++
Weaving of high-level
concerns
into domain model
Framework for creating new
weavers for each meta-model
Model interpreter 3
FPGA
Model instance of Stateflow
Process of Using a Model Weaver
GME
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE project SYSTEM "mga.dtd">
<project guid="{00000000-0000-0000-0000-00 000000 0000}" cdate="Thu Nov 30 14:15:40 2000" mdate="Thu Nov 30 14:15:40 2000" metaguid="{00000000-0000-0000-0000-00 000000 0000}" metaname="PCES">
<name>bit1</name>
<comment></comment>
<author></author>
<folder id="id-006a-00000001" kind="RootFolder">
<name>bit1</name>
<folder id="id-006a-00000002" kind="Structural">
<name>Structural</name>
<model id="id-0065-00000001" kind="ProcessingCompound">
<name>ProcessingCompound</name>
<attribute kind="Description" status="meta">
<value></value>
</attribute>
<atom id="id-0066-00000007" kind="Attribute" role="Attrib">
<name>GatesPerBit</name>
<regnode name="PartRegs">
<value></value>
<regnode name="StructuralAspect">
<value></value>
<regnode name="Position" isopaque="y es">
<value>37,153</value>
</regnode>
</regnode>
</regnode>
<attribute kind="Value" status="meta">
<value></value>
</attribute>
</atom>
<atom id="id-0066-00000006" kind="Attribute" role="Attrib">
<name>NomBits</name>
<regnode name="PartRegs">
<value></value>
<regnode name="StructuralAspect">
<value></value>
<regnode name="Position" isopaque="y es">
<value>205,76</value>
</regnode>
</regnode>
</regnode>
<attribute kind="Value" status="meta">
<value></value>
</attribute>
</atom>
<atom id="id-0066-00000005" kind="Attribute" role="Attrib">
<name>MaxBits</name>
<regnode name="PartRegs">
<value></value>
<regnode name="StructuralAspect">
<value></value>
<regnode name="Position" isopaque="y es">
<value>128,76</value>
</regnode>
</regnode>
</regnode>
Enhanced
FOO.XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE project SYSTEM "mga.dtd">
FOO.XML
<project guid="{00000000-0000-0000-0000-00 000000 0000}" cdate="Thu Nov 30 14:15:40 2000" mdate="Thu Nov 30 14:15:40 2000" metaguid="{00000000-0000-0000-0000-00 000000 0000}" metaname="PCES">
<name>bit1</name>
<comment></comment>
<author></author>
<folder id="id-006a-00000001" kind="RootFolder">
<name>bit1</name>
<folder id="id-006a-00000002" kind="Structural">
<name>Structural</name>
<model id="id-0065-00000001" kind="ProcessingCompound">
<name>ProcessingCompound</name>
<attribute kind="Description" status="meta">
<value></value>
</attribute>
<atom id="id-0066-00000007" kind="Attribute" role="Attrib">
<name>GatesPerBit</name>
<regnode name="PartRegs">
<value></value>
<regnode name="StructuralAspect">
<value></value>
<regnode name="Position" isopaque="y es">
<value>37,153</value>
</regnode>
</regnode>
</regnode>
<attribute kind="Value" status="meta">
<value></value>
</attribute>
</atom>
<atom id="id-0066-00000006" kind="Attribute" role="Attrib">
<name>NomBits</name>
<regnode name="PartRegs">
<value></value>
<regnode name="StructuralAspect">
<value></value>
<regnode name="Position" isopaque="y es">
<value>205,76</value>
</regnode>
</regnode>
</regnode>
<attribute kind="Value" status="meta">
<value></value>
</attribute>
</atom>
<atom id="id-0066-00000005" kind="Attribute" role="Attrib">
<name>MaxBits</name>
<regnode name="PartRegs">
<value></value>
<regnode name="StructuralAspect">
<value></value>
<regnode name="Position" isopaque="y es">
<value>128,76</value>
</regnode>
</regnode>
</regnode>
Domain-Specific
Weaver
Modeling
constraint FOOB2
{
// apply a specific constraint to “B2” only
in Structural models("ProcessingCompound")->
select(p | p.name() == "B2")->PowerStrategy (1, 100);
}
constraint FOOBStar
{
// apply a specific constraint to all nodes beginning with “B” - use
wildcard
in Structural models("ProcessingCompound")->
select(p | p.name() == "B*")->PowerStrategy (1, 100);
}
Pointcuts
Quantification Over Base Code
An AspectJ example
Advice
Comp1
package org. apac he.to mcat. sessi on;
void va lidat e() {
// i f we have an i nacti ve in terv al, c heck to se e if
// w e've exce eded it
import org.a pach e.tom cat.c ore.* ;
import org.a pach e.tom cat.u til.S tring Mana ger;
import java. io.* ;
import java. net. *;
import java. util .*;
import javax .ser vlet. *;
import javax .ser vlet. http. *;
if ( inac tiveI nterv al != -1) {
int thisI nterv al =
(int) (Syst em.cu rrent Time Milli s() - last Acces sed) / 10 00;
if ( thisI nterv al > inact iveI nterv al) {
inval idate ();
/**
* Core impl emen tatio n of a ser ver s essi on
*
* @aut hor J ames Dunc an Da vidso n [du ncan @eng. sun.c om]
* @aut hor J ames Todd [gon zo@en g.sun .com ]
*/
Serve rSess ionMa nager ssm =
S erver Sessi onMan ager .getM anage r();
ssm.r emove Sessi on(th is);
}
}
public class Ser verSe ssion {
}
pri vate Stri ngMan ager sm =
Stri ngMa nager .getM anage r("or g.ap ache. tomca t.ses sion" );
pri vate Hash table valu es = new H asht able( );
pri vate Hash table appS essio ns = new Hasht able( );
pri vate Stri ng id ;
pri vate long crea tionT ime = Syst em.c urren tTime Milli s();;
pri vate long this Acces sTime = cr eati onTim e;
pri vate long last Acces sed = crea tion Time;
pri vate int inact iveIn terva l = - 1;
syn chron ized void inva lidat e() {
Enum erat ion e num = appS essio ns.k eys() ;
Ser verSe ssio n(Str ing i d) {
this .id = id;
}
}
pub lic v oid putVa lue(S tring name , Ob ject value ) {
if ( name == n ull) {
Stri ng ms g = s m.get Strin g("s erver Sessi on.va lue.i ae") ;
whil e (e num.h asMor eElem ents( )) {
Obje ct ke y = e num.n extEl emen t();
Appl icati onSes sion appSe ssio n =
(Appl icati onSes sion) appS essio ns.ge t(key );
appS essio n.inv alida te();
}
pub lic S trin g get Id() {
retu rn i d;
}
thro w new Ille galAr gumen tExc eptio n(msg );
}
pub lic l ong getCr eatio nTime () {
retu rn c reati onTim e;
}
remo veVa lue(n ame); // remov e an y exi sting bind ing
valu es.p ut(na me, v alue) ;
}
pub lic l ong getLa stAcc essed Time( ) {
retu rn l astAc cesse d;
}
pub lic O bjec t get Value (Stri ng na me) {
if ( name == n ull) {
Stri ng ms g = s m.get Strin g("s erver Sessi on.va lue.i ae") ;
pub lic A ppli catio nSess ion g etApp lica tionS essio n(Con text cont ext,
bool ean creat e) {
Appl icat ionSe ssion appS essio n =
(App licat ionSe ssion )appS essi ons.g et(co ntext );
thro w new Ille galAr gumen tExc eptio n(msg );
}
retu rn v alues .get( name) ;
if ( appS essio n == null && cr eate ) {
}
// X XX
// s ync t o ens ure v alid?
pub lic E nume ratio n get Value Names () {
retu rn v alues .keys ();
}
appS essio n = n ew Ap plica tion Sessi on(id , thi s, co ntex t);
appS essio ns.pu t(con text, app Sessi on);
pub lic v oid remov eValu e(Str ing n ame) {
valu es.r emove (name );
}
}
// X XX
// m ake sure that we ha ven't gon e ove r the end of ou r
// i nact ive i nterv al -- if s o, i nvali date and c reate
// a new appS essio n
pub lic v oid setMa xInac tiveI nterv al(i nt in terva l) {
inac tive Inter val = inte rval;
}
retu rn a ppSes sion;
pub lic i nt g etMax Inact iveIn terva l() {
retu rn i nacti veInt erval ;
}
}
voi d rem oveA pplic ation Sessi on(Co ntex t con text) {
appS essi ons.r emove (cont ext);
}
// XXX
// sync' d fo r saf ty -- no o ther thre ad sh ould be ge tting som ethin g
// from this whil e we are r eapin g. T his i sn't the m ost o ptim al
// solut ion for t his, but w e'll dete rmine some thing else lat er.
/**
* Calle d by cont ext w hen r eques t co mes i n so that acces ses and
* inact ivit ies c an be deal t wit h ac cordi ngly.
*/
after(Object o) throwing (Error e): pubIntf(o) {
log.write(o, e);
…
}
syn chron ized void reap () {
Enum erat ion e num = appS essio ns.k eys() ;
voi d acc esse d() {
// s et l ast a ccess ed to this Acce ssTim e as it wi ll be lef t ove r
// f rom the p revio us ac cess
whil e (e num.h asMor eElem ents( )) {
Obje ct ke y = e num.n extEl emen t();
Appl icati onSes sion appSe ssio n =
(Appl icati onSes sion) appS essio ns.ge t(key );
last Acce ssed = thi sAcce ssTim e;
this Acce ssTim e = S ystem .curr entT imeMi llis( );
appS essio n.val idate ();
}
}
}
}
voi d val idat e()
Comp2
package org. apac he.to mcat. sessi on;
import org.a pach e.tom cat.u til.* ;
import org.a pach e.tom cat.c ore.* ;
import java. io.* ;
import java. net. *;
import java. util .*;
import javax .ser vlet. http. *;
// XXX
// sync' d fo r saf ty -- no o ther thre ad sh ould be ge tting som ethin g
// from this whil e we are r eapin g. T his i sn't the m ost o ptim al
// solut ion for t his, but w e'll dete rmine some thing else lat er.
syn chron ized void reap () {
Enum erat ion e num = sess ions. keys ();
whil e (e num.h asMor eElem ents( )) {
Obje ct ke y = e num.n extEl emen t();
Serv erSes sion sessi on = (Ser verSe ssion )sess ions. get( key);
/**
*
* @aut hor J ames Dunc an Da vidso n [du ncan @eng. sun.c om]
* @aut hor J ason Hunt er [j ch@en g.sun .com ]
* @aut hor J ames Todd [gon zo@en g.sun .com ]
*/
sess ion.r eap() ;
sess ion.v alida te();
}
}
public class Ser verSe ssion Manag er im plem ents Sessi onMan ager {
syn chron ized void remo veSes sion( Serv erSes sion sessi on) {
Stri ng i d = s essio n.get Id();
pri vate Stri ngMan ager sm =
Stri ngMa nager .getM anage r("or g.ap ache. tomca t.ses sion" );
pri vate stat ic Se rverS essio nMana ger manag er; / / = n ew Se rver Sessi onMan ager( );
sess ion. inval idate ();
sess ions .remo ve(id );
}
pro tecte d in t ina ctive Inter val = -1;
pub lic v oid remov eSess ions( Conte xt c ontex t) {
Enum erat ion e num = sess ions. keys ();
sta tic {
mana ger = new Serv erSes sionM anag er();
}
whil e (e num.h asMor eElem ents( )) {
Obje ct ke y = e num.n extEl emen t();
Serv erSes sion sessi on = (Ser verSe ssion )sess ions. get( key);
Appl icati onSes sion appSe ssio n =
sessi on.ge tAppl icati onSe ssion (cont ext, false );
pub lic s tati c Ser verSe ssion Manag er g etMan ager( ) {
retu rn m anage r;
}
pri vate Hash table sess ions = new Has htabl e();
pri vate Reap er re aper;
if ( appSe ssion != n ull) {
appSe ssion .inva lidat e();
}
pri vate Serv erSes sionM anage r() {
reap er = Reap er.ge tReap er();
reap er.s etSer verSe ssion Manag er(t his);
reap er.s tart( );
}
}
}
/**
* Used by c ontex t to confi gure the sessi on ma nager 's in acti vity timeo ut.
*
* The S essi onMan ager may h ave s ome defau lt se ssion time out , the
* Conte xt o n the othe r han d has it' s tim eout set b y the dep loyme nt
* descr ipto r (we b.xml ). Th is me thod lets the Conte xt co nfor gure the
* sessi on m anage r acc ordin g to this valu e.
*
* @para m mi nutes The sessi on in acti vity timeo ut in minu tes.
*/
pub lic v oid setSe ssion TimeO ut(in t mi nutes ) {
if(- 1 != minu tes) {
// T he ma nager work s wit h se conds ...
inac tiveI nterv al = (minu tes * 60) ;
}
}
pub lic v oid acces sed( Conte xt ct x, R eques t req , Str ing i d ) {
Appl icat ionSe ssion apS= (Appl icat ionSe ssion )find Sessi on( ctx, id);
if( apS= =null ) ret urn;
Serv erSe ssion serv S=apS .getS erve rSess ion() ;
serv S.ac cesse d();
apS. acce ssed( );
// c ache it - no n eed t o com pute it a gain
req. setS essio n( ap S );
}
pub lic H ttpS essio n cre ateSe ssion (Con text ctx) {
Stri ng s essio nId = Sess ionId Gene rator .gene rateI d();
Serv erSe ssion sess ion = new Serv erSes sion( sessi onId) ;
sess ions .put( sessi onId, sess ion) ;
pointcut pubIntf(Object o):
call(public * com.borland.*.*(..)) &&
target(o);
}
if(- 1 != inac tiveI nterv al) {
sess ion. setMa xInac tiveI nterv al(i nacti veInt erval );
}
retu rn s essio n.get Appli catio nSes sion( ctx, true );
}
pub lic H ttpS essio n fin dSess ion(C onte xt ct x, St ring id) {
Serv erSe ssion sSes sion= (Serv erSe ssion )sess ions. get(i d);
if(s Sess ion== null) retu rn nu ll;
retu rn s Sessi on.ge tAppl icati onSe ssion (ctx, fals e);
}
Pointcut
Quantification Over a Domain Model
Apply AO Weaving concepts to Model-based systems
Weavers ‘Decorate’ Models with attributes & constraints
Weavers compose new model constructs
Model
Domain-specific
Strategies
Strategy1
Strategy2
Strategy3
StrategyN
…
select(p | p.name() == “Model*” &&
p.kind() == “StateFlow”)->Strategy3();
…
Modeling Pointcut
Constructing Model Weavers
Domain-Specific Weavers
General Motors
Factory
+
GM specific weaver
DuPont Chemical
Factory
+
DuPont specific weaver
Boeing Bold Stroke
+
Bold Stroke specific weaver
Example: Evidence of “meta” in the corresponding XML of each of the above models
The Metaweaver Framework
XML
Modeling
Strategies (C++)
Pointcuts
(Model Hierarchy)
Strategies
strategy ApplyConstraint(constraintName : string, expression : string)
{
addAtom("OCLConstraint", "Constraint", constraintName).addAttribute("Expression", expression);
}
Strategy
Code
Generator
strategy RemoveConstraint(constraintName : string)
{
findAtom(constraintName).removeChild();
}
strategy ReplaceConstraint(constraintName : string, expression : string)
{
RemoveConstraint(constraintName);
ApplyConstraint(constraintName, expression);
}
Embedded Constraint Language
Included OCL Operators
Arithmetic Operators
Logical Operators
Collection Operator
Property Operator
Standard OCL
Collection Operators
+, -, *, /, =, <, >, <=, >=, <>
and, or, xor, not, implies, if/then/else
->
.
collection->size() : integer
collection->forAll( x | f(x) ) : Boolean
collection->select( x | f(x) ) : collection
collection->exists( x | f(x) ) : Boolean
Embedded Constraint Language
Traditional OCL has been strictly a declarative query
language
New uses require an imperative procedural style
Addition of side effects into model
Examples:
addAtom(…), findAtom(…)
addAttribute(…), findAttribute(…)
removeNode(…)
Support for recursion
Chaining of strategies (procedure calls)
Inlined C++ code
List of ECL Operators
Aggregates
Connections
Transformation
folders, models, atoms,
attributes, connections
connpoint, target, refs,
resolveRefeeredID,
resolveIDReferred
addAttribute, addAtom, addModel,
addConnection, removeNode
Selection
findFolder, findModel, findAtom,
findAttributeNode
General
id, parent, getID, getInt, getStr
Example: Processor Assignment
Weapons deployment
Sensor
WCET=1ms
WCET=4ms
100 Hz
Latency < 2ms
Latency < 10ms
Update
Σ
(x,y,z)
(x,y,z)
Map
MapDB
Weapon Release
WCET=2ms
Latency < 5ms
WCET=150ms
WCET=1ms
Latency < 20ms
(x,y,z)
Display
Processor Assignment:
Component Interaction Model
Processor Assignment:
Component Internals
Processor Assignment:
Modeling Pointcut
aspect ProcessorAssignment
{
models("")->select(m | m.kind() == “Comp*")->Assign(10);
}
Processor Assignment: Strategy
strategy Assign(limit : integer){
declare static accumulateWCET, processNum : integer;
declare currentWCET : integer;
self.compute.WCET.getInt(currentWCET);
accumulateWCET := accumulateWCET + currentWCET;
if (limit < accumulateWCET) then
accumulateWCET := currentWCET;
processNum := processNum + 1;
endif;
<<CComBSTR aConstraint = "self.assignTo()=processor" +
XMLParser::itos(processNum); >>
AddConstraint("ProcessConstraint", aConstraint);
}
Processor Assignment:
Weaved Constraint
self.assignTo() = processor0
strategy Assign(limit : integer){
declare static accumulateWCET, processNum : integer;
declare currentWCET : integer;
self.compute.WCET.getInt(currentWCET);
accumulateWCET := accumulateWCET + currentWCET;
if (limit < accumulateWCET) then
accumulateWCET := currentWCET;
processNum := processNum + 1;
endif;
<<CComBSTR aConstraint = "self.assignTo()=processor" +
XMLParser::itos(processNum); >>
AddConstraint("ProcessConstraint", aConstraint);
}
Code Generation Example
Consider the following, which appears in an
EagerLazy strategy:
…
components.models()->select(c |
c.id() == refID)->eagerLazy(…);
…
Code Generation Example
CComPtr<IXMLDOMNodeList> models0 = XMLParser::models(components, "");
nodeTypeVector selectVec1 = XMLParser::ConvertDomList(models0);
nodeTypeVector selectVecTrue1 = new std::vector<nodeType>;
vector<nodeType>::iterator itrSelect1;
for(itrSelect1 = selectVec1->begin(); itrSelect1 != selectVec1->end();
itrSelect1++) {
nodeType selectNode1 = (*itrSelect1);
nodeType c;
c = selectNode1;
CComBSTR id0 = XMLParser::id(c);
ClData varforward1(id0);
ClData varforward2(referredID);
bool varforward3 = varforward1 == varforward2;
if(varforward3)
selectVecTrue1->push_back(*itrSelect1);
}
vector<nodeType>::iterator itrCollCall1;
for(itrCollCall1 = selectVecTrue1->begin();
itrCollCall1 != selectVecTrue1->end(); itrCollCall1++)
eagerLazy::apply(…);
Sample XMLParser Methods
nodeType XMLParser::addAtom(nodeType self, CComBSTR kind, CComBSTR role, CComBSTR name)
{
return addNode(self, "atom", kind, role, name);
}
nodeType XMLParser::findModel(nodeType aNode, CComBSTR name)
{
CComBSTR bstrFind(L"./model[name=\""); bstrFind.Append(name); bstrFind.Append("\"]");
return submitXPath(aNode, bstrFind);
}
CComBSTR XMLParser::id(nodeType aNode)
{
CComBSTR res;
CComPtr<IXMLDOMNode> attr = XMLParser::findAttribute (aNode, "id");
XMLParser::getStr(attr, res);
return res;
}
Summary
Domain-Specific
Strategies
strategy ApplyConstraint(constraintName : string, expression : string)
{
addAtom("OCLConstraint", "Constraint",
constraintName).addAttribute("Expression", expression);
}
strategy RemoveConstraint(constraintName : string)
ApplyConstraint(constraintName, expression);
Domain-specific strategies
(encoded in a DSL) are
used to instantiate a new
model weaver
Specification aspects and
base model are sent
through the weaver
}
Meta-weaver
Framework
Strategies
(C++)
Domain-specific
Models
Modeling
Pointcuts
B
constraint FOOB2
{
// apply a specific constraint to “B2” only
in Structural models("ProcessingCompound")->
// apply a specific constraint to all nodes beginning with “B” - use wildcard
in Structural models("ProcessingCompound")->
select(p | p.name() == "B*")->PowerStrategy (1, 100);
}
c
d
e
3
B
1
The weaver distributes
constraints across the
base model
Constrained
Models
2
c
d
e
New
Two-level aspect weaving
(see upcoming AOSD book)
Summary Benefits of this Approach
The modeler can now perform various “what-if”
scenarios using modeling constraints
Impossible in previous approach
Constraints can be plugged/unplugged in model
Because much of the redundancy of constraint
application is removed, the effect of each constraint
on the global system can be better understood. This
localization of constraints improves modular
reasoning.
Allows for the rapid construction of new domainspecific weavers
Strategies are specified using a DSL
Generated code is at a much lower level
For more information
Please give us another week to upgrade site:
gray (at) cis.uab.edu
http://www.gray-area.org/Research/C-SAW
GME (freely available):
http://www.isis.vanderbilt.edu/Projects/gme/
OMG MIC PSIG:
http://mic.omg.org
A Concluding Quote
“Even for this let us divided live…That by this
separation I may give that due to thee which
thou deservest alone.”
William Shakespeare, Sonnet XXXIX
Extra slides
Tool Independence
Requires an exposed
API for accessing
internal model data
structures
Tool-specific adapters
written for each new
supported tool
Rose
Cadena
GME
MetaEdit
Adaptive Core Weaving Engine
Not unlike AspectJ AJDT
Eclipse
AJDT
JBuilder
emacs
Netbeans/FORTE