Wednesday, May 13, 2009

GMF : Same file for Diagram and Model

I am working on developing a graphical editor using GMF. GMF generated editor creates two files by default, one for diagram and one for model. We had a simple requirement to get a single file for both.
The requirement at first appeared quite straight forward with GMF with the following three steps.

1. The property "Same File for Model and Diagram" should be set to true in .gmfgen.
2. Specify same extension for diagram and model in .gmfgen.
3. Regenerate the diagram code.

Though this looks quite trivial, it will not do the magic in all cases atleast when one's model is not so simple.

XSD Model

In our case, we used an xsd model for generating the ecore which started the trouble. This would need a workaround in the generated code.

In the XXXDiagramEditorUtil class, createDiagram(...) method, the two lines will have to be commented

((XMLResource) diagramResource).getDefaultSaveOptions().put( XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);

((XMLResource) diagramResource).getDefaultLoadOptions().put( XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);

This creates the same file for diagram and model.

Editor dirty issues

There was another problem, editor was not getting dirty with our commands. To debug editor's dirty problems, the class responsible is XXXDocumentProvider#ResourceSetModificationListener. The notifyChanged method in ResourceSetModificationListener gets the call from GMFResource#createModificationTrackingAdapter(). But the GMFResource will fire the notifyChanged only if there is no transient feature in the containment hierarchy of the notifier. This is to filter the unnecessary calls from DiagramImpl .But this check is the culprit in our case.

if (!isModified() && !isTransient(notification.getNotifier(), notification.getFeature())) {
super.notifyChanged(notification);
}

This would skip the call to notifyChanged from the GMFResource all the times because ecore generated from xsd creates a DocumentRoot with references to the elements which are by default transient.

Now the work around for this is we have to create our custom ResourceFactory and custom Resource which should override the createModificationTrackingAdapter() and should handle our notifiers separately.
Ideally, the generated code should handle this :)

Refer to the bug for the status on this issue :https://bugs.eclipse.org/bugs/show_bug.cgi?id=274286.

No comments:

Post a Comment