-----Original Message-----
From: Matthias Bohlen [mailto:[EMAIL PROTECTED] 
Sent: Wednesday, November 19, 2003 8:34 PM
To: 'Doroszlai Attila'
Cc: 'Anthony Mowers'; '[EMAIL PROTECTED]'; 'SainTiss'
Subject: Model refactoring mathematics


Hi Attila,

sorry that it took me sooooo long to respond - it'll happen now. I'm
impressed that so many people think about model-based refactoring, now.
I find this one of the most exciting things in the MDA field.

See my comments below...
Matthias

> -----Original Message-----
> From: Doroszlai Attila [mailto:[EMAIL PROTECTED]
> Sent: Saturday, October 25, 2003 10:05 PM
> To: Matthias Bohlen
> Cc: Anthony Mowers
> Subject: model refactoring
> 
> 
> Matthias, Tony,
> 
> During the last six weeks or so I've been working on the
> model refactoring issue, i.e. enabling AndroMDA to take model 
> changes into account and change the generated code instead of 
> regenerating it.
> 
> I'd like to share with you what I've done so far to let you
> know how I'm progressing, and to ask for your insights.
> 
> As I see it, there are three distinct parts to the task of model
> refactoring:
> 
> 1. Storing previous version(s) of the model.
> 2. During a code-generation run, figuring out what has changed
>    since the previous version of the model.
> 3. Translate the changes of the model elements into changes in the
>    source code.

We could call this the "compare, generate, propagate" (C-G-P) approach.
I thought of an alternative approach: "generate, compare, propagate"
(G-C-P). First, generate code as we do it today, then compare on the
code level and propagate changes into the hand-written code. However, as
one model element maps to several elements in code, this solution will
possibly cause more comparison overhead.

So, let's toss that idea and stick to your C-G-P approach.

> In short, I'm done with the first one, mostly finished with
> the second one and haven't yet touched the third one.

This sounds like you have worked very fast!

> I used the Netbeans XMI writer to do the first task.  The
> model is saved as an XMI file and is loaded during the next 
> generation run. This works even if the original model was not 
> loaded by the MDRepositoryFacade.  The name of the XMI file 
> can be specified for each run of the AndroMDA Ant task by 
> using a nested "history" element.  The whole incremental 
> stuff can also be switched off.

Sounds good. An optimization might be to use a simple <copy> tag in the
ant file to save the old XMI. However, when you run inside a CASE tool
like Poseidon and operate on an in-memory model, the XMI writer approach
is better.

> I'd say I've made good progress on the second part.  I used
> the JMI reflective package to compare the two models and find 
> the differences at a low level in a metamodel-independent 
> manner (let's call this process exploration).  By low level 
> differences I mean that I identify only three kinds of 
> changes: new elements, differring values and removed 
> elements.  I have only tried it yet with a static model, but 
> it correctly identified changes between two versions of the 
> model.  The changes are passed as objects from the comparator 
> to the AndroMDA core, which then passes them on to the cartridges.

OK, so you have solved the "C" phase in C-G-P. I think, the way you did
it is good because it is generic: a comparator that does not know
anything and simply computes the set of all changed model elements. Each
cartridge should know how to deal with the results of the "C" phase.

Let's name the set of changed model elements - call it "SoCM", for
example. I'll use that name below.

So, till here, we have "C" done by you, "G" done by AndroMDA, so all
that is left is "P". As far as I have understood Pieter and Hans at
Antwerp University, they have started to solve "P", right? If Pieter can
really describe what "P" means in 20 lines of email text, maybe we can
skip this problem and use the Antwerp solution. But, let's pretend for a
moment that we don't have that solution.

> AndroMDA processes one model element at a time, so it would
> be logical to try to restrict the exploration of the 
> differences to the model element's context.  But how can I 
> possibly tell which parts of the model belong to the element 
> in question and which don't?  Frankly, I think this can only 
> be answered by the cartridges.  What's more, this is surely 
> metamodel-dependent.

Yes, sure.

> So now the exploration part goes over the whole model, or at
> least what it can reach via associations starting from the 
> model element AndroMDA is processing.  This places the burden 
> on the cartridges to decide which changes to take into 
> account when processing the model element.  

It seems like a cartridge is required to compute a kind of (possibly
transitive) closure TC(m) of a model element m - this is the set of
input model elements that will be read by the cartridge when it
generates code for m. Example: if m is an <<Entity>> class, TC(m)
contains at least:
* all the attributes and methods in m
* all association links connected to m
* all association links on "the opposite end" of each association
* all classes that can be reached via associations
* all other classes that can be reached via an <<EntityRef>> or
<<ServiceRef>> dependency
* an exception class that can be reached via an <<Exception>> dependency
* the superclass of m
* etc. etc.

Each cartridge should be able to formally describe how TC(m) is
computed. Phew - quite a complex task in itself! Well, let's assume that
can be done somehow and proceed.

Once the cartridge has got TC(m), the cartridge can intersect TC(m) with
SoCM (see above). For each model element mc ("c" for "changed") that is
a member of SoCM and TC(m), the cartridge has to compute a set of
"propagate commands" PC(mc) that tell the Java refactoring engine how to
do a change at the code level.

Example:
* Take two entity classes: a class Person and a class Address.
* Person has an association to Address with the role name "homeLocation"
at the association end near Address.
* The user changes this role name to "homeAddress".

What should happen?

* SoCM contains one element (mc) of type AssociationEnd with the new
name "homeAddress".
* TC(Entity) also contains mc so that mc is a member of the intersection
of both sets.
* The cartridge knows that association end names generate getter/setter
names.
* So, the cartridge calculates PC(mc) and decides to produce a propagate
command "change getter/setter name to getHomeAddress and setHomeAddress"
and sends it to the Java refactoring engine.
* The Java refactoring engine (Eclipse in that case) changes the name
"getHomeLocation" to "getHomeAddress" wherever it finds it (same for the
setter).

> I haven't yet
> given much thought to it, but I think we need some kind of 
> metamodel-dependent descriptor that defines which elements 
> and associations the cartridge should take into account (and 
> how, which leads us to the topic of transformation 
> definitions, but I won't go into this now).

Hmmmm ... specifying how a cartridge should compute TC(m) is
non-trivial. Maybe, the guys around Pieter have an idea.

> As for the third step, I've started to define an interface
> for cartridges that support the incremental change of 
> generated code. I've also written a dummy cartridge which 
> prints every change it's notified of (and does so several 
> times, since AndroMDA hands over the changes of the whole 
> model for every model element with the appropriate stereotypes).

Maybe, the core should keep a reference to SoCM so that each cartridge
can reference it on demand. SoCM should not be passed to the cartridge
each time a model element is processed.

> I don't know Eclipse JDT yet, but I know of another
> possibility available even when not running AndroMDA as an 
> Eclipse plug-in: InjectJ (http://injectj.sf.net), which is a 
> static source code transformation engine.  It may be worth a 
> look or two.  Anyway, I guess both of these are only 
> applicable to Java, but I'd definitely like to see this work 
> on SQL, too.

InjectJ looks good. It looks much more generic than Eclipse JDT. We'll
have to look at all the propagate commands that the cartridges will
spill out, then we can decide which refactoring engine would work best.

> I have to test it more thoroughly, maybe cover some cases I
> have forgotten so far, and clean up the code, then I'll be 
> able to send you the source for all this.  Until then, please 
> share your thoughts on what I described.

OK. Thanks. So much for my thoughts. Now, Pieter, Hans and the others
should add their comments and ideas.

> Attila

Cheers...
Matthias

P.S.: Oh boy, this was far more than 20 lines! Sorry! :-)

---

Matthias Bohlen
"Consulting that helps project teams to succeed..."
http://www.mbohlen.de/




-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
Does SourceForge.net help you be more productive?  Does it
help you create better code?  SHARE THE LOVE, and help us help
YOU!  Click Here: http://sourceforge.net/donate/
_______________________________________________
Andromda-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/andromda-devel

Reply via email to