The basic concept for such an editor can be summed up by the following bullet points:
- The editor should display the domain model, the GraphModel, the ToolModel and the MapModel together in a 3D view.
- The models should be visualized graphically, thus a graphical notation must be developed for each of them.
- References from the MapModel to the other models should be visualized using 3D connections.
- It should be possible to edit the MapModel entirely by dragging elements from the other models (or rather, their diagrams) to the MapModel. The user should not need to use any other methods to edit the MapModel.
- The editor should create as many elements of the MapModel automatically to assist the user.
Thus, the first step was to develop graphical notations for the domain model, the GraphModel and the MapModel. The ToolModel was excluded to limit the amount of work, and it can be added at a later stage. I began by creating 2D GEF editors that simply display the aforementioned models. Obviously, with the Ecore Tools there already is a graphical notation and a very capable editor for EMF based domain models, so no work had to be done there.
|Ecore Tools Editor|
The main focus in creating a graphical notation for the GraphModel was to render the figures in the figure gallery just like they would look like in the generated editor. The diagram elements defined in the model should be grouped by their type (node, connection, diagram label and compartment) and the layout should be automatic, without the need for user interaction. The following screenshot demonstrates this.
|Graphical Notation for the GraphModel|
Developing a graphical notation for the MapModel was a little more complex because it needs to convey more information than the notation for the GraphModel does:
- The MapModel mirrors the containment relationships of the domain model (using NodeReferences, NodeMappings and Compartments) which results in a hierarchical structure. This structure should be represented visually by nesting the figures which represent the model elements.
- The MapModel needs to display additional information like which domain element is mapped etc.
- The mappings should be represented by the figures which they map to in the GraphModel. That is, if a NodeMappping maps to a blue rectangle figure (in the GraphModel), then that NodeMapping should render itself as a blue rectangle also.
|Graphical Notation for the MapModel|
As you can see in the above screenshot, every model element is represented using a figure that has a gray border and title bar. These figures are nested, and those figures that represent a mapping (like NodeMapping) display the referenced figure as their child. Additional information is displayed at the bottom of some of the figures in the form of a list of named properties. CompartmentMappings are nested into the figures to which they belong and contain the child references that link to the contained domain model elements.
With all the graphical notations in place, the next step was to combine those into a 3D multi editor. In order to do that, the 2D GEF editors had to be 3D-fied first. A 3D version of the Ecore Tools already exists as a GEF3D example, so that was just reused here. The other editors could be easily 3D-fied by adapting four classes each.
Combining the three viewers into a multi editor also is a pretty easy task with the tools that GEF3D already contains. There is an abstract base class (AbstractMultiEditor3D) for multi editors that allow any editor implementing the interface INestableEditor to be embedded. There are only very few things that need to be taken care of manually here, like for example making sure that all embedded editors use the same EMF ResourceSet to load their models. Once everything is in place, a multi editor is used by opening one of the models using the newly created editor and dragging the other models onto the editor window - easy! The result of this step is displayed in the following screenshot.
|Multi Editor for the Mapping Model|
As you can see, this version of the editor already displays references from the MapModel to the other models using 3D connections. This has been implemented by using the UnidirectEditPart3D base class that comes with GEF3D. This class allows creating connections that are created by either the source or target edit part, which is exactly what was needed in this situation, since neither the domain model nor the GraphModel are aware of any references that a MapModel might have to their elements.
At this point, all that is missing from the editor is the actual editing functionality. It was decided to use a model transformation language to implement the editing functions (which always modify the MapModel in some way). This transformation language is called Mitra was created by Jens von Pilgrim for his Ph.D. thesis. Mitra is an acronym that stands for "Micro Transformations". The language is optimized for fine-grained, semi-automatic model transformations, as the name indicates. Since the Mitra rules that implement the editing functionality are triggered by drag and drop operations, a GEF tool is needed that can do this. Generally speaking, a drag and drop operation can also be interpreted as selecting a number of parameters for a rule. The model elements that are dragged are called source parameters while the model element which the elements are dropped on is a target parameter.
Consider the following example: Say you want to create a LinkMapping. For this you need a connection from the GraphModel and a domain element that represents the association in the domain model (this could be either an association class or a simple reference). For the sake of simplicity, let the association be modeled by a reference in the domain model. Now to create a LinkMapping, you can drag the connection from the GraphModel and drop it on the MapModel. This creates a new LinkMapping. To set the link feature, you would now drag the association from the domain model and drop it on the LinkMapping, etc.
There is one remaining problem however: How are the transformation rules selected? Currently, whenever an element is dropped, a popup menu is displayed that contains all rules defined for the editor. This is demonstrated in the following screenshot.
|Rule Selection Menu|
Obviously, this is not optimal, and there are plans to implement automatic rule selection by matching the parameter types against the rule signatures, but this is still on the todo list. But even if this is implemented, there will be cases in which there are multiple rules that match the parameter types, and in those cases, the rule name should be replaced by some more meaningful names in the menu.
This first video shows how a TopNodeReference (including a NodeMapping, LabelMappings and CompartmentMappings) is created simply by dragging a Node from the GraphModel onto the MapModel.
Note that no references to the domain model are set - to see how this is done you can watch the next video:
Finally, the last video demonstrates how to create a ChildNodeReference inside an existing CompartmentMapping and a LinkMapping: