EuGENia: Polishing your GMF editor

EuGENia is a front-end for GMF that enables developers to generate a fully functional GMF editor by attaching a few high-level annotations to the Ecore metamodel. The original aim of EuGENia was to lower the entrance barrier for new GMF users and enable people to quickly and easily develop the first version of their editor.

However, after the initial excitement of (at last) being able to get a working GMF editor with minimal effort and no cryptic error messages, all users (including ourselves) used to come to a dead-end. EuGENia could generate an editor that looked 90% similar to what we wanted but when we started polishing the .gmfgraph, .gmftool, .gmfmap and .gmfgen models manually to get to 100%, it meant we couldn’t use EuGENia any more as subsequent invocations of the tool would overwrite our manual changes. Obviously, providing support in EuGENia for all the options that GMF provides wouldn’t be reasonable either as this would progressively make EuGENia as complex as GMF itself.

Our first thought was to try merging (instead of overwriting) the generated with the existing GMF models, but due to the complexity and inter-weaving of these models we’ve found no sensible way of doing this in an automated way. Therefore, we’ve come up with a different solution.

Behind the scenes, EuGENia runs set of model-to-model transformations written in EOL which generate the necessary GMF models from the annotated Ecore metamodel. In order to accommodate the need for persistent customizations, we’re now allowing developers to specify their own little EOL scripts next to the annotated Ecore metamodel, which are responsible for customizing the generated GMF models.

Let’s go straight into a short example. We define this minimal flowchart metamodel using Emfatic.

@namespace(uri="flowchart", prefix="flowchart")
package flowchart;

@gmf.diagram(foo="bar")
class Flowchart {
   val Node[*] nodes;
   val Transition[*] transitions;
}

@gmf.node(label="name", label.icon="false")
abstract class Node {
   attr String name;
   ref Transition[*]#source outgoing;
   ref Transition[*]#target incoming;
}

@gmf.link(label="name", source="source",
   target="target", target.decoration="arrow")
class Transition {
   attr String name;
   ref Node#outgoing source;
   ref Node#incoming target;
}

class Subflow extends Flowchart, Node{

}

@gmf.node(figure=
	"org.eclipse...examples.flowchart.diagram.figures.SquareFigure")
class Action extends Node {

}

@gmf.node(figure=
	"org.eclipse...examples.flowchart.diagram.figures.DiamondFigure")
class Decision extends Node {

}

We then use EuGENia to generate a GMF editor out of it and here is what we get:

image

However, what we’d really like to get is this (spot the differences?)

image

To achieve this we need to tweak a few things in the flowchart.gmfgraph model:

image

We can either do these changes manually after every invocation of EuGENia (boring), or specify the changes in the following ECore2GMF.eol script next to our metamodel.

image

ECore2GMF.eol:

-- Set text of transitionLabel to empty string
var transitionLabel = GmfGraph!Label.
	selectOne(l|l.name='TransitionLabelLabel');
transitionLabel.text = '';

-- Add bold font to actionLabel
var actionLabel = GmfGraph!Label.
	selectOne(l|l.name='ActionLabelFigure');
actionLabel.font = new GmfGraph!BasicFont;
actionLabel.font.style = GmfGraph!FontStyle#BOLD;

-- Add italic font to actionLabel
var decisionLabel = GmfGraph!Label.
	selectOne(l|l.name='DecisionLabelFigure');
decisionLabel.font = new GmfGraph!BasicFont;
decisionLabel.font.style = GmfGraph!FontStyle#ITALIC;

Now, each time we click Eugenia->Generate GMF tool, graph and map models, EuGENia will perform the built-in transformation and then it will also run our custom script on the generated models so that we can get the tailored output we need. Similarly, by specifying a transformation named FixGMFGen.eol we can customize the generated .gmfgen model (in this example we add a dependency to the figures plugin).

Except for enabling developers to now use EuGENia throughout the GMF editor development process, this extension also provides a good evolution mechanism for EuGENia itself. Reoccurring scripts will be good candidates for inclusion in the form of high-level annotations, that will be natively supported by future versions of the tool.

The complete source code of this example is available (projects named org.eclipse.epsilon.eugenia.examples.flowchart.*) in the SVN. You can also find another example, as well as more technical details about this extension here.

This entry was posted in Uncategorized. Bookmark the permalink.

10 Responses to EuGENia: Polishing your GMF editor

  1. Looks pretty much like what we do in the GMFTools project, especially http://code.google.com/p/gmftools/wiki/GenModelTransformation
    We are using Xtend for model transformation and only convert the gmfgen model, as we manually create/edit the rest of the models.

    Note that GMF now comes with a configurable gmfmap->gmfgen transformation written in QVTO (just to add a third M2M trafo language in the game :-))

  2. Indeed. Our main motivation was to be able to customize the .gmfgraph, .gmftool and .gmfmap models which EuGENia generates from the annotated Ecore metamodel. The ability to modify the .gmfgen pretty much came as a free side-effect but it now seems to be equally useful.

  3. Pingback: EuGENia: Kick-start your GMF editor development « Epsilon Weblog

  4. Sakuraba says:

    WOW, just what I needed! Great!

  5. Christoph says:

    I tried this and in my case the line

    actionLabel.font.style = GmfGraph!FontStyle#BOLD.instance;

    did not work. The ‘style’ value would just not be accepted (no error though). After some trying I figured out a version that worked:

    actionLabel.font.style = GmfGraph!FontStyle#BOLD;

    I am using Eclipse Modeling Tools, build 20090920-1017.

  6. Many thanks for pointing this out. This is due to a change in 0.8.8. I’ve updated the scripts.

  7. Luis Molina says:

    hi, can you tell me about a sample on using two models and creating a editor, imagine the next structure: project-> pages -> actionsOnPage, so i can model a project creating pages and then model actionsOnpage on a page?

  8. Luis Molina says:

    ok, i will post my question in forums..

  9. gopal says:

    Thanks for the article. How to run these examples…i tried runas -eclipse
    it opens a new eclipse, what after that.How to test it.
    Please let me know.

Leave a reply to Jan Köhnlein Cancel reply