Login
Pass
Always remember me

Customize your GMF editor by customizing templates

During the development of BOS Studio, which is a technology nominee for Eclipse Community Awards, the BonitaSoft R&D team has customized GMF editors.  I will share what we did and show how to apply it yourself.

One way to customize your GMF editor is to modify the XPand templates. GMF provides a convenient way to do it. This post will explain two ways to take advantage of this method. To illustrate, I will show you how to set a custom SelectionManager in the editor.

Import GMF templates and customize them

  1. First, import the base templates used for GMF generation. You can get them from the templates folder in org.eclipse.gmf.codegen plugin. Open plug-in view, right-click on the plugin and import it as source project: importTemplates
  2. Now you can see the templates in your workspace: baseTemplatesFolder
  3. Create a folder which will contain your customized templates: templateDirectory
  4. Find the file that you want to customize. Be sure to use the same hierarchy for your customized templates folder. For instance, take the Editor.xpt file: and put it in the corresponding folder:
  5. Customize the template by modifying the DEFINE block that you want. For instance, to add your own SelectionManager, modify the configureGraphicalViewer DEFINE block:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    «DEFINE configureGraphicalViewer FOR gmfgen::GenEditorView-»
    «EXPAND xpt::Common::generatedMemberComment»
    protected void configureGraphicalViewer() {
    super.configureGraphicalViewer();
    «EXPAND xpt::editor::DiagramEditorContextMenuProvider::qualifiedClassName FOR editorGen.diagram» provider =
    new «EXPAND xpt::editor::DiagramEditorContextMenuProvider::qualifiedClassName FOR editorGen.diagram»(this, getDiagramGraphicalViewer());
    getDiagramGraphicalViewer().setContextMenu(provider);
    getSite().registerContextMenu(org.eclipse.gmf.runtime.diagram.ui.actions.ActionIds.DIAGRAM_EDITOR_CONTEXT_MENU, provider, getDiagramGraphicalViewer());
    «REM»Disable multiple selection for PREVIEW «ENDREM»
    getDiagramGraphicalViewer().setSelectionManager(new org.bonitasoft.studio.common.diagram.tools.BonitaDiagramSelectionManager());
    }
    «ENDDEFINE»
  6. For the GMF generator to  use your custom templates, there are two attributes to set in the gmfgen file:
    - Set Dynamic Templates value to true
    - Set Template Directory value with the platform path to the folder which contains your customized templates:
  7. gmfgenToUseCustomTemplate

And now for the elegant solution

Ok, now you know how to customize your templates. Let’s go further – learn how to customize them more efficiently. You can use aspects to do this. Aspects allow you to override just a part of the template. This avoids duplicate code, is easier to read, more efficient to maintain and easier to upgrade. Yes I, and the Bonitasoft R&D team, recommend this way ^^

  1. In order to do this, create a folder named “aspects”. Put your customized template into it, again respecting the hierarchy:
  2. aspectsFolder

  3. The customization is not exactly the same. This time, pick up just the DEFINE block that interests you, replace “DEFINE” with “AROUND” and then modify the contents of this block as above. This way, you have only the modified part of the template in the file. This is much clearer :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    «AROUND configureGraphicalViewer FOR gmfgen::GenEditorView-»
    «EXPAND xpt::Common::generatedMemberComment»
    protected void configureGraphicalViewer() {
    super.configureGraphicalViewer();
    «EXPAND xpt::editor::DiagramEditorContextMenuProvider::qualifiedClassName FOR editorGen.diagram» provider =
    new «EXPAND xpt::editor::DiagramEditorContextMenuProvider::qualifiedClassName FOR editorGen.diagram»(this, getDiagramGraphicalViewer());
    getDiagramGraphicalViewer().setContextMenu(provider);
    getSite().registerContextMenu(org.eclipse.gmf.runtime.diagram.ui.actions.ActionIds.DIAGRAM_EDITOR_CONTEXT_MENU, provider, getDiagramGraphicalViewer());
    «REM»Disable multiple selection for PREVIEW «ENDREM»
    getDiagramGraphicalViewer().setSelectionManager(new org.bonitasoft.studio.common.diagram.tools.BonitaDiagramSelectionManager());
    }
    «ENDAROUND»

    If you want more examples, take a look at the templates used for Bonita Open Solution Studio. They are available on the svn.
    And all your comments are welcome :)

4 Responses (and 2 trackbacks)

  1. #1 by Stephan Herrmann on February 19th, 2010

    Quote

    Sounds cool!
    We have a case study where we did s.t. similar not to the templates but at source code level:
    we pulled out all custom code from the class diagram editor of the UML2Tools project.
    I was planing to present this at EclipseCon:
    https://www.eclipsecon.org/submissions/2010/view_talk.php?id=1170
    but I had no luck with the talk selection this year.

    Maybe we should join forces and demonstrate elegant top-to-bottom customization?
    Do you ever customize generated source code?

  2. #2 by Aurelien Pupier on February 19th, 2010

    Quote

    Glad that you like.

    No, we never have to modify the generated source code.

    We really think that modify the templates used for generation is better. Like that we can modify the behavior of the generated code as we want.

    Of what I understood of your case study, you are using aspect-oriented technologies on the generated code in order to modify the behavior of generated code.
    In our case, we customize templates in order to have directly the generated code having the behavior that we want. The aspects are only used on the template in order to have an “elegant way” to modify these templates.

    Regards and thanks for your feedback

  3. #3 by Stephan Herrmann on February 19th, 2010

    Quote

    Lucky you, if you’re able to do everything at the template level :)

    I’m not a GMF expert, but what I understand from others is,
    that a lot of the fine-tuning is extremely difficult to achieve without going to
    the source code level. I mean, the UML2 editor was intended as a show case
    for GMF and they already used custom templates and still they had to do
    lots and lots of customizations in the generated Java sources.

    But sure, if you don’t need that things are a lot easier for you.

    cheers
    Stephan

  4. #4 by Aurelien Pupier on February 19th, 2010

    Quote

    Xpand (and qvto) template is not the only lever that GMF provides. (thinking about gmf providers or using aspects on the generated code ;) )

    And after all, as all the generated code is generated based on these templates, you can modify all this code based on them.
    I’m agree that it can be sometimes really tricky. To modify directly the generated code can be far easier. But I really think that it implies at long term the code to become unmanageable.

    I don’t see cases which requires to modify directly the generated code but perhaps it will come.If you have some samples, I will be curious to see them :)

    Regards,
    Aurelien