https://wiki.eclipse.org/api.php?action=feedcontributions&user=Rgronback&feedformat=atomEclipsepedia - User contributions [en]2024-03-28T07:58:14ZUser contributionsMediaWiki 1.26.4https://wiki.eclipse.org/index.php?title=File:Inserted_subtopic.png&diff=4449File:Inserted subtopic.png2006-05-02T19:33:10Z<p>Rgronback: </p>
<hr />
<div></div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_3&diff=4448Graphical Modeling Framework/Tutorial/Part 32006-05-02T19:32:46Z<p>Rgronback: /* Custom Actions */</p>
<hr />
<div>'''Note:''' This is still very much a work in progress...<br />
<br />
In this third part of the GMF Tutorial, we will explore some more advanced capabilities related to the tooling components, while also extending what's generated with customizations to the runtime. Specifically we will add a composite figure using the graphical definition, show how to leverage external figures, and how to use an extension plug-in to add a custom action to our diagram. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_3.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
== New Icons ==<br />
A quick way to get a new polished look for our mindmap diagram is by replacing the generated EMF icons we've seen so far with some that are more, well... distinctive ;) The easiest way to do this is to replace the GIF images found in our org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/ folder. <br />
<br />
In case you'd like to map another image file to a palette item, say in the case of our three Relationship tools, or for our Subtopic link which has no default icon, you can modify the children of your Creation Tool elements in the mindmap.gmftool model. For example, if you delete the 'Delete Image' entry below the 'Creation Tool Subtopic' element that represents the small icon and replace it with a 'Small Icon Bundle Image' and set its Path property to platform:/plugin/org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/Subtopic.gif, it will use this icon. Of course, you'll need to provide this file or use the one found in the solution to this tutorial section.<br />
<br />
Finally, take a look in the mindmap.genmodel for properties to set for the default wizard and diagram file icons. While you're there, you might want to change the diagram file extension from 'mindmap_diagram' to 'mmd' or something similar. Browsing the properties available in the gmfgen model is a useful exercise.<br />
<br />
Below is an image of our diagram and palette using some new images.<br />
<br />
[[Image:new_icons.png]]<br />
<br style="clear:both;"/><br />
<br />
== Composite Figures ==<br />
[[Image:resource.png|frame|right]]<br />
What we'd like to do is have an actor-style representation for our resources added to our diagram. These will be linked to their respective Topic elements, much like our relationship links between Topic elements. Also, we'd like to have the labels for our Resource figures external and display both the name and email address attribute values of the corresponding domain element.<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:resource_figure.png|frame|right]]<br />
Open up your graphical definition again and add a new Rectangle named 'ResourceFigure' to your Figure Gallery. Set its Outline property to false, along with its Fill. As you can see from the image to the right, we will be adding a series of children to the rectangle, which will act as a container for the elements that comprise our Resource figure. Specifically, right-click and add an XY Layout, and Ellipse for the head, a Polygon for the Body, and sizing elements. Rather than go through all of the gory details of these, the figure code is found below. Either paste it into your mindmap.gmfgraph in the appropriate location using a text editor, or utilize the default editor and properties view.<br />
<br />
To our Canvas, add a new Node named ResourceNode and assign our ResourceFigure as its Figure. Also, notice the new 'BasicLabelFigure' label that is added to the Figure Gallery in the image. Create this and add a new Diagram Label 'ResourceLabel' to the Figure Gallery and Canvas respectively. Note that the Label for our Resource is not a child element of its figure. We want the label to be external, and therefore be allowed to float and be positioned wherever the user would like it.<br />
<br style="clear:both;"/><br />
<br />
<pre><br />
<figures xsi:type="gmfgraph:Rectangle" name="ResourceFigure" outline="false" fill="false" lineWidth="0"><br />
<layout xsi:type="gmfgraph:XYLayout"/><br />
<children xsi:type="gmfgraph:Ellipse" name="Head"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<size x="40" y="20"/><br />
</children><br />
<children xsi:type="gmfgraph:Polygon" name="Body"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<template x="23" y="19"/><br />
<template x="23" y="24"/><br />
<template x="39" y="24"/><br />
<template x="39" y="29"/><br />
<template x="23" y="29"/><br />
<template x="23" y="36"/><br />
<template x="39" y="48"/><br />
<template x="39" y="53"/><br />
<template x="20" y="42"/><br />
<template x="1" y="53"/><br />
<template x="1" y="48"/><br />
<template x="17" y="36"/><br />
<template x="17" y="29"/><br />
<template x="1" y="29"/><br />
<template x="1" y="24"/><br />
<template x="17" y="24"/><br />
<template x="17" y="19"/><br />
</children><br />
<maximumSize dx="40" dy="60"/><br />
<minimumSize dx="40" dy="60"/><br />
<preferredSize dx="40" dy="60"/><br />
<size x="40" y="60"/><br />
</figures><br />
</pre><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> It's a bit tedious to add multiple template points in the manner above, so feel free to open the gmfgraph file in a text editor to make life easier. Furthermore, to get it looking right more quickly, open the generated figure class and simply modify the GEF code directly and run the editor to see how it looks. Then, move this information back into your gmfgraph model. Of course, when the WYSIWYG features of GMF become available and mature, none of this should be necessary.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:resource_tool.png|frame|right]]<br />
We'll need a tool to add Resource nodes, so as you've done many times before, open the mindmap.gmftool model and add a new node creation tool for the Resource. Next, we'll need to add our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:resource_map.png|frame|right]]<br />
First, we'll need to add a new Top Node Reference to our Mapping definition. Set the Containment Feature to our 'EReference resources' attribute of our Map class. Add a child Node Mapping element to this Top Node Reference and select our 'EClass Resource' for the Domain meta information Element property. Of course, we'll select our ResourceNode for the Diagram Node and our Resource creation tool for the palette.<br />
<br />
Now, to add our Label Mapping as a child of the Node Mapping and set the Edit and View Pattern and corresponding features from our Resource class in the domain model. Here, we'll utilize the edit and view pattern properties of the mapping model to allow a Resource label to be displayed as 'name [email@some.com]'. To allow for the proper parsing of what's entered into the direct edit field, we will define an edit pattern for the label as '{0} : {1}' where a colon is used to separate the name and email attributes. Note that the generated plug-in code will contribute to the parserProvider extension-point, which will in turn leverages the Java MessageFormat class.<br />
<br />
=== Generation ===<br />
You will need to make one tweak to the generated code after you transform your mapping model to a new gmfgen model, as before. Open the newly-generated ResourceEditPart class and locate the createNodeShape() method. In this method, you will find a call to figure.setUseLocalCoordinates(false). In order for our polygon to appear in the rendered figure, you will need to set the argument to true. This should be a temporary workaround, and if you're not making changes to the figure, go ahead and add a NOT after @generated in the method comment. <br />
<br />
Run the diagram and check the operation of the label, as well as the look of the figure. It should look similar to the one above. Resources added to the diagram are now available in the properties view for topic assignments, thread authoring, etc. To add the possibility to create links from other elements to a Resource, follow steps similar to how links are used to represent subtopics.<br />
<br />
== Using External Figures ==<br />
<br />
== Creating a Customization Plug-in ==<br />
<br />
Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in. For this purpose, create a new plug-in project named org.eclipse.gmf.examples.mindmap.diagram.custom to your workspace.<br />
<br />
== Custom Actions ==<br />
[[Image:insert_subtopic.png|frame|right]]<br />
The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic. Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or some combination) and have the new Topic created, including the link, and with the in-place editor active on the new Topic. In this section, we will explore how to accomplish just this.<br />
<br />
To begin, we know that the org.eclipse.ui.bindings can be used to assign a Ctrl+I key combination to our action (as seen on the image, though for OS X). This is easily accomplished by contributing to the extension-point in our new *.diagram.custom plugin.xml file. Note that this is a simplistic example that does not declare a context, as you would probably expect to create for your diagram and potentially extend a default GMF diagram context (if one existed ;-).<br />
<br />
<pre><br />
<extension point="org.eclipse.ui.bindings"><br />
<key commandId="org.eclipse.gmf.examples.mindmap.insertSubtopic" sequence="M1+I" schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/><br />
</extension><br />
</pre><br />
<br />
Now, for the command, we'll contribute to the org.eclipse.ui.commands extension-point, as seen below. When you run your diagram, you will see this command category and the shortcut listed in the General | Keys preference page.<br />
<br />
<pre><br />
<extension point="org.eclipse.ui.commands"><br />
<category name="Mindmap" description="Commands related to Mindmap diagrams." id="org.eclipse.gmf.category.mindmap"/><br />
<command categoryId="org.eclipse.gmf.category.mindmap" description="Inserts a new subtopic" id="org.eclipse.gmf.examples.mindmap.insertSubtopic" name="Insert Subtopic"><br />
</command><br />
</extension><br />
</pre><br />
<br />
Now, for the popup menu. We'd like to have a series of potential menu items to insert elements on our diagram (i.e. subtopics, threads, etc.), so our contribution to org.eclipse.ui.popupMenus will define an 'Insert | Subtopic' menu and link it to our binding above through the defintionId:<br />
<br />
<pre><br />
<extension point="org.eclipse.ui.popupMenus"><br />
<objectContribution<br />
adaptable="false"<br />
id="org.eclipse.gmf.examples.mindmap.diagram.ui.objectContribution.TopicEditPart1"<br />
objectClass="org.eclipse.gmf.examples.mindmap.diagram.edit.parts.TopicEditPart"><br />
<menu <br />
id="MindmapInsert" <br />
label="&amp;Insert" <br />
path="additions"> <br />
<separator name="group1"/><br />
</menu><br />
<action<br />
class="org.eclipse.gmf.examples.mindmap.diagram.part.MindmapCreateSubtopicAction"<br />
definitionId="org.eclipse.gmf.examples.mindmap.insertSubtopic"<br />
enablesFor="1"<br />
id="org.eclipse.gmf.examples.mindmap.popup.MindmapCreateSubtopicActionID"<br />
label="&amp;Subtopic"<br />
menubarPath="MindmapInsert/group1"><br />
</action><br />
</objectContribution> <br />
</extension><br />
</pre><br />
<br />
Now, for the fun part... to define the declared MindmapCreateSubtopicAction class. To begin, we know that similar functionality exists in the connection handles feature provided by the runtime (see image below).<br />
[[Image:connection_handle.png|frame|left]]<br />
<br style="clear:both;"/><br />
<br />
After some investigation, it seems the CreateViewAndOptionallyElementCommand class is the key to this functionality, so we will use this code as the inspiration for our action. I expect that if there is a better way, someone from the runtime team will make a recommendation :-). Rather than type in the code, simply copy the MindmapCreateSubtopicAction class into your project from the solution (or retrieve from CVS). The basic concepts are outlined next.<br />
<br />
Our action will implement IObjectActionDelegate, with its run method performing the following:<br />
- create and initialize a CreateConnectionRequest<br />
- create and execute a CompoundCommand, containing a DeferredCreateConnectionViewAndElementCommand<br />
- create and perform a direct edit request on the new subtopic<br />
[[Image:inserted_subtopic.png|frame|right]]<br />
Run the diagram and test the functionality using the keyboard combination (Ctrl+I) or right-click menu. Note that the subtopic is created above and to the right of the parent with direct editing enabled for you to give it a name. As you can see, the code to determine the position is a temporary hack.<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add a composite figure, utilize external images and figures, and create a custom action contained within a new extension plug-in.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_3&diff=4447Graphical Modeling Framework/Tutorial/Part 32006-05-02T19:30:34Z<p>Rgronback: /* Custom Actions */</p>
<hr />
<div>'''Note:''' This is still very much a work in progress...<br />
<br />
In this third part of the GMF Tutorial, we will explore some more advanced capabilities related to the tooling components, while also extending what's generated with customizations to the runtime. Specifically we will add a composite figure using the graphical definition, show how to leverage external figures, and how to use an extension plug-in to add a custom action to our diagram. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_3.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
== New Icons ==<br />
A quick way to get a new polished look for our mindmap diagram is by replacing the generated EMF icons we've seen so far with some that are more, well... distinctive ;) The easiest way to do this is to replace the GIF images found in our org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/ folder. <br />
<br />
In case you'd like to map another image file to a palette item, say in the case of our three Relationship tools, or for our Subtopic link which has no default icon, you can modify the children of your Creation Tool elements in the mindmap.gmftool model. For example, if you delete the 'Delete Image' entry below the 'Creation Tool Subtopic' element that represents the small icon and replace it with a 'Small Icon Bundle Image' and set its Path property to platform:/plugin/org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/Subtopic.gif, it will use this icon. Of course, you'll need to provide this file or use the one found in the solution to this tutorial section.<br />
<br />
Finally, take a look in the mindmap.genmodel for properties to set for the default wizard and diagram file icons. While you're there, you might want to change the diagram file extension from 'mindmap_diagram' to 'mmd' or something similar. Browsing the properties available in the gmfgen model is a useful exercise.<br />
<br />
Below is an image of our diagram and palette using some new images.<br />
<br />
[[Image:new_icons.png]]<br />
<br style="clear:both;"/><br />
<br />
== Composite Figures ==<br />
[[Image:resource.png|frame|right]]<br />
What we'd like to do is have an actor-style representation for our resources added to our diagram. These will be linked to their respective Topic elements, much like our relationship links between Topic elements. Also, we'd like to have the labels for our Resource figures external and display both the name and email address attribute values of the corresponding domain element.<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:resource_figure.png|frame|right]]<br />
Open up your graphical definition again and add a new Rectangle named 'ResourceFigure' to your Figure Gallery. Set its Outline property to false, along with its Fill. As you can see from the image to the right, we will be adding a series of children to the rectangle, which will act as a container for the elements that comprise our Resource figure. Specifically, right-click and add an XY Layout, and Ellipse for the head, a Polygon for the Body, and sizing elements. Rather than go through all of the gory details of these, the figure code is found below. Either paste it into your mindmap.gmfgraph in the appropriate location using a text editor, or utilize the default editor and properties view.<br />
<br />
To our Canvas, add a new Node named ResourceNode and assign our ResourceFigure as its Figure. Also, notice the new 'BasicLabelFigure' label that is added to the Figure Gallery in the image. Create this and add a new Diagram Label 'ResourceLabel' to the Figure Gallery and Canvas respectively. Note that the Label for our Resource is not a child element of its figure. We want the label to be external, and therefore be allowed to float and be positioned wherever the user would like it.<br />
<br style="clear:both;"/><br />
<br />
<pre><br />
<figures xsi:type="gmfgraph:Rectangle" name="ResourceFigure" outline="false" fill="false" lineWidth="0"><br />
<layout xsi:type="gmfgraph:XYLayout"/><br />
<children xsi:type="gmfgraph:Ellipse" name="Head"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<size x="40" y="20"/><br />
</children><br />
<children xsi:type="gmfgraph:Polygon" name="Body"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<template x="23" y="19"/><br />
<template x="23" y="24"/><br />
<template x="39" y="24"/><br />
<template x="39" y="29"/><br />
<template x="23" y="29"/><br />
<template x="23" y="36"/><br />
<template x="39" y="48"/><br />
<template x="39" y="53"/><br />
<template x="20" y="42"/><br />
<template x="1" y="53"/><br />
<template x="1" y="48"/><br />
<template x="17" y="36"/><br />
<template x="17" y="29"/><br />
<template x="1" y="29"/><br />
<template x="1" y="24"/><br />
<template x="17" y="24"/><br />
<template x="17" y="19"/><br />
</children><br />
<maximumSize dx="40" dy="60"/><br />
<minimumSize dx="40" dy="60"/><br />
<preferredSize dx="40" dy="60"/><br />
<size x="40" y="60"/><br />
</figures><br />
</pre><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> It's a bit tedious to add multiple template points in the manner above, so feel free to open the gmfgraph file in a text editor to make life easier. Furthermore, to get it looking right more quickly, open the generated figure class and simply modify the GEF code directly and run the editor to see how it looks. Then, move this information back into your gmfgraph model. Of course, when the WYSIWYG features of GMF become available and mature, none of this should be necessary.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:resource_tool.png|frame|right]]<br />
We'll need a tool to add Resource nodes, so as you've done many times before, open the mindmap.gmftool model and add a new node creation tool for the Resource. Next, we'll need to add our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:resource_map.png|frame|right]]<br />
First, we'll need to add a new Top Node Reference to our Mapping definition. Set the Containment Feature to our 'EReference resources' attribute of our Map class. Add a child Node Mapping element to this Top Node Reference and select our 'EClass Resource' for the Domain meta information Element property. Of course, we'll select our ResourceNode for the Diagram Node and our Resource creation tool for the palette.<br />
<br />
Now, to add our Label Mapping as a child of the Node Mapping and set the Edit and View Pattern and corresponding features from our Resource class in the domain model. Here, we'll utilize the edit and view pattern properties of the mapping model to allow a Resource label to be displayed as 'name [email@some.com]'. To allow for the proper parsing of what's entered into the direct edit field, we will define an edit pattern for the label as '{0} : {1}' where a colon is used to separate the name and email attributes. Note that the generated plug-in code will contribute to the parserProvider extension-point, which will in turn leverages the Java MessageFormat class.<br />
<br />
=== Generation ===<br />
You will need to make one tweak to the generated code after you transform your mapping model to a new gmfgen model, as before. Open the newly-generated ResourceEditPart class and locate the createNodeShape() method. In this method, you will find a call to figure.setUseLocalCoordinates(false). In order for our polygon to appear in the rendered figure, you will need to set the argument to true. This should be a temporary workaround, and if you're not making changes to the figure, go ahead and add a NOT after @generated in the method comment. <br />
<br />
Run the diagram and check the operation of the label, as well as the look of the figure. It should look similar to the one above. Resources added to the diagram are now available in the properties view for topic assignments, thread authoring, etc. To add the possibility to create links from other elements to a Resource, follow steps similar to how links are used to represent subtopics.<br />
<br />
== Using External Figures ==<br />
<br />
== Creating a Customization Plug-in ==<br />
<br />
Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in. For this purpose, create a new plug-in project named org.eclipse.gmf.examples.mindmap.diagram.custom to your workspace.<br />
<br />
== Custom Actions ==<br />
[[Image:insert_subtopic.png|frame|right]]<br />
The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic. Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or some combination) and have the new Topic created, including the link, and with the in-place editor active on the new Topic. In this section, we will explore how to accomplish just this.<br />
<br />
To begin, we know that the org.eclipse.ui.bindings can be used to assign a Ctrl+I key combination to our action (as seen on the image, though for OS X). This is easily accomplished by contributing to the extension-point in our new *.diagram.custom plugin.xml file. Note that this is a simplistic example that does not declare a context, as you would probably expect to create for your diagram and potentially extend a default GMF diagram context (if one existed ;-).<br />
<br />
<pre><br />
<extension point="org.eclipse.ui.bindings"><br />
<key commandId="org.eclipse.gmf.examples.mindmap.insertSubtopic" sequence="M1+I" schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/><br />
</extension><br />
</pre><br />
<br />
Now, for the command, we'll contribute to the org.eclipse.ui.commands extension-point, as seen below. When you run your diagram, you will see this command category and the shortcut listed in the General | Keys preference page.<br />
<br />
<pre><br />
<extension point="org.eclipse.ui.commands"><br />
<category name="Mindmap" description="Commands related to Mindmap diagrams." id="org.eclipse.gmf.category.mindmap"/><br />
<command categoryId="org.eclipse.gmf.category.mindmap" description="Inserts a new subtopic" id="org.eclipse.gmf.examples.mindmap.insertSubtopic" name="Insert Subtopic"><br />
</command><br />
</extension><br />
</pre><br />
<br />
Now, for the popup menu. We'd like to have a series of potential menu items to insert elements on our diagram (i.e. subtopics, threads, etc.), so our contribution to org.eclipse.ui.popupMenus will define an 'Insert | Subtopic' menu and link it to our binding above through the defintionId:<br />
<br />
<pre><br />
<extension point="org.eclipse.ui.popupMenus"><br />
<objectContribution<br />
adaptable="false"<br />
id="org.eclipse.gmf.examples.mindmap.diagram.ui.objectContribution.TopicEditPart1"<br />
objectClass="org.eclipse.gmf.examples.mindmap.diagram.edit.parts.TopicEditPart"><br />
<menu <br />
id="MindmapInsert" <br />
label="&amp;Insert" <br />
path="additions"> <br />
<separator name="group1"/><br />
</menu><br />
<action<br />
class="org.eclipse.gmf.examples.mindmap.diagram.part.MindmapCreateSubtopicAction"<br />
definitionId="org.eclipse.gmf.examples.mindmap.insertSubtopic"<br />
enablesFor="1"<br />
id="org.eclipse.gmf.examples.mindmap.popup.MindmapCreateSubtopicActionID"<br />
label="&amp;Subtopic"<br />
menubarPath="MindmapInsert/group1"><br />
</action><br />
</objectContribution> <br />
</extension><br />
</pre><br />
<br />
Now, for the fun part... to define the declared MindmapCreateSubtopicAction class. To begin, we know that similar functionality exists in the connection handles feature provided by the runtime (see image below).<br />
[[Image:connection_handle.png|frame|left]]<br />
<br style="clear:both;"/><br />
<br />
After some investigation, it seems the CreateViewAndOptionallyElementCommand class is the key to this functionality, so we will use this code as the inspiration for our action. I expect that if there is a better way, someone from the runtime team will make a recommendation :-). Rather than type in the code, simply copy the MindmapCreateSubtopicAction class into your project from the solution (or retrieve from CVS). The basic concepts are outlined next.<br />
<br />
Our action will implement IObjectActionDelegate, with its run method performing the following:<br />
- create and initialize a CreateConnectionRequest<br />
- create and execute a CompoundCommand, containing a DeferredCreateConnectionViewAndElementCommand<br />
- create and perform a direct edit request on the new subtopic<br />
<br />
Run the diagram and test the functionality using the keyboard combination (Ctrl+I) or right-click menu. Note that the subtopic is created above and to the right of the parent with direct editing enabled for you to give it a name. As you can see, the code to determine the position is a temporary hack.<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add a composite figure, utilize external images and figures, and create a custom action contained within a new extension plug-in.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_1&diff=4445Graphical Modeling Framework/Tutorial/Part 12006-05-02T18:10:07Z<p>Rgronback: /* Quick Start */</p>
<hr />
<div>This tutorial will introduce the Graphical Modeling Framework ([http://www.eclipse.org/gmf GMF]), an Eclipse Technology subproject which aims to provide a generative bridge between the Eclipse Modeling Framework ([http://www.eclipse.org/emf EMF]) and Graphical Editing Framework ([http://www.eclipse.org/gef GEF]). <br />
<br />
In this tutorial, a mindmap application will be developed, as described [http://www.eclipse.org/gmf/requirements.php#scenarios here]. This tutorial describes the functionality provided by GMF in its current state, using this build ([http://download.eclipse.org/technology/gmf/downloads/index.php 1.0M6]). It is expected that this tutorial will evolve with GMF to introduce new functionality as it is developed. New functionality will be covered by installments added to this tutorial, each with a corresponding viewlet. A viewlet for this installment of the tutorial can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial.html here].<br />
<br />
== Overview of GMF ==<br />
The use of both EMF and GEF for building Eclipse-based functionality is quite common. Many references below provide information on how to utilize these frameworks together, some of which inspired the GMF project itself. Before diving into a new GMF project, let's explore a little of how GMF approaches the task of utilizing EMF and GEF in a generative manner. Another article focusing on the runtime portion of GMF is found [http://www.eclipse.org/articles/Article-Introducing-GMF/article.html here].<br />
<br />
The GMF project has adopted the term 'toolsmith' to refer to developers that use GMF to build plug-ins, while 'user' is typically refered to those who utilize said plug-ins, and who may also be developers. From a usability perspective, the number and types of 'models' utilized by GMF internally should be hidden to the greatest extent possible. However, it is likely that most toolsmiths are interested in knowing what is going on under the covers, so a description of each model is presented in this tutorial.<br />
<br />
[[Image:overview.png|frame|right|GMF Overview]]<br />
<br />
This is a diagram that illustrates the main components and models used during GMF-based development. Core to GMF is the concept of a graphical definition model. This model contains information related to the graphical elements that will appear in a GEF-based runtime, but have no direct connection to the domain models for which they will provide representation and editing. An optional tooling definition model is used to design the palette and other periphery (overview, zoom, etc.).<br />
<br />
It is expected that a graphical or tooling definition may work equally well for several domains. For example, the UML class diagram has many counterparts, all of which are strikingly similar in their basic appearance and structure. A goal of GMF is to allow the graphical definition to be reused for several domains. This is achieved by using a separate mapping model to link the graphical and tooling definitions to the selected domain model(s).<br />
<br />
Once the appropriate mappings are defined, GMF provides a generator model to allow implementation details to be defined for the generation phase. The production of an editor plug-in based on the generator model will target a final model; that is, the diagram runtime (or "notation") model. The runtime will bridge the notation and domain model(s) when a user is working with a diagram, and also provides for the persistence and synchronization of both. An important aspect of this runtime is that it provides a services-based approach to EMF and GEF functionality and is able to be leveraged by non-generated applications.<br />
<br />
With the basics of GMF covered, let's now walk through the process of using GMF in the development of a graphical editing surface for a particular domain. First, you will need to install GMF and its dependencies.<br />
<br style="clear:both;"/><br />
<br />
== Setup ==<br />
This version of the tutorial was written using this build of GMF ([http://download.eclipse.org/technology/gmf/downloads/index.php 1.0M6]). Note that the prerequisites are listed on the build page, which must be installed prior to installing GMF, either from the [http://download.eclipse.org/technology/gmf/downloads download] page, or from the update manager [http://download.eclipse.org/technology/gmf/update-site/index.html site]. The TaiPan example referenced below is maintained in CVS and should remain functional with the latest builds of GMF, even if the tutorial is not quite up-to-date.<br />
<br />
==== Quick Start ====<br />
[[Image:checkout.png|right]]<br />
If you're anxious to see GMF in action, check out the Taipan example projects into your workspace from CVS by switching to the CVS Repository Exploring perspective and adding a repository location as shown in the image to the right. Otherwise, you can skip to the next section.<br />
<br />
Navigate to /HEAD/org.eclipse.gmf/examples and select the three org.eclipse.gmf.examples.taipan.* modules. Right-click and select Check Out. If you are not using the latest build and prerequisites of GMF, you can always check out the version of the Taipan by date to correspond with the version you're using. The important point is that you'll need to work with synchronized versions of the GMF SDK and the Taipan example. To do this, after checkout you can right-click on the projects and selecting 'Team | Switch to Another Branch or Version...' and then choose 'Select the tag from the following list' and use the 'Add Date...' button at the bottom to enter the date of the GMF 1.0M6 release (15 Apr 2006). Alternatively, use the 1.0M6 tag itself: 'M6_10'. Press Finish and you're set.<br />
<br />
Switch to the Plug-in Development perspective and open the models folder within the org.eclipse.gmf.examples.taipan project. Explore each of the models found here, particularly the taipan.gmfgraph and taipan.gmfmap models and their element properties.<br />
<br />
We will look at each of the models in turn during the tutorial, but just to validate your configuration, you should be able to run this sample in a runtime workspace (simply accept the defaults for a new 'Eclipse Application' run configuration). In the runtime workspace, create an empty project and a new 'TaiPan Diagram' found in the Examples folder of the New dialog. Name it whatever you wish and click Finish. The generated diagram editor should open for you to explore. Some things to note in particular are:<br />
<br />
:* tool palette and overview<br />
:* layout and selection tools<br />
:* diagram image export (svg, bmp, jpeg, gif)<br />
:* tabbed properties view<br />
:* font and color options for selected element<br />
:* link routing and style options<br />
:* pop-up bars and connection handles<br />
:* notes and geometric shapes<br />
:* animated zoom and layout<br />
:* diagram printing<br />
<br />
[[Image:taipan_diagram.png|center]]<br />
<br />
This concludes the quick start portion of this tutorial. What follows next is a more detailed look at each of the models shown above during the creation of a mindmap modeling surface.<br />
<br />
==== A New Project ====<br />
<br />
Before we start, you should specify for your workspace (or at least for your GMF projects) 1.4 compiler settings. In Window... Preferences... Java...Compiler options, make sure you have selected a Compliance Level of 1.4, including options for generated .class and source file compatibility. GMF itself is developed using these settings, although technically nothing prevents you from using Java 5 in your workspace, provided your runtime launch configuration also uses Java 5.<br />
<br />
As described [http://www.eclipse.org/gmf/requirements.php#scenarios here], one of the usage scenarios for GMF includes producing a graphical surface for a mindmap application, to be complemented with an alternative view of its temporal information (likely a Gantt chart). This section of the tutorial will demonstrate GMF's capabilities toward this end, and will continue to evolve as the project matures. If you'd prefer to follow along using a set of projects representing the complete solution to this tutorial, you can find a zip of them [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_1.zip here].<br />
<br />
[[Image:cheatsheet_project.png|right]]<br />
<br />
New to GMF is a Tutorial Cheat Sheet found under 'Help | Cheat Sheets...' If you open this cheat sheet and follow through each step, you can accomplish most of this first tutorial segment, while taking advantage of some actions that will launch and pre-populate wizards to get you started. Try this now to create your new project.<br />
<br />
Alternatively, you can begin by creating an "New GMF Project" found under 'Graphical Modeling Framework' in the New dialog (Ctrl+N). Name the project 'org.eclipse.gmf.examples.mindmap' and create a new folder named 'model' in its root.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Domain Model Definition ==<br />
<br />
Although it may seem necessary to begin with the domain model, it is not in the case with GMF, as the diagram definition is maintained separate from the domain. However, we will begin with the domain in the tutorial as it is likely familiar to most, and will allow us to jumpstart our diagram definition from the domain model using a wizard in the next section.<br />
<br />
A basic domain model for our mindmap is found [http://www.eclipse.org/gmf/tutorial/mindmap.ecore here]. Copy this file into your 'model' folder and feel free to examine the model, if you wish. GMF provides a (bootstrapped) graphical editor to complement the standard EMF generated editors. In order to use the GMF Ecore editor, you will need to install the GMF Examples feature. To render the mindmap.ecore (or any *.ecore model) with the editor, simply right-click the file and select 'Initialize ecore_diagram diagram file' from the menu. The next step is to layout the diagram using the 'Arrange All' action.<br />
<br />
[[Image:domain.png|frame|center|Mindmap domain model]]<br />
<br />
To continue, create a new mindmap.genmodel from the mindmap.ecore file using the New > Eclipse Modeling Framework > EMF Model wizard. You may wish to change the 'Base Package' property for the genmodel's 'Mindmap' package to org.eclipse.gmf.examples to have your generated packaging match the project name. These steps are also covered in the next step of the cheat sheet.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be sure to give your genmodel file the same name as your domain model (i.e. both mindmap.*), as GMF currently expects this naming convention to identify the genmodel for the mapped domain model.<br />
</blockquote><br />
<br />
Generate the model and edit code using the right-click menu available from the root of the generator model. There is no need to create an editor or tests, but you are welcome to do so if you'd like. Now, we're ready to begin creating the graphical and mapping definitions for our mindmap application.<br />
<br />
== Graphical Definition ==<br />
[[Image:graphical-thumbnail.png|frame|right|thumbnail|Graphical Definition Model, view in [[Media:graphical.png|actual size]].]]<br />
A graphical definition model is used to define the figures, nodes, links, etc. that you will display on your diagram. The model you will work with to do this is seen at the right.<br />
<br />
Continuing on with the next step in the cheat sheet, we will create a new graphical definition model. The cheat sheet will launch the GMFGraph Model wizard, which is found in the Graphical Modeling Framework folder of the New (Ctrl + N) dialog. Select the 'model' folder under your org.eclipse.gmf.examples.mindmap project for the mindmap.gmfgraph model, and on the next page of the wizard use 'Browse' to locate your mindmap.ecore file.<br />
<br />
On the last page of the wizard, select a minimal set of element, link, and label options for our Topic class as shown in the image. Later on, feel free to experiment with this wizard and observe its output. For now, we're just interested in getting a minimal set of models to get started. Click 'Finish' to complete.<br />
<br />
If you examine the model, you will find a Canvas at the root with a Figure gallery containing basic Rectangle, Label, and Polyline Connection elements. These are used by corresponding Node, Diagram Label, and Connection elements to represent our Topics from the domain model. We can leave the defaults as-is for now and continue with our tooling definition in the next step of the cheat sheet.<br />
<br />
[[Image:cheatsheet_graph.png]]<br />
<br style="clear:both;"/><br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are several figure galleries intended for reuse and included with GMF. You can load these into your *.gmfgraph model (or *.gmfmap model) by using "Load Resource..." and entering <code>platform:/plugin/org.eclipse.gmf.graphdef/models/basic.gmfgraph</code> for the Resource URI. Others available include <code>classDiagram.gmfgraph</code> and <code>stateDiagram.gmfgraph</code>.<br />
</blockquote><br />
<br />
== Tooling Definition ==<br />
[[Image:tooling-thumbnail.png|frame|right|thumbnail|Tooling Definition Model, view in [[Media:tooling.png|actual size]].]]<br />
As mentioned above, the tooling definition model is used to specify the palette, creation tools, actions, etc. for your graphical elements. To the right is a diagram of the model.<br />
<br />
The cheat sheet will guide you through a very similar process for getting started with our Tooling definition model. In fact, the two steps are virtually identical, as the mindmap domain model is loaded and examined for possible tooling needs. We will simply select the same options we did for the graphical definition, save a tool for the Topic name label, and begin with a very simple palette for our Topic elements.<br />
<br style="clear:both;"/><br />
[[Image:cheatsheet_tool.png]]<br />
<br style="clear:both;"/><br />
<br />
Looking at the model provided for us, we see there is a top-level 'Tool Registry' element, under which we find a Palette. The palette contains a Tool Group with Creation Tool elements for both Topic nodes and links for subtopic elements that were identified by the wizard. We will reorganize these and modify them a bit in the future, but for now we'll leave the defaults and move on to the mapping definition. Feel free to browse this model and inspect its properties to familiarize yourself with tooling definitions.<br />
<br />
== Mapping Definition ==<br />
[[Image:mapping-thumbnail.png|frame|right|thumbnail|Mapping Definition Model, view in [[Media:mapping.png|actual size]].]]<br />
<br />
The mapping definition model will let us bind the three models we have so far: the domain, the graphical definition, and the tooling definition. To the right is an image of this model. This is a key model to GMF development and will be used as input to a transformation step which will produce our final model, the generation model.<br />
<br />
Continuing on with our cheat sheet, follow the instructions to launch the GMFMap Model wizard. We will again select the 'model' folder to hold our mindmap.gmfmap file and move on to load each of the preselected mindmap.ecore, mindmap.gmfgraph, and mindmap.gmftool models. On the next page, select 'Map' as the Diagram Root Element and finally, make the last page look like the image below.<br />
<br />
[[Image:cheatsheet_map.png]]<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:label_mapping.png|right]]<br />
One thing we need to do manually is set the Diagram Label property of our Label Mapping to our TopicNameLabel from the graphical definition (yes, this is a temporary feature of the mapping wizard ;). The result should look like the image to the right.<br />
<br />
Before moving on, let's pause to describe the mappings. We'll start with the Label Mapping, as it's the one we're looking at here. It's a straightforward mapping, with the Diagram Label property set as we discussed and a mapping to the 'EAttribute name' feature on our Topic element in the domain model.<br />
<br />
Moving up to the Node Mapping, we see that our Diagram Node is mapped to the TopicNode of our graphical definition with its corresponding domain model element mapped to our Topic class. The Topic creation tool is also specified in the mapping.<br />
<br />
Above the Node Mapping you will find a Top Node Reference. Its Containment Feature is set to the 'EReference rootTopics' feature of our Map class. So, when new Topic nodes are added to the diagram, the instance of our domain Topic will be added to the rootTopics containment reference of our Map class. The label of the node will display the 'name' attribute of the Topic.<br />
<br />
The Map class itself is represented by the Canvas. Select the Canvas Mapping element to see this defined, along with the map to the Palette in our tooling definition. Finally, if you select the Link Mapping, you will observe that connections represented by our TopicSubtopicsLink are mapped to the 'EReference subtopics' feature of our Topic class, and are created with our TopicSubtopics Creation Tool.<br />
<br style="clear:both;"/><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Note that it is important to select the proper element when defining mappings at this stage; that is, before GMF does more complete filtering and validation. A good way to ensure you have selected the element you intended (as several may have the same name), open the mapping definition (*.gmfmap) file in a text editor.<br />
</blockquote><br />
<br />
== Code Generation ==<br />
[[Image:generation-thumbnail.png|frame|right|thumbnail|Generation Model, view in [[Media:generation.png|actual size]].]]<br />
The last model to cover in this tutorial, and the one that is not as critical to understand at this point, is the GMF generator model. See the diagram to the right if you're interested in examining this model.<br />
<br />
Now that the minimal graphical elements and mappings are defined, we can generate the code needed to test our work so far. To accomplish this, we will first create a generator model (*.gmfgen) in order to set the properties for code generation, similar to the familiar EMF genmodel. To accomplish this, right-click the mapping file and select 'Create generator model...' as shown below. When prompted, keep the default name 'mindmap.gmfgen'.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> You'll need to have your Java | Compiler | JDK Compliance settings to 1.4 (including Generated .class files compatibility and Source compatibility) when working with GMF.<br />
</blockquote><br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:create_gmfgen.png|right]]<br />
<br />
Now, we can examine the generator model to see what it includes (if you're the curious type). We'll keep all the default values for now and right-click the mindmap.gmfgen file and select 'Generate diagram code' to proceed. If all goes well, you will see a "Code generation completed successfully." message dialog. Dismiss the dialog, opting to never see it again, and notice the new org.eclipse.gmf.examples.mindmap.diagram plug-in in your workspace.<br />
<br />
Up to this point, the models used have been fairly straightforward to edit and understand. The transformation that takes place to create the generator model (*.gmfgen) from the mapping model involves a bit of logic that is important to understand. However, it is not required to understand the details at this point in the tutorial, so additional information can be found [[GMF_GenModel|here]] for those interested.<br />
<br style="clear:both;"/><br />
<br />
== Running the Diagram ==<br />
[[Image:notation-thumbnail.png|frame|right|thumbnail|Notation Model, view in [[Media:notation.png|actual size]].]]<br />
Recall that the runtime uses its own 'notation model' to display and persist the graphical components for your diagram. An image of this model is linked here for those interested.<br />
<br />
Now that we have generated the plug-in needed for our diagram, let's launch a new runtime workspace and test the diagram. The default settings of a new Eclipse Application runtime configuration should work fine, while you may opt to run a minimal configuration that includes only your generated plug-ins and their runtime dependencies within an org.eclipse.platform.ide configuration.<br />
<br />
Create an empty project and invoke the New... dialog (Ctrl+N). Under 'Examples' you'll notice your new Mindmap Diagram. Create a new diagram and explore its functionality, and look for the creation of the domain model instance as you add and save diagram elements. Of course, we've only specified enough in our diagram definition to allow for simple Topic elements and subtopic links. <br />
<br />
[[Image:basic_mindmap.png|center]]<br />
<br />
== Summary ==<br />
As you have seen, using GMF as a means by which to get started creating graphical editors for your domain models is fairly straightforward. We have seen how creating a graphical definition and a mapping definition to the chosen domain can be used to generate much of the basic functionality expected in an EMF/GEF-based editor. In the future, GMF will mature and include more advance capabilities, so check back to see how this tutorial matures along with the project. In the meantime, if you've skipped over links that provide more detail on certain aspects of GMF, now may be the time to do so. Otherwise, feel free to continue with the [[GMF_Tutorial_Part_2|GMF Tutorial Part 2]].<br />
<br />
== References ==<br />
* [http://www.eclipse.org/gmf Graphical Modeling Framework Website]<br />
<br />
* [http://publib-b.boulder.ibm.com/Redbooks.nsf/RedbookAbstracts/sg246302.html Eclipse Development using the Graphical Editing Framework and the Eclipse Modeling Framework], IBM Redbook<br />
<br />
* [http://www.eclipse.org/emf/docs.php EMF Documentation]<br />
<br />
* [http://eclipse.org/emf/docs.php?doc=tutorials/clibmod/clibmod.html Generating an EMF Model]<br />
<br />
* [http://sourceforge.net/projects/merlingenerator/ Merlin Homepage]<br />
<br />
* [http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.gef.examples.ediagram/?cvsroot=Tools_Project EDiagram Example Source]<br />
<br />
* [http://www.eclipse.org/articles/Article-GEF-EMF/gef-emf.html Using GEF with EMF], Eclipse Corner Article<br />
<br />
* [http://www.eclipse.org/emft EMF Technology project]<br />
<br />
* [http://www.omg.org/docs/ptc/03-10-14.pdf OCL Specification]</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_3&diff=4382Graphical Modeling Framework/Tutorial/Part 32006-04-28T21:26:24Z<p>Rgronback: /* Custom Actions */</p>
<hr />
<div>'''Note:''' This is still very much a work in progress...<br />
<br />
In this third part of the GMF Tutorial, we will explore some more advanced capabilities related to the tooling components, while also extending what's generated with customizations to the runtime. Specifically we will add a composite figure using the graphical definition, show how to leverage external figures, and how to use an extension plug-in to add a custom action to our diagram. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_3.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
== New Icons ==<br />
A quick way to get a new polished look for our mindmap diagram is by replacing the generated EMF icons we've seen so far with some that are more, well... distinctive ;) The easiest way to do this is to replace the GIF images found in our org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/ folder. <br />
<br />
In case you'd like to map another image file to a palette item, say in the case of our three Relationship tools, or for our Subtopic link which has no default icon, you can modify the children of your Creation Tool elements in the mindmap.gmftool model. For example, if you delete the 'Delete Image' entry below the 'Creation Tool Subtopic' element that represents the small icon and replace it with a 'Small Icon Bundle Image' and set its Path property to platform:/plugin/org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/Subtopic.gif, it will use this icon. Of course, you'll need to provide this file or use the one found in the solution to this tutorial section.<br />
<br />
Finally, take a look in the mindmap.genmodel for properties to set for the default wizard and diagram file icons. While you're there, you might want to change the diagram file extension from 'mindmap_diagram' to 'mmd' or something similar. Browsing the properties available in the gmfgen model is a useful exercise.<br />
<br />
Below is an image of our diagram and palette using some new images.<br />
<br />
[[Image:new_icons.png]]<br />
<br style="clear:both;"/><br />
<br />
== Composite Figures ==<br />
[[Image:resource.png|frame|right]]<br />
What we'd like to do is have an actor-style representation for our resources added to our diagram. These will be linked to their respective Topic elements, much like our relationship links between Topic elements. Also, we'd like to have the labels for our Resource figures external and display both the name and email address attribute values of the corresponding domain element.<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:resource_figure.png|frame|right]]<br />
Open up your graphical definition again and add a new Rectangle named 'ResourceFigure' to your Figure Gallery. Set its Outline property to false, along with its Fill. As you can see from the image to the right, we will be adding a series of children to the rectangle, which will act as a container for the elements that comprise our Resource figure. Specifically, right-click and add an XY Layout, and Ellipse for the head, a Polygon for the Body, and sizing elements. Rather than go through all of the gory details of these, the figure code is found below. Either paste it into your mindmap.gmfgraph in the appropriate location using a text editor, or utilize the default editor and properties view.<br />
<br />
To our Canvas, add a new Node named ResourceNode and assign our ResourceFigure as its Figure. Also, notice the new 'BasicLabelFigure' label that is added to the Figure Gallery in the image. Create this and add a new Diagram Label 'ResourceLabel' to the Figure Gallery and Canvas respectively. Note that the Label for our Resource is not a child element of its figure. We want the label to be external, and therefore be allowed to float and be positioned wherever the user would like it.<br />
<br style="clear:both;"/><br />
<br />
<pre><br />
<figures xsi:type="gmfgraph:Rectangle" name="ResourceFigure" outline="false" fill="false" lineWidth="0"><br />
<layout xsi:type="gmfgraph:XYLayout"/><br />
<children xsi:type="gmfgraph:Ellipse" name="Head"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<size x="40" y="20"/><br />
</children><br />
<children xsi:type="gmfgraph:Polygon" name="Body"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<template x="23" y="19"/><br />
<template x="23" y="24"/><br />
<template x="39" y="24"/><br />
<template x="39" y="29"/><br />
<template x="23" y="29"/><br />
<template x="23" y="36"/><br />
<template x="39" y="48"/><br />
<template x="39" y="53"/><br />
<template x="20" y="42"/><br />
<template x="1" y="53"/><br />
<template x="1" y="48"/><br />
<template x="17" y="36"/><br />
<template x="17" y="29"/><br />
<template x="1" y="29"/><br />
<template x="1" y="24"/><br />
<template x="17" y="24"/><br />
<template x="17" y="19"/><br />
</children><br />
<maximumSize dx="40" dy="60"/><br />
<minimumSize dx="40" dy="60"/><br />
<preferredSize dx="40" dy="60"/><br />
<size x="40" y="60"/><br />
</figures><br />
</pre><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> It's a bit tedious to add multiple template points in the manner above, so feel free to open the gmfgraph file in a text editor to make life easier. Furthermore, to get it looking right more quickly, open the generated figure class and simply modify the GEF code directly and run the editor to see how it looks. Then, move this information back into your gmfgraph model. Of course, when the WYSIWYG features of GMF become available and mature, none of this should be necessary.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:resource_tool.png|frame|right]]<br />
We'll need a tool to add Resource nodes, so as you've done many times before, open the mindmap.gmftool model and add a new node creation tool for the Resource. Next, we'll need to add our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:resource_map.png|frame|right]]<br />
First, we'll need to add a new Top Node Reference to our Mapping definition. Set the Containment Feature to our 'EReference resources' attribute of our Map class. Add a child Node Mapping element to this Top Node Reference and select our 'EClass Resource' for the Domain meta information Element property. Of course, we'll select our ResourceNode for the Diagram Node and our Resource creation tool for the palette.<br />
<br />
Now, to add our Label Mapping as a child of the Node Mapping and set the Edit and View Pattern and corresponding features from our Resource class in the domain model. Here, we'll utilize the edit and view pattern properties of the mapping model to allow a Resource label to be displayed as 'name [email@some.com]'. To allow for the proper parsing of what's entered into the direct edit field, we will define an edit pattern for the label as '{0} : {1}' where a colon is used to separate the name and email attributes. Note that the generated plug-in code will contribute to the parserProvider extension-point, which will in turn leverages the Java MessageFormat class.<br />
<br />
=== Generation ===<br />
You will need to make one tweak to the generated code after you transform your mapping model to a new gmfgen model, as before. Open the newly-generated ResourceEditPart class and locate the createNodeShape() method. In this method, you will find a call to figure.setUseLocalCoordinates(false). In order for our polygon to appear in the rendered figure, you will need to set the argument to true. This should be a temporary workaround, and if you're not making changes to the figure, go ahead and add a NOT after @generated in the method comment. <br />
<br />
Run the diagram and check the operation of the label, as well as the look of the figure. It should look similar to the one above. Resources added to the diagram are now available in the properties view for topic assignments, thread authoring, etc. To add the possibility to create links from other elements to a Resource, follow steps similar to how links are used to represent subtopics.<br />
<br />
== Using External Figures ==<br />
<br />
== Creating a Customization Plug-in ==<br />
<br />
Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in. For this purpose, create a new plug-in project named org.eclipse.gmf.examples.mindmap.diagram.custom to your workspace.<br />
<br />
== Custom Actions ==<br />
[[Image:insert_subtopic.png|frame|right]]<br />
The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic. Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or some combination) and have the new Topic created, including the link, and with the in-place editor active on the new Topic. In this section, we will explore how to accomplish just this.<br />
<br />
To begin, we know that the org.eclipse.ui.bindings can be used to assign a Ctrl+I key combination to our action (as seen on the image, though for OS X). This is easily accomplished by contributing to the extension-point in our new *.diagram.custom plugin.xml file. Note that this is a simplistic example that does not declare a context, as you would probably expect to create for your diagram and potentially extend a default GMF diagram context (if one existed ;-).<br />
<br />
<pre><br />
<extension point="org.eclipse.ui.bindings"><br />
<key commandId="org.eclipse.gmf.examples.mindmap.insertSubtopic" sequence="M1+I" schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/><br />
</extension><br />
</pre><br />
<br />
Now, for the command, we'll contribute to the org.eclipse.ui.commands extension-point, as seen below. When you run your diagram, you will see this command category and the shortcut listed in the General | Keys preference page.<br />
<br />
<pre><br />
<extension point="org.eclipse.ui.commands"><br />
<category name="Mindmap" description="Commands related to Mindmap diagrams." id="org.eclipse.gmf.category.mindmap"/><br />
<command categoryId="org.eclipse.gmf.category.mindmap" description="Inserts a new subtopic" id="org.eclipse.gmf.examples.mindmap.insertSubtopic" name="Insert Subtopic"><br />
</command><br />
</extension><br />
</pre><br />
<br />
Now, for the popup menu. We'd like to have a series of potential menu items to insert elements on our diagram (i.e. subtopics, threads, etc.), so our contribution to org.eclipse.ui.popupMenus will define an 'Insert | Subtopic' menu and link it to our binding above through the defintionId:<br />
<br />
<pre><br />
<extension point="org.eclipse.ui.popupMenus"><br />
<objectContribution<br />
adaptable="false"<br />
id="org.eclipse.gmf.examples.mindmap.diagram.ui.objectContribution.TopicEditPart1"<br />
objectClass="org.eclipse.gmf.examples.mindmap.diagram.edit.parts.TopicEditPart"><br />
<menu <br />
id="MindmapInsert" <br />
label="&amp;Insert" <br />
path="additions"> <br />
<separator name="group1"/><br />
</menu><br />
<action<br />
class="org.eclipse.gmf.examples.mindmap.diagram.part.MindmapCreateSubtopicAction"<br />
definitionId="org.eclipse.gmf.examples.mindmap.insertSubtopic"<br />
enablesFor="1"<br />
id="org.eclipse.gmf.examples.mindmap.popup.MindmapCreateSubtopicActionID"<br />
label="&amp;Subtopic"<br />
menubarPath="MindmapInsert/group1"><br />
</action><br />
</objectContribution> <br />
</extension><br />
</pre><br />
<br />
Now, for the fun part... to define the declared MindmapCreateSubtopicAction class. To begin, we know that similar functionality exists in the connection handles feature provided by the runtime (see image below).<br />
[[Image:connection_handle.png|frame|left]]<br />
<br style="clear:both;"/><br />
<br />
After some investigation, it seems the CreateViewAndOptionallyElementCommand class is the key to this functionality, so we will use this code as the inspiration for our action. I expect that if there is a better way, someone from the runtime team will make a recommendation (hint) :-). Rather than paste the code here, simply copy the MindmapCreateSubtopicAction class into your project from the solution (or retrieve from CVS). The basic concepts are outlined next.<br />
<br />
Our action will implement IObjectActionDelegate, with its run method performing the following:<br />
- create and initialize a <br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add a composite figure, utilize external images and figures, and create a custom action contained within a new extension plug-in.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_3&diff=4372Graphical Modeling Framework/Tutorial/Part 32006-04-28T16:17:40Z<p>Rgronback: /* Creating a Customization Plug-in */</p>
<hr />
<div>'''Note:''' This is still very much a work in progress...<br />
<br />
In this third part of the GMF Tutorial, we will explore some more advanced capabilities related to the tooling components, while also extending what's generated with customizations to the runtime. Specifically we will add a composite figure using the graphical definition, show how to leverage external figures, and how to use an extension plug-in to add a custom action to our diagram. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_3.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
== New Icons ==<br />
A quick way to get a new polished look for our mindmap diagram is by replacing the generated EMF icons we've seen so far with some that are more, well... distinctive ;) The easiest way to do this is to replace the GIF images found in our org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/ folder. <br />
<br />
In case you'd like to map another image file to a palette item, say in the case of our three Relationship tools, or for our Subtopic link which has no default icon, you can modify the children of your Creation Tool elements in the mindmap.gmftool model. For example, if you delete the 'Delete Image' entry below the 'Creation Tool Subtopic' element that represents the small icon and replace it with a 'Small Icon Bundle Image' and set its Path property to platform:/plugin/org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/Subtopic.gif, it will use this icon. Of course, you'll need to provide this file or use the one found in the solution to this tutorial section.<br />
<br />
Finally, take a look in the mindmap.genmodel for properties to set for the default wizard and diagram file icons. While you're there, you might want to change the diagram file extension from 'mindmap_diagram' to 'mmd' or something similar. Browsing the properties available in the gmfgen model is a useful exercise.<br />
<br />
Below is an image of our diagram and palette using some new images.<br />
<br />
[[Image:new_icons.png]]<br />
<br style="clear:both;"/><br />
<br />
== Composite Figures ==<br />
[[Image:resource.png|frame|right]]<br />
What we'd like to do is have an actor-style representation for our resources added to our diagram. These will be linked to their respective Topic elements, much like our relationship links between Topic elements. Also, we'd like to have the labels for our Resource figures external and display both the name and email address attribute values of the corresponding domain element.<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:resource_figure.png|frame|right]]<br />
Open up your graphical definition again and add a new Rectangle named 'ResourceFigure' to your Figure Gallery. Set its Outline property to false, along with its Fill. As you can see from the image to the right, we will be adding a series of children to the rectangle, which will act as a container for the elements that comprise our Resource figure. Specifically, right-click and add an XY Layout, and Ellipse for the head, a Polygon for the Body, and sizing elements. Rather than go through all of the gory details of these, the figure code is found below. Either paste it into your mindmap.gmfgraph in the appropriate location using a text editor, or utilize the default editor and properties view.<br />
<br />
To our Canvas, add a new Node named ResourceNode and assign our ResourceFigure as its Figure. Also, notice the new 'BasicLabelFigure' label that is added to the Figure Gallery in the image. Create this and add a new Diagram Label 'ResourceLabel' to the Figure Gallery and Canvas respectively. Note that the Label for our Resource is not a child element of its figure. We want the label to be external, and therefore be allowed to float and be positioned wherever the user would like it.<br />
<br style="clear:both;"/><br />
<br />
<pre><br />
<figures xsi:type="gmfgraph:Rectangle" name="ResourceFigure" outline="false" fill="false" lineWidth="0"><br />
<layout xsi:type="gmfgraph:XYLayout"/><br />
<children xsi:type="gmfgraph:Ellipse" name="Head"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<size x="40" y="20"/><br />
</children><br />
<children xsi:type="gmfgraph:Polygon" name="Body"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<template x="23" y="19"/><br />
<template x="23" y="24"/><br />
<template x="39" y="24"/><br />
<template x="39" y="29"/><br />
<template x="23" y="29"/><br />
<template x="23" y="36"/><br />
<template x="39" y="48"/><br />
<template x="39" y="53"/><br />
<template x="20" y="42"/><br />
<template x="1" y="53"/><br />
<template x="1" y="48"/><br />
<template x="17" y="36"/><br />
<template x="17" y="29"/><br />
<template x="1" y="29"/><br />
<template x="1" y="24"/><br />
<template x="17" y="24"/><br />
<template x="17" y="19"/><br />
</children><br />
<maximumSize dx="40" dy="60"/><br />
<minimumSize dx="40" dy="60"/><br />
<preferredSize dx="40" dy="60"/><br />
<size x="40" y="60"/><br />
</figures><br />
</pre><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> It's a bit tedious to add multiple template points in the manner above, so feel free to open the gmfgraph file in a text editor to make life easier. Furthermore, to get it looking right more quickly, open the generated figure class and simply modify the GEF code directly and run the editor to see how it looks. Then, move this information back into your gmfgraph model. Of course, when the WYSIWYG features of GMF become available and mature, none of this should be necessary.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:resource_tool.png|frame|right]]<br />
We'll need a tool to add Resource nodes, so as you've done many times before, open the mindmap.gmftool model and add a new node creation tool for the Resource. Next, we'll need to add our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:resource_map.png|frame|right]]<br />
First, we'll need to add a new Top Node Reference to our Mapping definition. Set the Containment Feature to our 'EReference resources' attribute of our Map class. Add a child Node Mapping element to this Top Node Reference and select our 'EClass Resource' for the Domain meta information Element property. Of course, we'll select our ResourceNode for the Diagram Node and our Resource creation tool for the palette.<br />
<br />
Now, to add our Label Mapping as a child of the Node Mapping and set the Edit and View Pattern and corresponding features from our Resource class in the domain model. Here, we'll utilize the edit and view pattern properties of the mapping model to allow a Resource label to be displayed as 'name [email@some.com]'. To allow for the proper parsing of what's entered into the direct edit field, we will define an edit pattern for the label as '{0} : {1}' where a colon is used to separate the name and email attributes. Note that the generated plug-in code will contribute to the parserProvider extension-point, which will in turn leverages the Java MessageFormat class.<br />
<br />
=== Generation ===<br />
You will need to make one tweak to the generated code after you transform your mapping model to a new gmfgen model, as before. Open the newly-generated ResourceEditPart class and locate the createNodeShape() method. In this method, you will find a call to figure.setUseLocalCoordinates(false). In order for our polygon to appear in the rendered figure, you will need to set the argument to true. This should be a temporary workaround, and if you're not making changes to the figure, go ahead and add a NOT after @generated in the method comment. <br />
<br />
Run the diagram and check the operation of the label, as well as the look of the figure. It should look similar to the one above. Resources added to the diagram are now available in the properties view for topic assignments, thread authoring, etc. To add the possibility to create links from other elements to a Resource, follow steps similar to how links are used to represent subtopics.<br />
<br />
== Using External Figures ==<br />
<br />
== Creating a Customization Plug-in ==<br />
<br />
Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in. For this purpose, create a new plug-in project named org.eclipse.gmf.examples.mindmap.diagram.custom to your workspace.<br />
<br />
== Custom Actions ==<br />
[[Image:insert_subtopic.png|frame|right]]<br />
The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic. Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or some combination) and have the new Topic created, including the link, and with the in-place editor active on the new Topic. In this section, we will explore how to accomplish just this.<br />
<br />
To begin, we know that the org.eclipse.ui.bindings can be used to assign a Ctrl+I key combination to our action (as seen on the image, though for OS X). This is easily accomplished by contributing to the extension-point in our new *.diagram.custom plugin.xml file. Note that this is a simplistic example that does not declare a context, as you would probably expect to create for your diagram and potentially extend a default GMF diagram context (if one existed ;-).<br />
<br />
<pre><br />
<extension point="org.eclipse.ui.bindings"><br />
<key commandId="org.eclipse.gmf.examples.mindmap.insertSubtopic" sequence="M1+I" schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/><br />
</extension><br />
</pre><br />
<br />
Now, for the command, we'll contribute to the org.eclipse.ui.commands extension-point, as seen below. When you run your diagram, you will see this command category and the shortcut listed in the General | Keys preference page.<br />
<br />
<pre><br />
<extension point="org.eclipse.ui.commands"><br />
<category name="Mindmap" description="Commands related to Mindmap diagrams." id="org.eclipse.gmf.category.mindmap"/><br />
<command categoryId="org.eclipse.gmf.category.mindmap" description="Inserts a new subtopic" id="org.eclipse.gmf.examples.mindmap.insertSubtopic" name="Insert Subtopic"><br />
</command><br />
</extension><br />
</pre><br />
<br />
Now, for the popup menu. We'd like to have a series of potential menu items to insert elements on our diagram (i.e. subtopics, threads, etc.), so our contribution to org.eclipse.ui.popupMenus will define an 'Insert | Subtopic' menu and link it to our binding above through the defintionId:<br />
<br />
<pre><br />
<extension point="org.eclipse.ui.popupMenus"><br />
<objectContribution<br />
adaptable="false"<br />
id="org.eclipse.gmf.examples.mindmap.diagram.ui.objectContribution.TopicEditPart1"<br />
objectClass="org.eclipse.gmf.examples.mindmap.diagram.edit.parts.TopicEditPart"><br />
<menu <br />
id="MindmapInsert" <br />
label="&amp;Insert" <br />
path="additions"> <br />
<separator name="group1"/><br />
</menu><br />
<action<br />
class="org.eclipse.gmf.examples.mindmap.diagram.part.MindmapCreateSubtopicAction"<br />
definitionId="org.eclipse.gmf.examples.mindmap.insertSubtopic"<br />
enablesFor="1"<br />
id="org.eclipse.gmf.examples.mindmap.popup.MindmapCreateSubtopicActionID"<br />
label="&amp;Subtopic"<br />
menubarPath="MindmapInsert/group1"><br />
</action><br />
</objectContribution> <br />
</extension><br />
</pre><br />
<br />
Now, for the fun part... to define the declared MindmapCreateSubtopicAction class. To begin, we know that similar functionality exists in the connection handles feature provided by the runtime (see image below).<br />
[[Image:connection_handle.png|frame|left]]<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add a composite figure, utilize external images and figures, and create a custom action contained within a new extension plug-in.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_3&diff=4371Graphical Modeling Framework/Tutorial/Part 32006-04-28T16:12:58Z<p>Rgronback: /* Custom Actions */</p>
<hr />
<div>'''Note:''' This is still very much a work in progress...<br />
<br />
In this third part of the GMF Tutorial, we will explore some more advanced capabilities related to the tooling components, while also extending what's generated with customizations to the runtime. Specifically we will add a composite figure using the graphical definition, show how to leverage external figures, and how to use an extension plug-in to add a custom action to our diagram. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_3.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
== New Icons ==<br />
A quick way to get a new polished look for our mindmap diagram is by replacing the generated EMF icons we've seen so far with some that are more, well... distinctive ;) The easiest way to do this is to replace the GIF images found in our org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/ folder. <br />
<br />
In case you'd like to map another image file to a palette item, say in the case of our three Relationship tools, or for our Subtopic link which has no default icon, you can modify the children of your Creation Tool elements in the mindmap.gmftool model. For example, if you delete the 'Delete Image' entry below the 'Creation Tool Subtopic' element that represents the small icon and replace it with a 'Small Icon Bundle Image' and set its Path property to platform:/plugin/org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/Subtopic.gif, it will use this icon. Of course, you'll need to provide this file or use the one found in the solution to this tutorial section.<br />
<br />
Finally, take a look in the mindmap.genmodel for properties to set for the default wizard and diagram file icons. While you're there, you might want to change the diagram file extension from 'mindmap_diagram' to 'mmd' or something similar. Browsing the properties available in the gmfgen model is a useful exercise.<br />
<br />
Below is an image of our diagram and palette using some new images.<br />
<br />
[[Image:new_icons.png]]<br />
<br style="clear:both;"/><br />
<br />
== Composite Figures ==<br />
[[Image:resource.png|frame|right]]<br />
What we'd like to do is have an actor-style representation for our resources added to our diagram. These will be linked to their respective Topic elements, much like our relationship links between Topic elements. Also, we'd like to have the labels for our Resource figures external and display both the name and email address attribute values of the corresponding domain element.<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:resource_figure.png|frame|right]]<br />
Open up your graphical definition again and add a new Rectangle named 'ResourceFigure' to your Figure Gallery. Set its Outline property to false, along with its Fill. As you can see from the image to the right, we will be adding a series of children to the rectangle, which will act as a container for the elements that comprise our Resource figure. Specifically, right-click and add an XY Layout, and Ellipse for the head, a Polygon for the Body, and sizing elements. Rather than go through all of the gory details of these, the figure code is found below. Either paste it into your mindmap.gmfgraph in the appropriate location using a text editor, or utilize the default editor and properties view.<br />
<br />
To our Canvas, add a new Node named ResourceNode and assign our ResourceFigure as its Figure. Also, notice the new 'BasicLabelFigure' label that is added to the Figure Gallery in the image. Create this and add a new Diagram Label 'ResourceLabel' to the Figure Gallery and Canvas respectively. Note that the Label for our Resource is not a child element of its figure. We want the label to be external, and therefore be allowed to float and be positioned wherever the user would like it.<br />
<br style="clear:both;"/><br />
<br />
<pre><br />
<figures xsi:type="gmfgraph:Rectangle" name="ResourceFigure" outline="false" fill="false" lineWidth="0"><br />
<layout xsi:type="gmfgraph:XYLayout"/><br />
<children xsi:type="gmfgraph:Ellipse" name="Head"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<size x="40" y="20"/><br />
</children><br />
<children xsi:type="gmfgraph:Polygon" name="Body"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<template x="23" y="19"/><br />
<template x="23" y="24"/><br />
<template x="39" y="24"/><br />
<template x="39" y="29"/><br />
<template x="23" y="29"/><br />
<template x="23" y="36"/><br />
<template x="39" y="48"/><br />
<template x="39" y="53"/><br />
<template x="20" y="42"/><br />
<template x="1" y="53"/><br />
<template x="1" y="48"/><br />
<template x="17" y="36"/><br />
<template x="17" y="29"/><br />
<template x="1" y="29"/><br />
<template x="1" y="24"/><br />
<template x="17" y="24"/><br />
<template x="17" y="19"/><br />
</children><br />
<maximumSize dx="40" dy="60"/><br />
<minimumSize dx="40" dy="60"/><br />
<preferredSize dx="40" dy="60"/><br />
<size x="40" y="60"/><br />
</figures><br />
</pre><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> It's a bit tedious to add multiple template points in the manner above, so feel free to open the gmfgraph file in a text editor to make life easier. Furthermore, to get it looking right more quickly, open the generated figure class and simply modify the GEF code directly and run the editor to see how it looks. Then, move this information back into your gmfgraph model. Of course, when the WYSIWYG features of GMF become available and mature, none of this should be necessary.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:resource_tool.png|frame|right]]<br />
We'll need a tool to add Resource nodes, so as you've done many times before, open the mindmap.gmftool model and add a new node creation tool for the Resource. Next, we'll need to add our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:resource_map.png|frame|right]]<br />
First, we'll need to add a new Top Node Reference to our Mapping definition. Set the Containment Feature to our 'EReference resources' attribute of our Map class. Add a child Node Mapping element to this Top Node Reference and select our 'EClass Resource' for the Domain meta information Element property. Of course, we'll select our ResourceNode for the Diagram Node and our Resource creation tool for the palette.<br />
<br />
Now, to add our Label Mapping as a child of the Node Mapping and set the Edit and View Pattern and corresponding features from our Resource class in the domain model. Here, we'll utilize the edit and view pattern properties of the mapping model to allow a Resource label to be displayed as 'name [email@some.com]'. To allow for the proper parsing of what's entered into the direct edit field, we will define an edit pattern for the label as '{0} : {1}' where a colon is used to separate the name and email attributes. Note that the generated plug-in code will contribute to the parserProvider extension-point, which will in turn leverages the Java MessageFormat class.<br />
<br />
=== Generation ===<br />
You will need to make one tweak to the generated code after you transform your mapping model to a new gmfgen model, as before. Open the newly-generated ResourceEditPart class and locate the createNodeShape() method. In this method, you will find a call to figure.setUseLocalCoordinates(false). In order for our polygon to appear in the rendered figure, you will need to set the argument to true. This should be a temporary workaround, and if you're not making changes to the figure, go ahead and add a NOT after @generated in the method comment. <br />
<br />
Run the diagram and check the operation of the label, as well as the look of the figure. It should look similar to the one above. Resources added to the diagram are now available in the properties view for topic assignments, thread authoring, etc. To add the possibility to create links from other elements to a Resource, follow steps similar to how links are used to represent subtopics.<br />
<br />
== Using External Figures ==<br />
<br />
== Creating a Customization Plug-in ==<br />
<br />
Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in...<br />
<br />
== Custom Actions ==<br />
[[Image:insert_subtopic.png|frame|right]]<br />
The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic. Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or some combination) and have the new Topic created, including the link, and with the in-place editor active on the new Topic. In this section, we will explore how to accomplish just this.<br />
<br />
To begin, we know that the org.eclipse.ui.bindings can be used to assign a Ctrl+I key combination to our action (as seen on the image, though for OS X). This is easily accomplished by contributing to the extension-point in our new *.diagram.custom plugin.xml file. Note that this is a simplistic example that does not declare a context, as you would probably expect to create for your diagram and potentially extend a default GMF diagram context (if one existed ;-).<br />
<br />
<pre><br />
<extension point="org.eclipse.ui.bindings"><br />
<key commandId="org.eclipse.gmf.examples.mindmap.insertSubtopic" sequence="M1+I" schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/><br />
</extension><br />
</pre><br />
<br />
Now, for the command, we'll contribute to the org.eclipse.ui.commands extension-point, as seen below. When you run your diagram, you will see this command category and the shortcut listed in the General | Keys preference page.<br />
<br />
<pre><br />
<extension point="org.eclipse.ui.commands"><br />
<category name="Mindmap" description="Commands related to Mindmap diagrams." id="org.eclipse.gmf.category.mindmap"/><br />
<command categoryId="org.eclipse.gmf.category.mindmap" description="Inserts a new subtopic" id="org.eclipse.gmf.examples.mindmap.insertSubtopic" name="Insert Subtopic"><br />
</command><br />
</extension><br />
</pre><br />
<br />
Now, for the popup menu. We'd like to have a series of potential menu items to insert elements on our diagram (i.e. subtopics, threads, etc.), so our contribution to org.eclipse.ui.popupMenus will define an 'Insert | Subtopic' menu and link it to our binding above through the defintionId:<br />
<br />
<pre><br />
<extension point="org.eclipse.ui.popupMenus"><br />
<objectContribution<br />
adaptable="false"<br />
id="org.eclipse.gmf.examples.mindmap.diagram.ui.objectContribution.TopicEditPart1"<br />
objectClass="org.eclipse.gmf.examples.mindmap.diagram.edit.parts.TopicEditPart"><br />
<menu <br />
id="MindmapInsert" <br />
label="&amp;Insert" <br />
path="additions"> <br />
<separator name="group1"/><br />
</menu><br />
<action<br />
class="org.eclipse.gmf.examples.mindmap.diagram.part.MindmapCreateSubtopicAction"<br />
definitionId="org.eclipse.gmf.examples.mindmap.insertSubtopic"<br />
enablesFor="1"<br />
id="org.eclipse.gmf.examples.mindmap.popup.MindmapCreateSubtopicActionID"<br />
label="&amp;Subtopic"<br />
menubarPath="MindmapInsert/group1"><br />
</action><br />
</objectContribution> <br />
</extension><br />
</pre><br />
<br />
Now, for the fun part... to define the declared MindmapCreateSubtopicAction class. To begin, we know that similar functionality exists in the connection handles feature provided by the runtime (see image below).<br />
[[Image:connection_handle.png|frame|left]]<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add a composite figure, utilize external images and figures, and create a custom action contained within a new extension plug-in.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=File:Connection_handle.png&diff=4370File:Connection handle.png2006-04-28T16:11:38Z<p>Rgronback: </p>
<hr />
<div></div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_3&diff=4369Graphical Modeling Framework/Tutorial/Part 32006-04-28T15:06:35Z<p>Rgronback: /* Custom Actions */</p>
<hr />
<div>'''Note:''' This is still very much a work in progress...<br />
<br />
In this third part of the GMF Tutorial, we will explore some more advanced capabilities related to the tooling components, while also extending what's generated with customizations to the runtime. Specifically we will add a composite figure using the graphical definition, show how to leverage external figures, and how to use an extension plug-in to add a custom action to our diagram. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_3.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
== New Icons ==<br />
A quick way to get a new polished look for our mindmap diagram is by replacing the generated EMF icons we've seen so far with some that are more, well... distinctive ;) The easiest way to do this is to replace the GIF images found in our org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/ folder. <br />
<br />
In case you'd like to map another image file to a palette item, say in the case of our three Relationship tools, or for our Subtopic link which has no default icon, you can modify the children of your Creation Tool elements in the mindmap.gmftool model. For example, if you delete the 'Delete Image' entry below the 'Creation Tool Subtopic' element that represents the small icon and replace it with a 'Small Icon Bundle Image' and set its Path property to platform:/plugin/org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/Subtopic.gif, it will use this icon. Of course, you'll need to provide this file or use the one found in the solution to this tutorial section.<br />
<br />
Finally, take a look in the mindmap.genmodel for properties to set for the default wizard and diagram file icons. While you're there, you might want to change the diagram file extension from 'mindmap_diagram' to 'mmd' or something similar. Browsing the properties available in the gmfgen model is a useful exercise.<br />
<br />
Below is an image of our diagram and palette using some new images.<br />
<br />
[[Image:new_icons.png]]<br />
<br style="clear:both;"/><br />
<br />
== Composite Figures ==<br />
[[Image:resource.png|frame|right]]<br />
What we'd like to do is have an actor-style representation for our resources added to our diagram. These will be linked to their respective Topic elements, much like our relationship links between Topic elements. Also, we'd like to have the labels for our Resource figures external and display both the name and email address attribute values of the corresponding domain element.<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:resource_figure.png|frame|right]]<br />
Open up your graphical definition again and add a new Rectangle named 'ResourceFigure' to your Figure Gallery. Set its Outline property to false, along with its Fill. As you can see from the image to the right, we will be adding a series of children to the rectangle, which will act as a container for the elements that comprise our Resource figure. Specifically, right-click and add an XY Layout, and Ellipse for the head, a Polygon for the Body, and sizing elements. Rather than go through all of the gory details of these, the figure code is found below. Either paste it into your mindmap.gmfgraph in the appropriate location using a text editor, or utilize the default editor and properties view.<br />
<br />
To our Canvas, add a new Node named ResourceNode and assign our ResourceFigure as its Figure. Also, notice the new 'BasicLabelFigure' label that is added to the Figure Gallery in the image. Create this and add a new Diagram Label 'ResourceLabel' to the Figure Gallery and Canvas respectively. Note that the Label for our Resource is not a child element of its figure. We want the label to be external, and therefore be allowed to float and be positioned wherever the user would like it.<br />
<br style="clear:both;"/><br />
<br />
<pre><br />
<figures xsi:type="gmfgraph:Rectangle" name="ResourceFigure" outline="false" fill="false" lineWidth="0"><br />
<layout xsi:type="gmfgraph:XYLayout"/><br />
<children xsi:type="gmfgraph:Ellipse" name="Head"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<size x="40" y="20"/><br />
</children><br />
<children xsi:type="gmfgraph:Polygon" name="Body"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<template x="23" y="19"/><br />
<template x="23" y="24"/><br />
<template x="39" y="24"/><br />
<template x="39" y="29"/><br />
<template x="23" y="29"/><br />
<template x="23" y="36"/><br />
<template x="39" y="48"/><br />
<template x="39" y="53"/><br />
<template x="20" y="42"/><br />
<template x="1" y="53"/><br />
<template x="1" y="48"/><br />
<template x="17" y="36"/><br />
<template x="17" y="29"/><br />
<template x="1" y="29"/><br />
<template x="1" y="24"/><br />
<template x="17" y="24"/><br />
<template x="17" y="19"/><br />
</children><br />
<maximumSize dx="40" dy="60"/><br />
<minimumSize dx="40" dy="60"/><br />
<preferredSize dx="40" dy="60"/><br />
<size x="40" y="60"/><br />
</figures><br />
</pre><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> It's a bit tedious to add multiple template points in the manner above, so feel free to open the gmfgraph file in a text editor to make life easier. Furthermore, to get it looking right more quickly, open the generated figure class and simply modify the GEF code directly and run the editor to see how it looks. Then, move this information back into your gmfgraph model. Of course, when the WYSIWYG features of GMF become available and mature, none of this should be necessary.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:resource_tool.png|frame|right]]<br />
We'll need a tool to add Resource nodes, so as you've done many times before, open the mindmap.gmftool model and add a new node creation tool for the Resource. Next, we'll need to add our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:resource_map.png|frame|right]]<br />
First, we'll need to add a new Top Node Reference to our Mapping definition. Set the Containment Feature to our 'EReference resources' attribute of our Map class. Add a child Node Mapping element to this Top Node Reference and select our 'EClass Resource' for the Domain meta information Element property. Of course, we'll select our ResourceNode for the Diagram Node and our Resource creation tool for the palette.<br />
<br />
Now, to add our Label Mapping as a child of the Node Mapping and set the Edit and View Pattern and corresponding features from our Resource class in the domain model. Here, we'll utilize the edit and view pattern properties of the mapping model to allow a Resource label to be displayed as 'name [email@some.com]'. To allow for the proper parsing of what's entered into the direct edit field, we will define an edit pattern for the label as '{0} : {1}' where a colon is used to separate the name and email attributes. Note that the generated plug-in code will contribute to the parserProvider extension-point, which will in turn leverages the Java MessageFormat class.<br />
<br />
=== Generation ===<br />
You will need to make one tweak to the generated code after you transform your mapping model to a new gmfgen model, as before. Open the newly-generated ResourceEditPart class and locate the createNodeShape() method. In this method, you will find a call to figure.setUseLocalCoordinates(false). In order for our polygon to appear in the rendered figure, you will need to set the argument to true. This should be a temporary workaround, and if you're not making changes to the figure, go ahead and add a NOT after @generated in the method comment. <br />
<br />
Run the diagram and check the operation of the label, as well as the look of the figure. It should look similar to the one above. Resources added to the diagram are now available in the properties view for topic assignments, thread authoring, etc. To add the possibility to create links from other elements to a Resource, follow steps similar to how links are used to represent subtopics.<br />
<br />
== Using External Figures ==<br />
<br />
== Creating a Customization Plug-in ==<br />
<br />
Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in...<br />
<br />
== Custom Actions ==<br />
[[Image:insert_subtopic.png|frame|right]]<br />
The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic. Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or equivalent) and have the new Topic created, including the link, and with the in-place editor active on the new Topic. In this section, we will explore how to accomplish just this.<br />
<br />
<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add a composite figure, utilize external images and figures, and create a custom action contained within a new extension plug-in.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=File:Insert_subtopic.png&diff=4368File:Insert subtopic.png2006-04-28T15:05:57Z<p>Rgronback: </p>
<hr />
<div></div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_3&diff=4367Graphical Modeling Framework/Tutorial/Part 32006-04-28T15:05:44Z<p>Rgronback: /* Custom Actions */</p>
<hr />
<div>'''Note:''' This is still very much a work in progress...<br />
<br />
In this third part of the GMF Tutorial, we will explore some more advanced capabilities related to the tooling components, while also extending what's generated with customizations to the runtime. Specifically we will add a composite figure using the graphical definition, show how to leverage external figures, and how to use an extension plug-in to add a custom action to our diagram. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_3.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
== New Icons ==<br />
A quick way to get a new polished look for our mindmap diagram is by replacing the generated EMF icons we've seen so far with some that are more, well... distinctive ;) The easiest way to do this is to replace the GIF images found in our org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/ folder. <br />
<br />
In case you'd like to map another image file to a palette item, say in the case of our three Relationship tools, or for our Subtopic link which has no default icon, you can modify the children of your Creation Tool elements in the mindmap.gmftool model. For example, if you delete the 'Delete Image' entry below the 'Creation Tool Subtopic' element that represents the small icon and replace it with a 'Small Icon Bundle Image' and set its Path property to platform:/plugin/org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/Subtopic.gif, it will use this icon. Of course, you'll need to provide this file or use the one found in the solution to this tutorial section.<br />
<br />
Finally, take a look in the mindmap.genmodel for properties to set for the default wizard and diagram file icons. While you're there, you might want to change the diagram file extension from 'mindmap_diagram' to 'mmd' or something similar. Browsing the properties available in the gmfgen model is a useful exercise.<br />
<br />
Below is an image of our diagram and palette using some new images.<br />
<br />
[[Image:new_icons.png]]<br />
<br style="clear:both;"/><br />
<br />
== Composite Figures ==<br />
[[Image:resource.png|frame|right]]<br />
What we'd like to do is have an actor-style representation for our resources added to our diagram. These will be linked to their respective Topic elements, much like our relationship links between Topic elements. Also, we'd like to have the labels for our Resource figures external and display both the name and email address attribute values of the corresponding domain element.<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:resource_figure.png|frame|right]]<br />
Open up your graphical definition again and add a new Rectangle named 'ResourceFigure' to your Figure Gallery. Set its Outline property to false, along with its Fill. As you can see from the image to the right, we will be adding a series of children to the rectangle, which will act as a container for the elements that comprise our Resource figure. Specifically, right-click and add an XY Layout, and Ellipse for the head, a Polygon for the Body, and sizing elements. Rather than go through all of the gory details of these, the figure code is found below. Either paste it into your mindmap.gmfgraph in the appropriate location using a text editor, or utilize the default editor and properties view.<br />
<br />
To our Canvas, add a new Node named ResourceNode and assign our ResourceFigure as its Figure. Also, notice the new 'BasicLabelFigure' label that is added to the Figure Gallery in the image. Create this and add a new Diagram Label 'ResourceLabel' to the Figure Gallery and Canvas respectively. Note that the Label for our Resource is not a child element of its figure. We want the label to be external, and therefore be allowed to float and be positioned wherever the user would like it.<br />
<br style="clear:both;"/><br />
<br />
<pre><br />
<figures xsi:type="gmfgraph:Rectangle" name="ResourceFigure" outline="false" fill="false" lineWidth="0"><br />
<layout xsi:type="gmfgraph:XYLayout"/><br />
<children xsi:type="gmfgraph:Ellipse" name="Head"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<size x="40" y="20"/><br />
</children><br />
<children xsi:type="gmfgraph:Polygon" name="Body"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<template x="23" y="19"/><br />
<template x="23" y="24"/><br />
<template x="39" y="24"/><br />
<template x="39" y="29"/><br />
<template x="23" y="29"/><br />
<template x="23" y="36"/><br />
<template x="39" y="48"/><br />
<template x="39" y="53"/><br />
<template x="20" y="42"/><br />
<template x="1" y="53"/><br />
<template x="1" y="48"/><br />
<template x="17" y="36"/><br />
<template x="17" y="29"/><br />
<template x="1" y="29"/><br />
<template x="1" y="24"/><br />
<template x="17" y="24"/><br />
<template x="17" y="19"/><br />
</children><br />
<maximumSize dx="40" dy="60"/><br />
<minimumSize dx="40" dy="60"/><br />
<preferredSize dx="40" dy="60"/><br />
<size x="40" y="60"/><br />
</figures><br />
</pre><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> It's a bit tedious to add multiple template points in the manner above, so feel free to open the gmfgraph file in a text editor to make life easier. Furthermore, to get it looking right more quickly, open the generated figure class and simply modify the GEF code directly and run the editor to see how it looks. Then, move this information back into your gmfgraph model. Of course, when the WYSIWYG features of GMF become available and mature, none of this should be necessary.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:resource_tool.png|frame|right]]<br />
We'll need a tool to add Resource nodes, so as you've done many times before, open the mindmap.gmftool model and add a new node creation tool for the Resource. Next, we'll need to add our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:resource_map.png|frame|right]]<br />
First, we'll need to add a new Top Node Reference to our Mapping definition. Set the Containment Feature to our 'EReference resources' attribute of our Map class. Add a child Node Mapping element to this Top Node Reference and select our 'EClass Resource' for the Domain meta information Element property. Of course, we'll select our ResourceNode for the Diagram Node and our Resource creation tool for the palette.<br />
<br />
Now, to add our Label Mapping as a child of the Node Mapping and set the Edit and View Pattern and corresponding features from our Resource class in the domain model. Here, we'll utilize the edit and view pattern properties of the mapping model to allow a Resource label to be displayed as 'name [email@some.com]'. To allow for the proper parsing of what's entered into the direct edit field, we will define an edit pattern for the label as '{0} : {1}' where a colon is used to separate the name and email attributes. Note that the generated plug-in code will contribute to the parserProvider extension-point, which will in turn leverages the Java MessageFormat class.<br />
<br />
=== Generation ===<br />
You will need to make one tweak to the generated code after you transform your mapping model to a new gmfgen model, as before. Open the newly-generated ResourceEditPart class and locate the createNodeShape() method. In this method, you will find a call to figure.setUseLocalCoordinates(false). In order for our polygon to appear in the rendered figure, you will need to set the argument to true. This should be a temporary workaround, and if you're not making changes to the figure, go ahead and add a NOT after @generated in the method comment. <br />
<br />
Run the diagram and check the operation of the label, as well as the look of the figure. It should look similar to the one above. Resources added to the diagram are now available in the properties view for topic assignments, thread authoring, etc. To add the possibility to create links from other elements to a Resource, follow steps similar to how links are used to represent subtopics.<br />
<br />
== Using External Figures ==<br />
<br />
== Creating a Customization Plug-in ==<br />
<br />
Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in...<br />
<br />
== Custom Actions ==<br />
<br />
The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic. Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or equivalent) and have the new Topic created, including the link, and with the in-place editor active on the new Topic. In this section, we will explore how to accomplish just this.<br />
<br />
[[Image:insert_subtopic.png|frame|right]]<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add a composite figure, utilize external images and figures, and create a custom action contained within a new extension plug-in.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Callisto_Plan_Summary&diff=4339Callisto Plan Summary2006-04-26T20:34:37Z<p>Rgronback: </p>
<hr />
<div>This is a temporaray working copy of what is proposed to be the summary table of the Callisto <br />
Plan as detailed in http://www.eclipse.org/projects/callisto.php<br />
<br />
<br />
<br />
=== RC1 (25-Apr) ===<br />
<br />
* 14-Apr - Platform (RC1a)<br />
* 19-Apr - CDT, DTP, EMF (RC1) , GEF (RC0), VE<br />
* 21-Apr - BIRT (RC0), GMF (RC0), TPTP (i2), WTP (RC1a)<br />
* 25-Apr - admin, mirror propagation<br />
<br />
=== RC2 (9-May)=== <br />
<br />
* 28-Apr - Platform (RC2)<br />
* 3-May - CDT (RC0), DTP, EMF (RC2) , GEF (RC2), VE<br />
* 5-May - BIRT, GMF (RC2), TPTP (i2), WTP (RC2)<br />
* 9-May - admin, mirror propagation<br />
<br />
=== RC3 (23-May)=== <br />
<br />
* 12-May - Platform (RC4)<br />
* 17-May - CDT (RC0), DTP, EMF (RC4), GEF (RC3), VE<br />
* 19-May - BIRT, GMF (RC3), TPTP (i2), WTP (RC3)<br />
* 23-May - admin, mirror propagation<br />
<br />
=== RC4 (2 -Jun)=== <br />
<br />
* 26-May - Platform (RCx, none planned)<br />
* 29-May - CDT (RC1), DTP, EMF, GEF (RC4), VE<br />
* 31-May - BIRT, GMF (RC4), TPTP (i3), WTP (RC4)<br />
* 2 -June - admin, mirror propagation<br />
<br />
=== RC5 (22-Jun)=== <br />
<br />
* 16-Jun - Platform (RCx, none planned)<br />
* 19-Jun - CDT (RC1) , DTP, EMF, GEF (RC5), VE<br />
* 20-Jun - BIRT, GMF (RC5), TPTP (RC5), WTP (RC5)<br />
* 22-Jun - admin, mirror propagation<br />
<br />
=== RC6 (30-Jun)=== <br />
<br />
* 28-Jun - Platform (RCx, none planned)<br />
* 28-Jun - CDT (RC2, if needed) , DTP, EMF, GEF (RC5), VE<br />
* 28-Jun - BIRT, GMF (RC6), TPTP (RC6), WTP (RC6)<br />
* 30-Jun - admin, mirror propagation<br />
<br />
=== Callisto Release 6/30 ===</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework&diff=3902Graphical Modeling Framework2006-04-14T11:45:12Z<p>Rgronback: </p>
<hr />
<div><table><br />
<tr><td>The Eclipse Graphical Modeling Framework ([http://www.eclipse.org/gmf GMF]) provides a generative component and runtime infrastructure for developing graphical editors based on [http://www.eclipse.org/emf EMF] and [http://www.eclipse.org/gef GEF].<br/><br/>While the main GMF [http://www.eclipse.org/gmf website] contains the bulk of information regarding the project, the type of information more appropriately hosted on a wiki is (or will be) found here, such as: FAQs, tutorials, requirements, discussions, etc.</td><td align='right'><br />
[[Image:gmf_logo_banner.png]]</td><br />
</tr></table><br />
<br/><br />
[[GMF Tutorial|GMF Tutorial Part 1]]<br />
<br />
[[GMF Tutorial Part 2|GMF Tutorial Part 2]]<br />
<br />
[[GMF Tutorial Part 3|GMF Tutorial Part 3]]<br />
<br />
[[Graphical Modeling Framework FAQ|Graphical Modeling Framework FAQs]]<br />
<br />
[[GMF Troubleshooting Guide|GMF Troubleshooting Guide]]</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_1&diff=3901Graphical Modeling Framework/Tutorial/Part 12006-04-14T01:19:38Z<p>Rgronback: </p>
<hr />
<div>This tutorial will introduce the Graphical Modeling Framework ([http://www.eclipse.org/gmf GMF]), an Eclipse Technology subproject which aims to provide a generative bridge between the Eclipse Modeling Framework ([http://www.eclipse.org/emf EMF]) and Graphical Editing Framework ([http://www.eclipse.org/gef GEF]). <br />
<br />
In this tutorial, a mindmap application will be developed, as described [http://www.eclipse.org/gmf/requirements.php#scenarios here]. This tutorial describes the functionality provided by GMF in its current state, using this build ([http://download.eclipse.org/technology/gmf/downloads/index.php 1.0M6]). It is expected that this tutorial will evolve with GMF to introduce new functionality as it is developed. New functionality will be covered by installments added to this tutorial, each with a corresponding viewlet. A viewlet for this installment of the tutorial can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial.html here].<br />
<br />
== Overview of GMF ==<br />
The use of both EMF and GEF for building Eclipse-based functionality is quite common. Many references below provide information on how to utilize these frameworks together, some of which inspired the GMF project itself. Before diving into a new GMF project, let's explore a little of how GMF approaches the task of utilizing EMF and GEF in a generative manner. Another article focusing on the runtime portion of GMF is found [http://www.eclipse.org/articles/Article-Introducing-GMF/article.html here].<br />
<br />
The GMF project has adopted the term 'toolsmith' to refer to developers that use GMF to build plug-ins, while 'user' is typically refered to those who utilize said plug-ins, and who may also be developers. From a usability perspective, the number and types of 'models' utilized by GMF internally should be hidden to the greatest extent possible. However, it is likely that most toolsmiths are interested in knowing what is going on under the covers, so a description of each model is presented in this tutorial.<br />
<br />
[[Image:overview.png|frame|right|GMF Overview]]<br />
<br />
This is a diagram that illustrates the main components and models used during GMF-based development. Core to GMF is the concept of a graphical definition model. This model contains information related to the graphical elements that will appear in a GEF-based runtime, but have no direct connection to the domain models for which they will provide representation and editing. An optional tooling definition model is used to design the palette and other periphery (overview, zoom, etc.).<br />
<br />
It is expected that a graphical or tooling definition may work equally well for several domains. For example, the UML class diagram has many counterparts, all of which are strikingly similar in their basic appearance and structure. A goal of GMF is to allow the graphical definition to be reused for several domains. This is achieved by using a separate mapping model to link the graphical and tooling definitions to the selected domain model(s).<br />
<br />
Once the appropriate mappings are defined, GMF provides a generator model to allow implementation details to be defined for the generation phase. The production of an editor plug-in based on the generator model will target a final model; that is, the diagram runtime (or "notation") model. The runtime will bridge the notation and domain model(s) when a user is working with a diagram, and also provides for the persistence and synchronization of both. An important aspect of this runtime is that it provides a services-based approach to EMF and GEF functionality and is able to be leveraged by non-generated applications.<br />
<br />
With the basics of GMF covered, let's now walk through the process of using GMF in the development of a graphical editing surface for a particular domain. First, you will need to install GMF and its dependencies.<br />
<br style="clear:both;"/><br />
<br />
== Setup ==<br />
This version of the tutorial was written using this build of GMF ([http://download.eclipse.org/technology/gmf/downloads/index.php 1.0M6]). Note that the prerequisites are listed on the build page, which must be installed prior to installing GMF, either from the [http://download.eclipse.org/technology/gmf/downloads download] page, or from the update manager [http://download.eclipse.org/technology/gmf/update-site/index.html site]. The TaiPan example referenced below is maintained in CVS and should remain functional with the latest builds of GMF, even if the tutorial is not quite up-to-date.<br />
<br />
==== Quick Start ====<br />
[[Image:checkout.png|right]]<br />
If you're anxious to see GMF in action, check out the Taipan example projects into your workspace from CVS by switching to the CVS Repository Exploring perspective and adding a repository location as shown in the image to the right. Otherwise, you can skip to the next section.<br />
<br />
Navigate to /HEAD/org.eclipse.gmf/examples and select the three org.eclipse.gmf.examples.taipan.* modules. Right-click and select Check Out. If you are not using the latest build and prerequisites of GMF, you can always check out the version of the Taipan by date to correspond with the version you're using. The important point is that you'll need to work with synchronized versions of the GMF SDK and the Taipan example. To do this, after checkout you can right-click on the projects and selecting 'Team | Switch to Another Branch or Version...' and then choose 'Select the tag from the following list' and use the 'Add Date...' button at the bottom to enter the date of the GMF 1.0M6 release (14 Apr 2006). Press Finish and you're set.<br />
<br />
Switch to the Plug-in Development perspective and open the models folder within the org.eclipse.gmf.examples.taipan project. Explore each of the models found here, particularly the taipan.gmfgraph and taipan.gmfmap models and their element properties.<br />
<br />
We will look at each of the models in turn during the tutorial, but just to validate your configuration, you should be able to run this sample in a runtime workspace (simply accept the defaults for a new 'Eclipse Application' run configuration). In the runtime workspace, create an empty project and a new 'TaiPan Diagram' found in the Examples folder of the New dialog. Name it whatever you wish and click Finish. The generated diagram editor should open for you to explore. Some things to note in particular are:<br />
<br />
:* tool palette and overview<br />
:* layout and selection tools<br />
:* diagram image export (svg, bmp, jpeg, gif)<br />
:* tabbed properties view<br />
:* font and color options for selected element<br />
:* link routing and style options<br />
:* pop-up bars and connection handles<br />
:* notes and geometric shapes<br />
:* animated zoom and layout<br />
:* diagram printing<br />
<br />
[[Image:taipan_diagram.png|center]]<br />
<br />
This concludes the quick start portion of this tutorial. What follows next is a more detailed look at each of the models shown above during the creation of a mindmap modeling surface.<br />
<br />
==== A New Project ====<br />
<br />
Before we start, you should specify for your workspace (or at least for your GMF projects) 1.4 compiler settings. In Window... Preferences... Java...Compiler options, make sure you have selected a Compliance Level of 1.4, including options for generated .class and source file compatibility. GMF itself is developed using these settings, although technically nothing prevents you from using Java 5 in your workspace, provided your runtime launch configuration also uses Java 5.<br />
<br />
As described [http://www.eclipse.org/gmf/requirements.php#scenarios here], one of the usage scenarios for GMF includes producing a graphical surface for a mindmap application, to be complemented with an alternative view of its temporal information (likely a Gantt chart). This section of the tutorial will demonstrate GMF's capabilities toward this end, and will continue to evolve as the project matures. If you'd prefer to follow along using a set of projects representing the complete solution to this tutorial, you can find a zip of them [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_1.zip here].<br />
<br />
[[Image:cheatsheet_project.png|right]]<br />
<br />
New to GMF is a Tutorial Cheat Sheet found under 'Help | Cheat Sheets...' If you open this cheat sheet and follow through each step, you can accomplish most of this first tutorial segment, while taking advantage of some actions that will launch and pre-populate wizards to get you started. Try this now to create your new project.<br />
<br />
Alternatively, you can begin by creating an "New GMF Project" found under 'Graphical Modeling Framework' in the New dialog (Ctrl+N). Name the project 'org.eclipse.gmf.examples.mindmap' and create a new folder named 'model' in its root.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Domain Model Definition ==<br />
<br />
Although it may seem necessary to begin with the domain model, it is not in the case with GMF, as the diagram definition is maintained separate from the domain. However, we will begin with the domain in the tutorial as it is likely familiar to most, and will allow us to jumpstart our diagram definition from the domain model using a wizard in the next section.<br />
<br />
A basic domain model for our mindmap is found [http://www.eclipse.org/gmf/tutorial/mindmap.ecore here]. Copy this file into your 'model' folder and feel free to examine the model, if you wish. GMF provides a (bootstrapped) graphical editor to complement the standard EMF generated editors. In order to use the GMF Ecore editor, you will need to install the GMF Examples feature. To render the mindmap.ecore (or any *.ecore model) with the editor, simply right-click the file and select 'Initialize ecore_diagram diagram file' from the menu. The next step is to layout the diagram using the 'Arrange All' action.<br />
<br />
[[Image:domain.png|frame|center|Mindmap domain model]]<br />
<br />
To continue, create a new mindmap.genmodel from the mindmap.ecore file using the New > Eclipse Modeling Framework > EMF Model wizard. You may wish to change the 'Base Package' property for the genmodel's 'Mindmap' package to org.eclipse.gmf.examples to have your generated packaging match the project name. These steps are also covered in the next step of the cheat sheet.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be sure to give your genmodel file the same name as your domain model (i.e. both mindmap.*), as GMF currently expects this naming convention to identify the genmodel for the mapped domain model.<br />
</blockquote><br />
<br />
Generate the model and edit code using the right-click menu available from the root of the generator model. There is no need to create an editor or tests, but you are welcome to do so if you'd like. Now, we're ready to begin creating the graphical and mapping definitions for our mindmap application.<br />
<br />
== Graphical Definition ==<br />
[[Image:graphical-thumbnail.png|frame|right|thumbnail|Graphical Definition Model, view in [[Media:graphical.png|actual size]].]]<br />
A graphical definition model is used to define the figures, nodes, links, etc. that you will display on your diagram. The model you will work with to do this is seen at the right.<br />
<br />
Continuing on with the next step in the cheat sheet, we will create a new graphical definition model. The cheat sheet will launch the GMFGraph Model wizard, which is found in the Graphical Modeling Framework folder of the New (Ctrl + N) dialog. Select the 'model' folder under your org.eclipse.gmf.examples.mindmap project for the mindmap.gmfgraph model, and on the next page of the wizard use 'Browse' to locate your mindmap.ecore file.<br />
<br />
On the last page of the wizard, select a minimal set of element, link, and label options for our Topic class as shown in the image. Later on, feel free to experiment with this wizard and observe its output. For now, we're just interested in getting a minimal set of models to get started. Click 'Finish' to complete.<br />
<br />
If you examine the model, you will find a Canvas at the root with a Figure gallery containing basic Rectangle, Label, and Polyline Connection elements. These are used by corresponding Node, Diagram Label, and Connection elements to represent our Topics from the domain model. We can leave the defaults as-is for now and continue with our tooling definition in the next step of the cheat sheet.<br />
<br />
[[Image:cheatsheet_graph.png]]<br />
<br style="clear:both;"/><br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are several figure galleries intended for reuse and included with GMF. You can load these into your *.gmfgraph model (or *.gmfmap model) by using "Load Resource..." and entering <code>platform:/plugin/org.eclipse.gmf.graphdef/models/basic.gmfgraph</code> for the Resource URI. Others available include <code>classDiagram.gmfgraph</code> and <code>stateDiagram.gmfgraph</code>.<br />
</blockquote><br />
<br />
== Tooling Definition ==<br />
[[Image:tooling-thumbnail.png|frame|right|thumbnail|Tooling Definition Model, view in [[Media:tooling.png|actual size]].]]<br />
As mentioned above, the tooling definition model is used to specify the palette, creation tools, actions, etc. for your graphical elements. To the right is a diagram of the model.<br />
<br />
The cheat sheet will guide you through a very similar process for getting started with our Tooling definition model. In fact, the two steps are virtually identical, as the mindmap domain model is loaded and examined for possible tooling needs. We will simply select the same options we did for the graphical definition, save a tool for the Topic name label, and begin with a very simple palette for our Topic elements.<br />
<br style="clear:both;"/><br />
[[Image:cheatsheet_tool.png]]<br />
<br style="clear:both;"/><br />
<br />
Looking at the model provided for us, we see there is a top-level 'Tool Registry' element, under which we find a Palette. The palette contains a Tool Group with Creation Tool elements for both Topic nodes and links for subtopic elements that were identified by the wizard. We will reorganize these and modify them a bit in the future, but for now we'll leave the defaults and move on to the mapping definition. Feel free to browse this model and inspect its properties to familiarize yourself with tooling definitions.<br />
<br />
== Mapping Definition ==<br />
[[Image:mapping-thumbnail.png|frame|right|thumbnail|Mapping Definition Model, view in [[Media:mapping.png|actual size]].]]<br />
<br />
The mapping definition model will let us bind the three models we have so far: the domain, the graphical definition, and the tooling definition. To the right is an image of this model. This is a key model to GMF development and will be used as input to a transformation step which will produce our final model, the generation model.<br />
<br />
Continuing on with our cheat sheet, follow the instructions to launch the GMFMap Model wizard. We will again select the 'model' folder to hold our mindmap.gmfmap file and move on to load each of the preselected mindmap.ecore, mindmap.gmfgraph, and mindmap.gmftool models. On the next page, select 'Map' as the Diagram Root Element and finally, make the last page look like the image below.<br />
<br />
[[Image:cheatsheet_map.png]]<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:label_mapping.png|right]]<br />
One thing we need to do manually is set the Diagram Label property of our Label Mapping to our TopicNameLabel from the graphical definition (yes, this is a temporary feature of the mapping wizard ;). The result should look like the image to the right.<br />
<br />
Before moving on, let's pause to describe the mappings. We'll start with the Label Mapping, as it's the one we're looking at here. It's a straightforward mapping, with the Diagram Label property set as we discussed and a mapping to the 'EAttribute name' feature on our Topic element in the domain model.<br />
<br />
Moving up to the Node Mapping, we see that our Diagram Node is mapped to the TopicNode of our graphical definition with its corresponding domain model element mapped to our Topic class. The Topic creation tool is also specified in the mapping.<br />
<br />
Above the Node Mapping you will find a Top Node Reference. Its Containment Feature is set to the 'EReference rootTopics' feature of our Map class. So, when new Topic nodes are added to the diagram, the instance of our domain Topic will be added to the rootTopics containment reference of our Map class. The label of the node will display the 'name' attribute of the Topic.<br />
<br />
The Map class itself is represented by the Canvas. Select the Canvas Mapping element to see this defined, along with the map to the Palette in our tooling definition. Finally, if you select the Link Mapping, you will observe that connections represented by our TopicSubtopicsLink are mapped to the 'EReference subtopics' feature of our Topic class, and are created with our TopicSubtopics Creation Tool.<br />
<br style="clear:both;"/><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Note that it is important to select the proper element when defining mappings at this stage; that is, before GMF does more complete filtering and validation. A good way to ensure you have selected the element you intended (as several may have the same name), open the mapping definition (*.gmfmap) file in a text editor.<br />
</blockquote><br />
<br />
== Code Generation ==<br />
[[Image:generation-thumbnail.png|frame|right|thumbnail|Generation Model, view in [[Media:generation.png|actual size]].]]<br />
The last model to cover in this tutorial, and the one that is not as critical to understand at this point, is the GMF generator model. See the diagram to the right if you're interested in examining this model.<br />
<br />
Now that the minimal graphical elements and mappings are defined, we can generate the code needed to test our work so far. To accomplish this, we will first create a generator model (*.gmfgen) in order to set the properties for code generation, similar to the familiar EMF genmodel. To accomplish this, right-click the mapping file and select 'Create generator model...' as shown below. When prompted, keep the default name 'mindmap.gmfgen'.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> You'll need to have your Java | Compiler | JDK Compliance settings to 1.4 (including Generated .class files compatibility and Source compatibility) when working with GMF.<br />
</blockquote><br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:create_gmfgen.png|right]]<br />
<br />
Now, we can examine the generator model to see what it includes (if you're the curious type). We'll keep all the default values for now and right-click the mindmap.gmfgen file and select 'Generate diagram code' to proceed. If all goes well, you will see a "Code generation completed successfully." message dialog. Dismiss the dialog, opting to never see it again, and notice the new org.eclipse.gmf.examples.mindmap.diagram plug-in in your workspace.<br />
<br />
Up to this point, the models used have been fairly straightforward to edit and understand. The transformation that takes place to create the generator model (*.gmfgen) from the mapping model involves a bit of logic that is important to understand. However, it is not required to understand the details at this point in the tutorial, so additional information can be found [[GMF_GenModel|here]] for those interested.<br />
<br style="clear:both;"/><br />
<br />
== Running the Diagram ==<br />
[[Image:notation-thumbnail.png|frame|right|thumbnail|Notation Model, view in [[Media:notation.png|actual size]].]]<br />
Recall that the runtime uses its own 'notation model' to display and persist the graphical components for your diagram. An image of this model is linked here for those interested.<br />
<br />
Now that we have generated the plug-in needed for our diagram, let's launch a new runtime workspace and test the diagram. The default settings of a new Eclipse Application runtime configuration should work fine, while you may opt to run a minimal configuration that includes only your generated plug-ins and their runtime dependencies within an org.eclipse.platform.ide configuration.<br />
<br />
Create an empty project and invoke the New... dialog (Ctrl+N). Under 'Examples' you'll notice your new Mindmap Diagram. Create a new diagram and explore its functionality, and look for the creation of the domain model instance as you add and save diagram elements. Of course, we've only specified enough in our diagram definition to allow for simple Topic elements and subtopic links. <br />
<br />
[[Image:basic_mindmap.png|center]]<br />
<br />
== Summary ==<br />
As you have seen, using GMF as a means by which to get started creating graphical editors for your domain models is fairly straightforward. We have seen how creating a graphical definition and a mapping definition to the chosen domain can be used to generate much of the basic functionality expected in an EMF/GEF-based editor. In the future, GMF will mature and include more advance capabilities, so check back to see how this tutorial matures along with the project. In the meantime, if you've skipped over links that provide more detail on certain aspects of GMF, now may be the time to do so. Otherwise, feel free to continue with the [[GMF_Tutorial_Part_2|GMF Tutorial Part 2]].<br />
<br />
== References ==<br />
* [http://www.eclipse.org/gmf Graphical Modeling Framework Website]<br />
<br />
* [http://publib-b.boulder.ibm.com/Redbooks.nsf/RedbookAbstracts/sg246302.html Eclipse Development using the Graphical Editing Framework and the Eclipse Modeling Framework], IBM Redbook<br />
<br />
* [http://www.eclipse.org/emf/docs.php EMF Documentation]<br />
<br />
* [http://eclipse.org/emf/docs.php?doc=tutorials/clibmod/clibmod.html Generating an EMF Model]<br />
<br />
* [http://sourceforge.net/projects/merlingenerator/ Merlin Homepage]<br />
<br />
* [http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.gef.examples.ediagram/?cvsroot=Tools_Project EDiagram Example Source]<br />
<br />
* [http://www.eclipse.org/articles/Article-GEF-EMF/gef-emf.html Using GEF with EMF], Eclipse Corner Article<br />
<br />
* [http://www.eclipse.org/emft EMF Technology project]<br />
<br />
* [http://www.omg.org/docs/ptc/03-10-14.pdf OCL Specification]</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework&diff=3896Graphical Modeling Framework2006-04-13T16:19:55Z<p>Rgronback: </p>
<hr />
<div><table><br />
<tr><td>The Eclipse Graphical Modeling Framework ([http://www.eclipse.org/gmf GMF]) provides a generative component and runtime infrastructure for developing graphical editors based on [http://www.eclipse.org/emf EMF] and [http://www.eclipse.org/gef GEF].<br/><br/>While the main GMF [http://www.eclipse.org/gmf website] contains the bulk of information regarding the project, the type of information more appropriately hosted on a wiki is (or will be) found here, such as: FAQs, tutorials, requirements, discussions, etc.</td><td align='right'><br />
[[Image:gmf_logo_banner.png]]</td><br />
</tr></table><br />
<br/><br />
[[GMF Tutorial|GMF Tutorial]]<br />
<br />
[[GMF Tutorial Part 2|GMF Tutorial Part 2]]<br />
<br />
[[GMF Tutorial Part 3|GMF Tutorial Part 3]]<br />
<br />
[[Graphical Modeling Framework FAQ|Graphical Modeling Framework FAQs]]<br />
<br />
[[GMF Troubleshooting Guide|GMF Troubleshooting Guide]]</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_3&diff=3866Graphical Modeling Framework/Tutorial/Part 32006-04-12T23:01:50Z<p>Rgronback: /* Generation */</p>
<hr />
<div>'''Note:''' This is still very much a work in progress...<br />
<br />
In this third part of the GMF Tutorial, we will explore some more advanced capabilities related to the tooling components, while also extending what's generated with customizations to the runtime. Specifically we will add a composite figure using the graphical definition, show how to leverage external figures, and how to use an extension plug-in to add a custom action to our diagram. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_3.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
== New Icons ==<br />
A quick way to get a new polished look for our mindmap diagram is by replacing the generated EMF icons we've seen so far with some that are more, well... distinctive ;) The easiest way to do this is to replace the GIF images found in our org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/ folder. <br />
<br />
In case you'd like to map another image file to a palette item, say in the case of our three Relationship tools, or for our Subtopic link which has no default icon, you can modify the children of your Creation Tool elements in the mindmap.gmftool model. For example, if you delete the 'Delete Image' entry below the 'Creation Tool Subtopic' element that represents the small icon and replace it with a 'Small Icon Bundle Image' and set its Path property to platform:/plugin/org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/Subtopic.gif, it will use this icon. Of course, you'll need to provide this file or use the one found in the solution to this tutorial section.<br />
<br />
Finally, take a look in the mindmap.genmodel for properties to set for the default wizard and diagram file icons. While you're there, you might want to change the diagram file extension from 'mindmap_diagram' to 'mmd' or something similar. Browsing the properties available in the gmfgen model is a useful exercise.<br />
<br />
Below is an image of our diagram and palette using some new images.<br />
<br />
[[Image:new_icons.png]]<br />
<br style="clear:both;"/><br />
<br />
== Composite Figures ==<br />
[[Image:resource.png|frame|right]]<br />
What we'd like to do is have an actor-style representation for our resources added to our diagram. These will be linked to their respective Topic elements, much like our relationship links between Topic elements. Also, we'd like to have the labels for our Resource figures external and display both the name and email address attribute values of the corresponding domain element.<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:resource_figure.png|frame|right]]<br />
Open up your graphical definition again and add a new Rectangle named 'ResourceFigure' to your Figure Gallery. Set its Outline property to false, along with its Fill. As you can see from the image to the right, we will be adding a series of children to the rectangle, which will act as a container for the elements that comprise our Resource figure. Specifically, right-click and add an XY Layout, and Ellipse for the head, a Polygon for the Body, and sizing elements. Rather than go through all of the gory details of these, the figure code is found below. Either paste it into your mindmap.gmfgraph in the appropriate location using a text editor, or utilize the default editor and properties view.<br />
<br />
To our Canvas, add a new Node named ResourceNode and assign our ResourceFigure as its Figure. Also, notice the new 'BasicLabelFigure' label that is added to the Figure Gallery in the image. Create this and add a new Diagram Label 'ResourceLabel' to the Figure Gallery and Canvas respectively. Note that the Label for our Resource is not a child element of its figure. We want the label to be external, and therefore be allowed to float and be positioned wherever the user would like it.<br />
<br style="clear:both;"/><br />
<br />
<pre><br />
<figures xsi:type="gmfgraph:Rectangle" name="ResourceFigure" outline="false" fill="false" lineWidth="0"><br />
<layout xsi:type="gmfgraph:XYLayout"/><br />
<children xsi:type="gmfgraph:Ellipse" name="Head"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<size x="40" y="20"/><br />
</children><br />
<children xsi:type="gmfgraph:Polygon" name="Body"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<template x="23" y="19"/><br />
<template x="23" y="24"/><br />
<template x="39" y="24"/><br />
<template x="39" y="29"/><br />
<template x="23" y="29"/><br />
<template x="23" y="36"/><br />
<template x="39" y="48"/><br />
<template x="39" y="53"/><br />
<template x="20" y="42"/><br />
<template x="1" y="53"/><br />
<template x="1" y="48"/><br />
<template x="17" y="36"/><br />
<template x="17" y="29"/><br />
<template x="1" y="29"/><br />
<template x="1" y="24"/><br />
<template x="17" y="24"/><br />
<template x="17" y="19"/><br />
</children><br />
<maximumSize dx="40" dy="60"/><br />
<minimumSize dx="40" dy="60"/><br />
<preferredSize dx="40" dy="60"/><br />
<size x="40" y="60"/><br />
</figures><br />
</pre><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> It's a bit tedious to add multiple template points in the manner above, so feel free to open the gmfgraph file in a text editor to make life easier. Furthermore, to get it looking right more quickly, open the generated figure class and simply modify the GEF code directly and run the editor to see how it looks. Then, move this information back into your gmfgraph model. Of course, when the WYSIWYG features of GMF become available and mature, none of this should be necessary.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:resource_tool.png|frame|right]]<br />
We'll need a tool to add Resource nodes, so as you've done many times before, open the mindmap.gmftool model and add a new node creation tool for the Resource. Next, we'll need to add our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:resource_map.png|frame|right]]<br />
First, we'll need to add a new Top Node Reference to our Mapping definition. Set the Containment Feature to our 'EReference resources' attribute of our Map class. Add a child Node Mapping element to this Top Node Reference and select our 'EClass Resource' for the Domain meta information Element property. Of course, we'll select our ResourceNode for the Diagram Node and our Resource creation tool for the palette.<br />
<br />
Now, to add our Label Mapping as a child of the Node Mapping and set the Edit and View Pattern and corresponding features from our Resource class in the domain model. Here, we'll utilize the edit and view pattern properties of the mapping model to allow a Resource label to be displayed as 'name [email@some.com]'. To allow for the proper parsing of what's entered into the direct edit field, we will define an edit pattern for the label as '{0} : {1}' where a colon is used to separate the name and email attributes. Note that the generated plug-in code will contribute to the parserProvider extension-point, which will in turn leverages the Java MessageFormat class.<br />
<br />
=== Generation ===<br />
You will need to make one tweak to the generated code after you transform your mapping model to a new gmfgen model, as before. Open the newly-generated ResourceEditPart class and locate the createNodeShape() method. In this method, you will find a call to figure.setUseLocalCoordinates(false). In order for our polygon to appear in the rendered figure, you will need to set the argument to true. This should be a temporary workaround, and if you're not making changes to the figure, go ahead and add a NOT after @generated in the method comment. <br />
<br />
Run the diagram and check the operation of the label, as well as the look of the figure. It should look similar to the one above. Resources added to the diagram are now available in the properties view for topic assignments, thread authoring, etc. To add the possibility to create links from other elements to a Resource, follow steps similar to how links are used to represent subtopics.<br />
<br />
== Using External Figures ==<br />
<br />
== Creating a Customization Plug-in ==<br />
<br />
Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in...<br />
<br />
== Custom Actions ==<br />
<br />
The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic. Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or equivalent) and have the new Topic created, including the link, and with the in-place editor active on the new Topic. In this section, we will explore how to accomplish just this.<br />
<br />
[[Image:create_subtopic.png|frame|right]]<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add a composite figure, utilize external images and figures, and create a custom action contained within a new extension plug-in.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_3&diff=3864Graphical Modeling Framework/Tutorial/Part 32006-04-12T21:40:50Z<p>Rgronback: /* Composite Figures */</p>
<hr />
<div>'''Note:''' This is still very much a work in progress...<br />
<br />
In this third part of the GMF Tutorial, we will explore some more advanced capabilities related to the tooling components, while also extending what's generated with customizations to the runtime. Specifically we will add a composite figure using the graphical definition, show how to leverage external figures, and how to use an extension plug-in to add a custom action to our diagram. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_3.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
== New Icons ==<br />
A quick way to get a new polished look for our mindmap diagram is by replacing the generated EMF icons we've seen so far with some that are more, well... distinctive ;) The easiest way to do this is to replace the GIF images found in our org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/ folder. <br />
<br />
In case you'd like to map another image file to a palette item, say in the case of our three Relationship tools, or for our Subtopic link which has no default icon, you can modify the children of your Creation Tool elements in the mindmap.gmftool model. For example, if you delete the 'Delete Image' entry below the 'Creation Tool Subtopic' element that represents the small icon and replace it with a 'Small Icon Bundle Image' and set its Path property to platform:/plugin/org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/Subtopic.gif, it will use this icon. Of course, you'll need to provide this file or use the one found in the solution to this tutorial section.<br />
<br />
Finally, take a look in the mindmap.genmodel for properties to set for the default wizard and diagram file icons. While you're there, you might want to change the diagram file extension from 'mindmap_diagram' to 'mmd' or something similar. Browsing the properties available in the gmfgen model is a useful exercise.<br />
<br />
Below is an image of our diagram and palette using some new images.<br />
<br />
[[Image:new_icons.png]]<br />
<br style="clear:both;"/><br />
<br />
== Composite Figures ==<br />
[[Image:resource.png|frame|right]]<br />
What we'd like to do is have an actor-style representation for our resources added to our diagram. These will be linked to their respective Topic elements, much like our relationship links between Topic elements. Also, we'd like to have the labels for our Resource figures external and display both the name and email address attribute values of the corresponding domain element.<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:resource_figure.png|frame|right]]<br />
Open up your graphical definition again and add a new Rectangle named 'ResourceFigure' to your Figure Gallery. Set its Outline property to false, along with its Fill. As you can see from the image to the right, we will be adding a series of children to the rectangle, which will act as a container for the elements that comprise our Resource figure. Specifically, right-click and add an XY Layout, and Ellipse for the head, a Polygon for the Body, and sizing elements. Rather than go through all of the gory details of these, the figure code is found below. Either paste it into your mindmap.gmfgraph in the appropriate location using a text editor, or utilize the default editor and properties view.<br />
<br />
To our Canvas, add a new Node named ResourceNode and assign our ResourceFigure as its Figure. Also, notice the new 'BasicLabelFigure' label that is added to the Figure Gallery in the image. Create this and add a new Diagram Label 'ResourceLabel' to the Figure Gallery and Canvas respectively. Note that the Label for our Resource is not a child element of its figure. We want the label to be external, and therefore be allowed to float and be positioned wherever the user would like it.<br />
<br style="clear:both;"/><br />
<br />
<pre><br />
<figures xsi:type="gmfgraph:Rectangle" name="ResourceFigure" outline="false" fill="false" lineWidth="0"><br />
<layout xsi:type="gmfgraph:XYLayout"/><br />
<children xsi:type="gmfgraph:Ellipse" name="Head"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<size x="40" y="20"/><br />
</children><br />
<children xsi:type="gmfgraph:Polygon" name="Body"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<template x="23" y="19"/><br />
<template x="23" y="24"/><br />
<template x="39" y="24"/><br />
<template x="39" y="29"/><br />
<template x="23" y="29"/><br />
<template x="23" y="36"/><br />
<template x="39" y="48"/><br />
<template x="39" y="53"/><br />
<template x="20" y="42"/><br />
<template x="1" y="53"/><br />
<template x="1" y="48"/><br />
<template x="17" y="36"/><br />
<template x="17" y="29"/><br />
<template x="1" y="29"/><br />
<template x="1" y="24"/><br />
<template x="17" y="24"/><br />
<template x="17" y="19"/><br />
</children><br />
<maximumSize dx="40" dy="60"/><br />
<minimumSize dx="40" dy="60"/><br />
<preferredSize dx="40" dy="60"/><br />
<size x="40" y="60"/><br />
</figures><br />
</pre><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> It's a bit tedious to add multiple template points in the manner above, so feel free to open the gmfgraph file in a text editor to make life easier. Furthermore, to get it looking right more quickly, open the generated figure class and simply modify the GEF code directly and run the editor to see how it looks. Then, move this information back into your gmfgraph model. Of course, when the WYSIWYG features of GMF become available and mature, none of this should be necessary.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:resource_tool.png|frame|right]]<br />
We'll need a tool to add Resource nodes, so as you've done many times before, open the mindmap.gmftool model and add a new node creation tool for the Resource. Next, we'll need to add our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:resource_map.png|frame|right]]<br />
First, we'll need to add a new Top Node Reference to our Mapping definition. Set the Containment Feature to our 'EReference resources' attribute of our Map class. Add a child Node Mapping element to this Top Node Reference and select our 'EClass Resource' for the Domain meta information Element property. Of course, we'll select our ResourceNode for the Diagram Node and our Resource creation tool for the palette.<br />
<br />
Now, to add our Label Mapping as a child of the Node Mapping and set the Edit and View Pattern and corresponding features from our Resource class in the domain model. Here, we'll utilize the edit and view pattern properties of the mapping model to allow a Resource label to be displayed as 'name [email@some.com]'. To allow for the proper parsing of what's entered into the direct edit field, we will define an edit pattern for the label as '{0} : {1}' where a colon is used to separate the name and email attributes. Note that the generated plug-in code will contribute to the parserProvider extension-point, which will in turn leverages the Java MessageFormat class.<br />
<br />
=== Generation ===<br />
You will need to make one tweak to the generated code after you transform your mapping model to a new gmfgen model, as before. Open the newly-generated ResourceEditPart class and locate the createNodeShape() method. In this method, you will find a call to figure.setUseLocalCoordinates(false). In order for our polygon to appear in the rendered figure, you will need to set the argument to true. This should be a temporary workaround, and if you're not making changes to the figure, go ahead and add a NOT after @generated in the method comment. Run the diagram and check the operation of the label, as well as the look of the figure. It should look similar to the one above.<br />
<br />
== Using External Figures ==<br />
<br />
== Creating a Customization Plug-in ==<br />
<br />
Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in...<br />
<br />
== Custom Actions ==<br />
<br />
The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic. Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or equivalent) and have the new Topic created, including the link, and with the in-place editor active on the new Topic. In this section, we will explore how to accomplish just this.<br />
<br />
[[Image:create_subtopic.png|frame|right]]<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add a composite figure, utilize external images and figures, and create a custom action contained within a new extension plug-in.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=File:Resource_map.png&diff=3863File:Resource map.png2006-04-12T21:34:31Z<p>Rgronback: </p>
<hr />
<div></div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_3&diff=3862Graphical Modeling Framework/Tutorial/Part 32006-04-12T21:34:21Z<p>Rgronback: /* Mapping Definition */</p>
<hr />
<div>'''Note:''' This is still very much a work in progress...<br />
<br />
In this third part of the GMF Tutorial, we will explore some more advanced capabilities related to the tooling components, while also extending what's generated with customizations to the runtime. Specifically we will add a composite figure using the graphical definition, show how to leverage external figures, and how to use an extension plug-in to add a custom action to our diagram. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_3.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
== New Icons ==<br />
A quick way to get a new polished look for our mindmap diagram is by replacing the generated EMF icons we've seen so far with some that are more, well... distinctive ;) The easiest way to do this is to replace the GIF images found in our org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/ folder. <br />
<br />
In case you'd like to map another image file to a palette item, say in the case of our three Relationship tools, or for our Subtopic link which has no default icon, you can modify the children of your Creation Tool elements in the mindmap.gmftool model. For example, if you delete the 'Delete Image' entry below the 'Creation Tool Subtopic' element that represents the small icon and replace it with a 'Small Icon Bundle Image' and set its Path property to platform:/plugin/org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/Subtopic.gif, it will use this icon. Of course, you'll need to provide this file or use the one found in the solution to this tutorial section.<br />
<br />
Finally, take a look in the mindmap.genmodel for properties to set for the default wizard and diagram file icons. While you're there, you might want to change the diagram file extension from 'mindmap_diagram' to 'mmd' or something similar. Browsing the properties available in the gmfgen model is a useful exercise.<br />
<br />
Below is an image of our diagram and palette using some new images.<br />
<br />
[[Image:new_icons.png]]<br />
<br style="clear:both;"/><br />
<br />
== Composite Figures ==<br />
[[Image:resource.png|frame|right]]<br />
What we'd like to do is have an actor-style representation for our resources added to our diagram. These will be linked to their respective Topic elements, much like our relationship links between Topic elements. Also, we'd like to have the labels for our Resource figures external and display both the name and email address attribute values of the corresponding domain element.<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:resource_figure.png|frame|right]]<br />
Open up your graphical definition again and add a new Rectangle named 'ResourceFigure' to your Figure Gallery. Set its Outline property to false, along with its Fill. As you can see from the image to the right, we will be adding a series of children to the rectangle, which will act as a container for the elements that comprise our Resource figure. Specifically, right-click and add an XY Layout, and Ellipse for the head, a Polygon for the Body, and sizing elements. Rather than go through all of the gory details of these, the figure code is found below. Either paste it into your mindmap.gmfgraph in the appropriate location using a text editor, or utilize the default editor and properties view.<br />
<br />
To our Canvas, add a new Node named ResourceNode and assign our ResourceFigure as its Figure. Also, notice the new 'BasicLabelFigure' label that is added to the Figure Gallery in the image. Create this and add a new Diagram Label 'ResourceLabel' to the Figure Gallery and Canvas respectively. Note that the Label for our Resource is not a child element of its figure. We want the label to be external, and therefore be allowed to float and be positioned wherever the user would like it.<br />
<br style="clear:both;"/><br />
<br />
<pre><br />
<figures xsi:type="gmfgraph:Rectangle" name="ResourceFigure" outline="false" fill="false" lineWidth="0"><br />
<layout xsi:type="gmfgraph:XYLayout"/><br />
<children xsi:type="gmfgraph:Ellipse" name="Head"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<size x="40" y="20"/><br />
</children><br />
<children xsi:type="gmfgraph:Polygon" name="Body"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<template x="23" y="19"/><br />
<template x="23" y="24"/><br />
<template x="39" y="24"/><br />
<template x="39" y="29"/><br />
<template x="23" y="29"/><br />
<template x="23" y="36"/><br />
<template x="39" y="48"/><br />
<template x="39" y="53"/><br />
<template x="20" y="42"/><br />
<template x="1" y="53"/><br />
<template x="1" y="48"/><br />
<template x="17" y="36"/><br />
<template x="17" y="29"/><br />
<template x="1" y="29"/><br />
<template x="1" y="24"/><br />
<template x="17" y="24"/><br />
<template x="17" y="19"/><br />
</children><br />
<maximumSize dx="40" dy="60"/><br />
<minimumSize dx="40" dy="60"/><br />
<preferredSize dx="40" dy="60"/><br />
<size x="40" y="60"/><br />
</figures><br />
</pre><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> It's a bit tedious to add multiple template points in the manner above, so feel free to open the gmfgraph file in a text editor to make life easier. Furthermore, to get it looking right more quickly, open the generated figure class and simply modify the GEF code directly and run the editor to see how it looks. Then, move this information back into your gmfgraph model. Of course, when the WYSIWYG features of GMF become available and mature, none of this should be necessary.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:resource_tool.png|frame|right]]<br />
We'll need a tool to add Resource nodes, so as you've done many times before, open the mindmap.gmftool model and add a new node creation tool for the Resource. Next, we'll need to add our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:resource_map.png|frame|right]]<br />
First, we'll need to add a new Top Node Reference to our Mapping definition. Set the Containment Feature to our 'EReference resources' attribute of our Map class. Add a child Node Mapping element to this Top Node Reference and select our 'EClass Resource' for the Domain meta information Element property. Of course, we'll select our ResourceNode for the Diagram Node and our Resource creation tool for the palette.<br />
<br />
Now, to add our Label Mapping as a child of the Node Mapping and set the Edit and View Pattern and corresponding features from our Resource class in the domain model. Here, we'll utilize the edit and view pattern properties of the mapping model to allow a Resource label to be displayed as 'name [email@some.com]'. To allow for the proper parsing of what's entered into the direct edit field, we will define an edit pattern for the label as '{0} : {1}' where a colon is used to separate the name and email attributes. Note that the generated plug-in code will contribute to the parserProvider extension-point, which will in turn leverages the Java MessageFormat class.<br />
<br />
== Using External Figures ==<br />
<br />
== Creating a Customization Plug-in ==<br />
<br />
Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in...<br />
<br />
== Custom Actions ==<br />
<br />
The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic. Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or equivalent) and have the new Topic created, including the link, and with the in-place editor active on the new Topic. In this section, we will explore how to accomplish just this.<br />
<br />
[[Image:create_subtopic.png|frame|right]]<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add a composite figure, utilize external images and figures, and create a custom action contained within a new extension plug-in.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=File:Resource_tool.png&diff=3861File:Resource tool.png2006-04-12T21:20:42Z<p>Rgronback: </p>
<hr />
<div></div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_3&diff=3860Graphical Modeling Framework/Tutorial/Part 32006-04-12T21:19:20Z<p>Rgronback: /* Graphical Definition */</p>
<hr />
<div>'''Note:''' This is still very much a work in progress...<br />
<br />
In this third part of the GMF Tutorial, we will explore some more advanced capabilities related to the tooling components, while also extending what's generated with customizations to the runtime. Specifically we will add a composite figure using the graphical definition, show how to leverage external figures, and how to use an extension plug-in to add a custom action to our diagram. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_3.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
== New Icons ==<br />
A quick way to get a new polished look for our mindmap diagram is by replacing the generated EMF icons we've seen so far with some that are more, well... distinctive ;) The easiest way to do this is to replace the GIF images found in our org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/ folder. <br />
<br />
In case you'd like to map another image file to a palette item, say in the case of our three Relationship tools, or for our Subtopic link which has no default icon, you can modify the children of your Creation Tool elements in the mindmap.gmftool model. For example, if you delete the 'Delete Image' entry below the 'Creation Tool Subtopic' element that represents the small icon and replace it with a 'Small Icon Bundle Image' and set its Path property to platform:/plugin/org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/Subtopic.gif, it will use this icon. Of course, you'll need to provide this file or use the one found in the solution to this tutorial section.<br />
<br />
Finally, take a look in the mindmap.genmodel for properties to set for the default wizard and diagram file icons. While you're there, you might want to change the diagram file extension from 'mindmap_diagram' to 'mmd' or something similar. Browsing the properties available in the gmfgen model is a useful exercise.<br />
<br />
Below is an image of our diagram and palette using some new images.<br />
<br />
[[Image:new_icons.png]]<br />
<br style="clear:both;"/><br />
<br />
== Composite Figures ==<br />
[[Image:resource.png|frame|right]]<br />
What we'd like to do is have an actor-style representation for our resources added to our diagram. These will be linked to their respective Topic elements, much like our relationship links between Topic elements. Also, we'd like to have the labels for our Resource figures external and display both the name and email address attribute values of the corresponding domain element.<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:resource_figure.png|frame|right]]<br />
Open up your graphical definition again and add a new Rectangle named 'ResourceFigure' to your Figure Gallery. Set its Outline property to false, along with its Fill. As you can see from the image to the right, we will be adding a series of children to the rectangle, which will act as a container for the elements that comprise our Resource figure. Specifically, right-click and add an XY Layout, and Ellipse for the head, a Polygon for the Body, and sizing elements. Rather than go through all of the gory details of these, the figure code is found below. Either paste it into your mindmap.gmfgraph in the appropriate location using a text editor, or utilize the default editor and properties view.<br />
<br />
To our Canvas, add a new Node named ResourceNode and assign our ResourceFigure as its Figure. Also, notice the new 'BasicLabelFigure' label that is added to the Figure Gallery in the image. Create this and add a new Diagram Label 'ResourceLabel' to the Figure Gallery and Canvas respectively. Note that the Label for our Resource is not a child element of its figure. We want the label to be external, and therefore be allowed to float and be positioned wherever the user would like it.<br />
<br style="clear:both;"/><br />
<br />
<pre><br />
<figures xsi:type="gmfgraph:Rectangle" name="ResourceFigure" outline="false" fill="false" lineWidth="0"><br />
<layout xsi:type="gmfgraph:XYLayout"/><br />
<children xsi:type="gmfgraph:Ellipse" name="Head"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<size x="40" y="20"/><br />
</children><br />
<children xsi:type="gmfgraph:Polygon" name="Body"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<template x="23" y="19"/><br />
<template x="23" y="24"/><br />
<template x="39" y="24"/><br />
<template x="39" y="29"/><br />
<template x="23" y="29"/><br />
<template x="23" y="36"/><br />
<template x="39" y="48"/><br />
<template x="39" y="53"/><br />
<template x="20" y="42"/><br />
<template x="1" y="53"/><br />
<template x="1" y="48"/><br />
<template x="17" y="36"/><br />
<template x="17" y="29"/><br />
<template x="1" y="29"/><br />
<template x="1" y="24"/><br />
<template x="17" y="24"/><br />
<template x="17" y="19"/><br />
</children><br />
<maximumSize dx="40" dy="60"/><br />
<minimumSize dx="40" dy="60"/><br />
<preferredSize dx="40" dy="60"/><br />
<size x="40" y="60"/><br />
</figures><br />
</pre><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> It's a bit tedious to add multiple template points in the manner above, so feel free to open the gmfgraph file in a text editor to make life easier. Furthermore, to get it looking right more quickly, open the generated figure class and simply modify the GEF code directly and run the editor to see how it looks. Then, move this information back into your gmfgraph model. Of course, when the WYSIWYG features of GMF become available and mature, none of this should be necessary.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:resource_tool.png|frame|right]]<br />
We'll need a tool to add Resource nodes, so as you've done many times before, open the mindmap.gmftool model and add a new node creation tool for the Resource. Next, we'll need to add our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:resource_map.png|frame|right]]<br />
First, we'll need to add...<br />
<br />
Here, we'll utilize the edit and view pattern properties of the mapping model to allow a Resource label to be displayed as 'name [email@some.com]'.<br />
<br />
== Using External Figures ==<br />
<br />
== Creating a Customization Plug-in ==<br />
<br />
Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in...<br />
<br />
== Custom Actions ==<br />
<br />
The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic. Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or equivalent) and have the new Topic created, including the link, and with the in-place editor active on the new Topic. In this section, we will explore how to accomplish just this.<br />
<br />
[[Image:create_subtopic.png|frame|right]]<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add a composite figure, utilize external images and figures, and create a custom action contained within a new extension plug-in.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_3&diff=3859Graphical Modeling Framework/Tutorial/Part 32006-04-12T21:11:19Z<p>Rgronback: /* Graphical Definition */</p>
<hr />
<div>'''Note:''' This is still very much a work in progress...<br />
<br />
In this third part of the GMF Tutorial, we will explore some more advanced capabilities related to the tooling components, while also extending what's generated with customizations to the runtime. Specifically we will add a composite figure using the graphical definition, show how to leverage external figures, and how to use an extension plug-in to add a custom action to our diagram. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_3.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
== New Icons ==<br />
A quick way to get a new polished look for our mindmap diagram is by replacing the generated EMF icons we've seen so far with some that are more, well... distinctive ;) The easiest way to do this is to replace the GIF images found in our org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/ folder. <br />
<br />
In case you'd like to map another image file to a palette item, say in the case of our three Relationship tools, or for our Subtopic link which has no default icon, you can modify the children of your Creation Tool elements in the mindmap.gmftool model. For example, if you delete the 'Delete Image' entry below the 'Creation Tool Subtopic' element that represents the small icon and replace it with a 'Small Icon Bundle Image' and set its Path property to platform:/plugin/org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/Subtopic.gif, it will use this icon. Of course, you'll need to provide this file or use the one found in the solution to this tutorial section.<br />
<br />
Finally, take a look in the mindmap.genmodel for properties to set for the default wizard and diagram file icons. While you're there, you might want to change the diagram file extension from 'mindmap_diagram' to 'mmd' or something similar. Browsing the properties available in the gmfgen model is a useful exercise.<br />
<br />
Below is an image of our diagram and palette using some new images.<br />
<br />
[[Image:new_icons.png]]<br />
<br style="clear:both;"/><br />
<br />
== Composite Figures ==<br />
[[Image:resource.png|frame|right]]<br />
What we'd like to do is have an actor-style representation for our resources added to our diagram. These will be linked to their respective Topic elements, much like our relationship links between Topic elements. Also, we'd like to have the labels for our Resource figures external and display both the name and email address attribute values of the corresponding domain element.<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:resource_figure.png|frame|right]]<br />
Open up your graphical definition again and add a new...<br />
<br style="clear:both;"/><br />
<br />
<pre><br />
<figures xsi:type="gmfgraph:Rectangle" name="ResourceFigure" outline="false" fill="false" lineWidth="0"><br />
<layout xsi:type="gmfgraph:XYLayout"/><br />
<children xsi:type="gmfgraph:Ellipse" name="Head"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<size x="40" y="20"/><br />
</children><br />
<children xsi:type="gmfgraph:Polygon" name="Body"><br />
<foregroundColor xsi:type="gmfgraph:RGBColor" red="220" green="220" blue="250"/><br />
<backgroundColor xsi:type="gmfgraph:RGBColor" red="230" green="230" blue="255"/><br />
<template x="23" y="19"/><br />
<template x="23" y="24"/><br />
<template x="39" y="24"/><br />
<template x="39" y="29"/><br />
<template x="23" y="29"/><br />
<template x="23" y="36"/><br />
<template x="39" y="48"/><br />
<template x="39" y="53"/><br />
<template x="20" y="42"/><br />
<template x="1" y="53"/><br />
<template x="1" y="48"/><br />
<template x="17" y="36"/><br />
<template x="17" y="29"/><br />
<template x="1" y="29"/><br />
<template x="1" y="24"/><br />
<template x="17" y="24"/><br />
<template x="17" y="19"/><br />
</children><br />
<maximumSize dx="40" dy="60"/><br />
<minimumSize dx="40" dy="60"/><br />
<preferredSize dx="40" dy="60"/><br />
<size x="40" y="60"/><br />
</figures><br />
</pre><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> It's a bit tedious to add multiple template points in the manner above, so feel free to open the gmfgraph file in a text editor to make life easier. Furthermore, to get it looking right more quickly, open the generated figure class and simply modify the GEF code directly and run the editor to see how it looks. Then, move this information back into your gmfgraph model. Of course, when the WYSIWYG features of GMF become available and mature, none of this should be necessary.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:resource_tool.png|frame|right]]<br />
We'll need a tool to add Resource nodes, so as you've done many times before, open the mindmap.gmftool model and add a new node creation tool for the Resource. Next, we'll need to add our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:resource_map.png|frame|right]]<br />
First, we'll need to add...<br />
<br />
Here, we'll utilize the edit and view pattern properties of the mapping model to allow a Resource label to be displayed as 'name [email@some.com]'.<br />
<br />
== Using External Figures ==<br />
<br />
== Creating a Customization Plug-in ==<br />
<br />
Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in...<br />
<br />
== Custom Actions ==<br />
<br />
The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic. Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or equivalent) and have the new Topic created, including the link, and with the in-place editor active on the new Topic. In this section, we will explore how to accomplish just this.<br />
<br />
[[Image:create_subtopic.png|frame|right]]<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add a composite figure, utilize external images and figures, and create a custom action contained within a new extension plug-in.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=File:Resource_figure.png&diff=3858File:Resource figure.png2006-04-12T21:09:37Z<p>Rgronback: </p>
<hr />
<div></div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_3&diff=3857Graphical Modeling Framework/Tutorial/Part 32006-04-12T21:04:37Z<p>Rgronback: /* Composite Figures */</p>
<hr />
<div>'''Note:''' This is still very much a work in progress...<br />
<br />
In this third part of the GMF Tutorial, we will explore some more advanced capabilities related to the tooling components, while also extending what's generated with customizations to the runtime. Specifically we will add a composite figure using the graphical definition, show how to leverage external figures, and how to use an extension plug-in to add a custom action to our diagram. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_3.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
== New Icons ==<br />
A quick way to get a new polished look for our mindmap diagram is by replacing the generated EMF icons we've seen so far with some that are more, well... distinctive ;) The easiest way to do this is to replace the GIF images found in our org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/ folder. <br />
<br />
In case you'd like to map another image file to a palette item, say in the case of our three Relationship tools, or for our Subtopic link which has no default icon, you can modify the children of your Creation Tool elements in the mindmap.gmftool model. For example, if you delete the 'Delete Image' entry below the 'Creation Tool Subtopic' element that represents the small icon and replace it with a 'Small Icon Bundle Image' and set its Path property to platform:/plugin/org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/Subtopic.gif, it will use this icon. Of course, you'll need to provide this file or use the one found in the solution to this tutorial section.<br />
<br />
Finally, take a look in the mindmap.genmodel for properties to set for the default wizard and diagram file icons. While you're there, you might want to change the diagram file extension from 'mindmap_diagram' to 'mmd' or something similar. Browsing the properties available in the gmfgen model is a useful exercise.<br />
<br />
Below is an image of our diagram and palette using some new images.<br />
<br />
[[Image:new_icons.png]]<br />
<br style="clear:both;"/><br />
<br />
== Composite Figures ==<br />
[[Image:resource.png|frame|right]]<br />
What we'd like to do is have an actor-style representation for our resources added to our diagram. These will be linked to their respective Topic elements, much like our relationship links between Topic elements. Also, we'd like to have the labels for our Resource figures external and display both the name and email address attribute values of the corresponding domain element.<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:resource_figure.png|frame|right]]<br />
Open up your graphical definition again and add a new...<br />
<br style="clear:both;"/><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> It's a bit tedious to add multiple template points in the manner above, so feel free to open the gmfgraph file in a text editor to make life easier. Furthermore, to get it looking right more quickly, open the generated figure class and simply modify the GEF code directly and run the editor to see how it looks. Then, move this information back into your gmfgraph model. Of course, when the WYSIWYG features of GMF become available and mature, none of this should be necessary.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:resource_tool.png|frame|right]]<br />
We'll need a tool to add Resource nodes, so as you've done many times before, open the mindmap.gmftool model and add a new node creation tool for the Resource. Next, we'll need to add our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:resource_map.png|frame|right]]<br />
First, we'll need to add...<br />
<br />
Here, we'll utilize the edit and view pattern properties of the mapping model to allow a Resource label to be displayed as 'name [email@some.com]'.<br />
<br />
== Using External Figures ==<br />
<br />
== Creating a Customization Plug-in ==<br />
<br />
Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in...<br />
<br />
== Custom Actions ==<br />
<br />
The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic. Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or equivalent) and have the new Topic created, including the link, and with the in-place editor active on the new Topic. In this section, we will explore how to accomplish just this.<br />
<br />
[[Image:create_subtopic.png|frame|right]]<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add a composite figure, utilize external images and figures, and create a custom action contained within a new extension plug-in.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=File:Resource.png&diff=3856File:Resource.png2006-04-12T21:04:28Z<p>Rgronback: </p>
<hr />
<div></div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_3&diff=3851Graphical Modeling Framework/Tutorial/Part 32006-04-12T15:19:38Z<p>Rgronback: /* New Icons */</p>
<hr />
<div>'''Note:''' This is still very much a work in progress...<br />
<br />
In this third part of the GMF Tutorial, we will explore some more advanced capabilities related to the tooling components, while also extending what's generated with customizations to the runtime. Specifically we will add a composite figure using the graphical definition, show how to leverage external figures, and how to use an extension plug-in to add a custom action to our diagram. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_3.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
== New Icons ==<br />
A quick way to get a new polished look for our mindmap diagram is by replacing the generated EMF icons we've seen so far with some that are more, well... distinctive ;) The easiest way to do this is to replace the GIF images found in our org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/ folder. <br />
<br />
In case you'd like to map another image file to a palette item, say in the case of our three Relationship tools, or for our Subtopic link which has no default icon, you can modify the children of your Creation Tool elements in the mindmap.gmftool model. For example, if you delete the 'Delete Image' entry below the 'Creation Tool Subtopic' element that represents the small icon and replace it with a 'Small Icon Bundle Image' and set its Path property to platform:/plugin/org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/Subtopic.gif, it will use this icon. Of course, you'll need to provide this file or use the one found in the solution to this tutorial section.<br />
<br />
Finally, take a look in the mindmap.genmodel for properties to set for the default wizard and diagram file icons. While you're there, you might want to change the diagram file extension from 'mindmap_diagram' to 'mmd' or something similar. Browsing the properties available in the gmfgen model is a useful exercise.<br />
<br />
Below is an image of our diagram and palette using some new images.<br />
<br />
[[Image:new_icons.png]]<br />
<br style="clear:both;"/><br />
<br />
== Composite Figures ==<br />
[[Image:resource.png|frame|right]]<br />
What we'd like to do is have an actor-style representation for our resources added to our diagram. These will be linked to their respective Topic elements, much like our relationship links between Topic elements.<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:resource_figure.png|frame|right]]<br />
Open up your graphical definition again and add a new...<br />
<br style="clear:both;"/><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> It's a bit tedious to add multiple template points in the manner above, so feel free to open the gmfgraph file in a text editor to make life easier. Furthermore, to get it looking right more quickly, open the generated figure class and simply modify the GEF code directly and run the editor to see how it looks. Then, move this information back into your gmfgraph model. Of course, when the WYSIWYG features of GMF become available and mature, none of this should be necessary.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:resource_tool.png|frame|right]]<br />
We'll need a tool to add Resource nodes, so as you've done many times before, open the mindmap.gmftool model and add a new node creation tool for the Resource. Next, we'll need to add our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:resource_map.png|frame|right]]<br />
First, we'll need to add...<br />
<br />
Here, we'll utilize the edit and view pattern properties of the mapping model to allow a Resource label to be displayed as 'name [email@some.com]'.<br />
<br />
== Using External Figures ==<br />
<br />
== Creating a Customization Plug-in ==<br />
<br />
Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in...<br />
<br />
== Custom Actions ==<br />
<br />
The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic. Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or equivalent) and have the new Topic created, including the link, and with the in-place editor active on the new Topic. In this section, we will explore how to accomplish just this.<br />
<br />
[[Image:create_subtopic.png|frame|right]]<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add a composite figure, utilize external images and figures, and create a custom action contained within a new extension plug-in.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_3&diff=3850Graphical Modeling Framework/Tutorial/Part 32006-04-12T15:19:25Z<p>Rgronback: /* New Icons */</p>
<hr />
<div>'''Note:''' This is still very much a work in progress...<br />
<br />
In this third part of the GMF Tutorial, we will explore some more advanced capabilities related to the tooling components, while also extending what's generated with customizations to the runtime. Specifically we will add a composite figure using the graphical definition, show how to leverage external figures, and how to use an extension plug-in to add a custom action to our diagram. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_3.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
== New Icons ==<br />
A quick way to get a new polished look for our mindmap diagram is by replacing the generated EMF icons we've seen so far with some that are more, well... distinctive ;) The easiest way to do this is to replace the GIF images found in our org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/ folder. <br />
<br />
In case you'd like to map another image file to a palette item, say in the case of our three Relationship tools, or for our Subtopic link which has no default icon, you can modify the children of your Creation Tool elements in the mindmap.gmftool model. For example, if you delete the 'Delete Image' entry below the 'Creation Tool Subtopic' element that represents the small icon and replace it with a 'Small Icon Bundle Image' and set its Path property to platform:/plugin/org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/Subtopic.gif, it will use this icon. Of course, you'll need to provide this file or use the one found in the solution to this tutorial section.<br />
<br />
Finally, take a look in the mindmap.genmodel for properties to set for the default wizard and diagram file icons. While you're there, you might want to change the diagram file extension from 'mindmap_diagram' to 'mmd' or something similar. Browsing the properties available in the gmfgen model is a useful exercise.<br />
<br />
Below is an image of our diagram and palette using some new images.<br />
<br />
[[Image:new_icons.png|right]]<br />
<br style="clear:both;"/><br />
<br />
== Composite Figures ==<br />
[[Image:resource.png|frame|right]]<br />
What we'd like to do is have an actor-style representation for our resources added to our diagram. These will be linked to their respective Topic elements, much like our relationship links between Topic elements.<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:resource_figure.png|frame|right]]<br />
Open up your graphical definition again and add a new...<br />
<br style="clear:both;"/><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> It's a bit tedious to add multiple template points in the manner above, so feel free to open the gmfgraph file in a text editor to make life easier. Furthermore, to get it looking right more quickly, open the generated figure class and simply modify the GEF code directly and run the editor to see how it looks. Then, move this information back into your gmfgraph model. Of course, when the WYSIWYG features of GMF become available and mature, none of this should be necessary.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:resource_tool.png|frame|right]]<br />
We'll need a tool to add Resource nodes, so as you've done many times before, open the mindmap.gmftool model and add a new node creation tool for the Resource. Next, we'll need to add our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:resource_map.png|frame|right]]<br />
First, we'll need to add...<br />
<br />
Here, we'll utilize the edit and view pattern properties of the mapping model to allow a Resource label to be displayed as 'name [email@some.com]'.<br />
<br />
== Using External Figures ==<br />
<br />
== Creating a Customization Plug-in ==<br />
<br />
Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in...<br />
<br />
== Custom Actions ==<br />
<br />
The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic. Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or equivalent) and have the new Topic created, including the link, and with the in-place editor active on the new Topic. In this section, we will explore how to accomplish just this.<br />
<br />
[[Image:create_subtopic.png|frame|right]]<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add a composite figure, utilize external images and figures, and create a custom action contained within a new extension plug-in.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_3&diff=3849Graphical Modeling Framework/Tutorial/Part 32006-04-12T15:17:18Z<p>Rgronback: </p>
<hr />
<div>'''Note:''' This is still very much a work in progress...<br />
<br />
In this third part of the GMF Tutorial, we will explore some more advanced capabilities related to the tooling components, while also extending what's generated with customizations to the runtime. Specifically we will add a composite figure using the graphical definition, show how to leverage external figures, and how to use an extension plug-in to add a custom action to our diagram. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_3.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
== New Icons ==<br />
A quick way to get a new polished look for our mindmap diagram is by replacing the generated EMF icons we've seen so far with some that are more, well... distinctive ;) The easiest way to do this is to replace the GIF images found in our org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/ folder. <br />
<br />
In the case you'd like to map another image file to a palette item, say in the case of our three Relationship tools or for our Subtopic link which has no default icon, you can modify the children of your Creation Tool elements in the mindmap.gmftool model. For example, if you delete the 'Delete Image' entry below the 'Creation Tool Subtopic' element that represents the small icon and replace it with a 'Small Icon Bundle Image' and set its Path property to platform:/plugin/org.eclipse.gmf.examples.mindmap.edit/icons/full/obj16/Subtopic.gif, it will use this icon. Of course, you'll need to provide this file or use the one found in the solution to this tutorial section.<br />
<br />
Finally, take a look in the mindmap.genmodel for properties to set for the default wizard and diagram file icons. While you're there, you might want to change the diagram file extension from 'mindmap_diagram' to 'mmd' or something similar.<br />
<br />
Below is an image of our new diagram and palette using some new images.<br />
<br />
[[Image:new_icons.png|right]]<br />
<br style="clear:both;"/><br />
<br />
== Composite Figures ==<br />
[[Image:resource.png|frame|right]]<br />
What we'd like to do is have an actor-style representation for our resources added to our diagram. These will be linked to their respective Topic elements, much like our relationship links between Topic elements.<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:resource_figure.png|frame|right]]<br />
Open up your graphical definition again and add a new...<br />
<br style="clear:both;"/><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> It's a bit tedious to add multiple template points in the manner above, so feel free to open the gmfgraph file in a text editor to make life easier. Furthermore, to get it looking right more quickly, open the generated figure class and simply modify the GEF code directly and run the editor to see how it looks. Then, move this information back into your gmfgraph model. Of course, when the WYSIWYG features of GMF become available and mature, none of this should be necessary.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:resource_tool.png|frame|right]]<br />
We'll need a tool to add Resource nodes, so as you've done many times before, open the mindmap.gmftool model and add a new node creation tool for the Resource. Next, we'll need to add our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:resource_map.png|frame|right]]<br />
First, we'll need to add...<br />
<br />
Here, we'll utilize the edit and view pattern properties of the mapping model to allow a Resource label to be displayed as 'name [email@some.com]'.<br />
<br />
== Using External Figures ==<br />
<br />
== Creating a Customization Plug-in ==<br />
<br />
Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in...<br />
<br />
== Custom Actions ==<br />
<br />
The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic. Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or equivalent) and have the new Topic created, including the link, and with the in-place editor active on the new Topic. In this section, we will explore how to accomplish just this.<br />
<br />
[[Image:create_subtopic.png|frame|right]]<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add a composite figure, utilize external images and figures, and create a custom action contained within a new extension plug-in.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=File:New_icons.png&diff=3848File:New icons.png2006-04-12T15:17:00Z<p>Rgronback: </p>
<hr />
<div></div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_3&diff=3844Graphical Modeling Framework/Tutorial/Part 32006-04-12T13:02:28Z<p>Rgronback: </p>
<hr />
<div>'''Note:''' This is still very much a work in progress...<br />
<br />
In this third part of the GMF Tutorial, we will explore some more advanced capabilities related to the tooling components, while also extending what's generated with customizations to the runtime. Specifically we will add a composite figure using the graphical definition, show how to leverage external figures, and how to use an extension plug-in to add a custom action to our diagram. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_3.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Composite Figures ==<br />
[[Image:resource.png|frame|right]]<br />
What we'd like to do is have an actor-style representation for our resources added to our diagram. These will be linked to their respective Topic elements, much like our relationship links between Topic elements.<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:resource_figure.png|frame|right]]<br />
Open up your graphical definition again and add a new...<br />
<br style="clear:both;"/><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> It's a bit tedious to add multiple template points in the manner above, so feel free to open the gmfgraph file in a text editor to make life easier. Furthermore, to get it looking right more quickly, open the generated figure class and simply modify the GEF code directly and run the editor to see how it looks. Then, move this information back into your gmfgraph model. Of course, when the WYSIWYG features of GMF become available and mature, none of this should be necessary.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:resource_tool.png|frame|right]]<br />
We'll need a tool to add Resource nodes, so as you've done many times before, open the mindmap.gmftool model and add a new node creation tool for the Resource. Next, we'll need to add our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:resource_map.png|frame|right]]<br />
First, we'll need to add...<br />
<br />
Here, we'll utilize the edit and view pattern properties of the mapping model to allow a Resource label to be displayed as 'name [email@some.com]'.<br />
<br />
== Using External Figures ==<br />
<br />
== Creating a Customization Plug-in ==<br />
<br />
Although making modifications to the generated code and specifying '@generated NOT' to allow JMerge to preserve our changes works well for some customizations, it's also possible to separate other customizations (extensions) to our generated plug-in using a new plug-in...<br />
<br />
== Custom Actions ==<br />
<br />
The standard means to create a new subtopic is a bit painful at the moment: click on Topic creation tool, then diagram, name with in-place editor, click Subtopic link creation tool, draw link from parent to subtopic. Ideally, we'd like to simply use a right-click menu option on a selected Topic and choose "Create Subtopic" or better yet, press the Insert key (or equivalent) and have the new Topic created, including the link, and with the in-place editor active on the new Topic. In this section, we will explore how to accomplish just this.<br />
<br />
[[Image:create_subtopic.png|frame|right]]<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add a composite figure, utilize external images and figures, and create a custom action contained within a new extension plug-in.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3843Graphical Modeling Framework/Tutorial/Part 22006-04-12T13:01:50Z<p>Rgronback: /* Summary */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Link Constraints ==<br />
[[Image:link2self.png|frame|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|frame|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: oppositeEnd.oclIsUndefined() or self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
Note: the expression above is different than in previous versions of this tutorial, and is expected to return to just 'self <> oppositeEnd' when a bug in EMFT OCL is fixed.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but it's in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool. Finally, rename the 'mindmap' tool group to 'Nodes'.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|frame|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Add a new child Label to our Polyline Connection DashedLineOpenArrow and name it DashedLineLabelFigure. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineLabelFigure.<br />
<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Includes' and 'Extends' tools. <br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first verify the tool used by our current Relationship Link Mapping is set to the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). Lastly, we'll need to provide a new Label Mapping to let the 'EAttribute label' feature of our Relationship domain element be represented by our RelationshipLabel.<br />
<br />
Copy/paste your Dependency Link Mapping to create an Include and Extend link mapping, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'New Child... Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element Target' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
<br style="clear:both;"/><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor.<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor, along with adding some polish. See [[GMF_Tutorial_Part_3|GMF Tutorial Part 3]].</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3842Graphical Modeling Framework/Tutorial/Part 22006-04-12T12:58:07Z<p>Rgronback: /* Summary */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Link Constraints ==<br />
[[Image:link2self.png|frame|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|frame|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: oppositeEnd.oclIsUndefined() or self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
Note: the expression above is different than in previous versions of this tutorial, and is expected to return to just 'self <> oppositeEnd' when a bug in EMFT OCL is fixed.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but it's in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool. Finally, rename the 'mindmap' tool group to 'Nodes'.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|frame|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Add a new child Label to our Polyline Connection DashedLineOpenArrow and name it DashedLineLabelFigure. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineLabelFigure.<br />
<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Includes' and 'Extends' tools. <br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first verify the tool used by our current Relationship Link Mapping is set to the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). Lastly, we'll need to provide a new Label Mapping to let the 'EAttribute label' feature of our Relationship domain element be represented by our RelationshipLabel.<br />
<br />
Copy/paste your Dependency Link Mapping to create an Include and Extend link mapping, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'New Child... Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element Target' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
<br style="clear:both;"/><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor.<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor, along with adding some polish. See [[GMF_Tutorial_Part_2|GMF Tutorial Part 2]].</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3841Graphical Modeling Framework/Tutorial/Part 22006-04-12T12:51:52Z<p>Rgronback: /* Shortcuts */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Link Constraints ==<br />
[[Image:link2self.png|frame|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|frame|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: oppositeEnd.oclIsUndefined() or self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
Note: the expression above is different than in previous versions of this tutorial, and is expected to return to just 'self <> oppositeEnd' when a bug in EMFT OCL is fixed.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but it's in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool. Finally, rename the 'mindmap' tool group to 'Nodes'.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|frame|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Add a new child Label to our Polyline Connection DashedLineOpenArrow and name it DashedLineLabelFigure. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineLabelFigure.<br />
<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Includes' and 'Extends' tools. <br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first verify the tool used by our current Relationship Link Mapping is set to the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). Lastly, we'll need to provide a new Label Mapping to let the 'EAttribute label' feature of our Relationship domain element be represented by our RelationshipLabel.<br />
<br />
Copy/paste your Dependency Link Mapping to create an Include and Extend link mapping, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'New Child... Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element Target' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
<br style="clear:both;"/><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor.<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3840Graphical Modeling Framework/Tutorial/Part 22006-04-12T12:42:22Z<p>Rgronback: /* Validation */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Link Constraints ==<br />
[[Image:link2self.png|frame|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|frame|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: oppositeEnd.oclIsUndefined() or self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
Note: the expression above is different than in previous versions of this tutorial, and is expected to return to just 'self <> oppositeEnd' when a bug in EMFT OCL is fixed.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but it's in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool. Finally, rename the 'mindmap' tool group to 'Nodes'.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|frame|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Add a new child Label to our Polyline Connection DashedLineOpenArrow and name it DashedLineLabelFigure. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineLabelFigure.<br />
<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Includes' and 'Extends' tools. <br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first verify the tool used by our current Relationship Link Mapping is set to the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). Lastly, we'll need to provide a new Label Mapping to let the 'EAttribute label' feature of our Relationship domain element be represented by our RelationshipLabel.<br />
<br />
Copy/paste your Dependency Link Mapping to create an Include and Extend link mapping, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'New Child... Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element Target' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
<br style="clear:both;"/><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_audit.html here].<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3839Graphical Modeling Framework/Tutorial/Part 22006-04-12T12:41:50Z<p>Rgronback: /* Validation */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Link Constraints ==<br />
[[Image:link2self.png|frame|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|frame|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: oppositeEnd.oclIsUndefined() or self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
Note: the expression above is different than in previous versions of this tutorial, and is expected to return to just 'self <> oppositeEnd' when a bug in EMFT OCL is fixed.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but it's in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool. Finally, rename the 'mindmap' tool group to 'Nodes'.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|frame|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Add a new child Label to our Polyline Connection DashedLineOpenArrow and name it DashedLineLabelFigure. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineLabelFigure.<br />
<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Includes' and 'Extends' tools. <br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first verify the tool used by our current Relationship Link Mapping is set to the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). Lastly, we'll need to provide a new Label Mapping to let the 'EAttribute label' feature of our Relationship domain element be represented by our RelationshipLabel.<br />
<br />
Copy/paste your Dependency Link Mapping to create an Include and Extend link mapping, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'New Child... Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element Target' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<br style="clear:both;"/><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_audit.html here].<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3838Graphical Modeling Framework/Tutorial/Part 22006-04-12T12:35:17Z<p>Rgronback: /* Validation */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Link Constraints ==<br />
[[Image:link2self.png|frame|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|frame|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: oppositeEnd.oclIsUndefined() or self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
Note: the expression above is different than in previous versions of this tutorial, and is expected to return to just 'self <> oppositeEnd' when a bug in EMFT OCL is fixed.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but it's in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool. Finally, rename the 'mindmap' tool group to 'Nodes'.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|frame|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Add a new child Label to our Polyline Connection DashedLineOpenArrow and name it DashedLineLabelFigure. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineLabelFigure.<br />
<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Includes' and 'Extends' tools. <br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first verify the tool used by our current Relationship Link Mapping is set to the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). Lastly, we'll need to provide a new Label Mapping to let the 'EAttribute label' feature of our Relationship domain element be represented by our RelationshipLabel.<br />
<br />
Copy/paste your Dependency Link Mapping to create an Include and Extend link mapping, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'New Child... Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<br style="clear:both;"/><br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_audit.html here].<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3833Graphical Modeling Framework/Tutorial/Part 22006-04-11T19:55:49Z<p>Rgronback: /* Mapping Definition */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Link Constraints ==<br />
[[Image:link2self.png|frame|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|frame|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: oppositeEnd.oclIsUndefined() or self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
Note: the expression above is different than in previous versions of this tutorial, and is expected to return to just 'self <> oppositeEnd' when a bug in EMFT OCL is fixed.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but it's in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool. Finally, rename the 'mindmap' tool group to 'Nodes'.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|frame|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Add a new child Label to our Polyline Connection DashedLineOpenArrow and name it DashedLineLabelFigure. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineLabelFigure.<br />
<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Includes' and 'Extends' tools. <br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first verify the tool used by our current Relationship Link Mapping is set to the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). Lastly, we'll need to provide a new Label Mapping to let the 'EAttribute label' feature of our Relationship domain element be represented by our RelationshipLabel.<br />
<br />
Copy/paste your Dependency Link Mapping to create an Include and Extend link mapping, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<br style="clear:both;"/><br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_audit.html here].<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3832Graphical Modeling Framework/Tutorial/Part 22006-04-11T19:53:34Z<p>Rgronback: /* Graphical Definition */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Link Constraints ==<br />
[[Image:link2self.png|frame|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|frame|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: oppositeEnd.oclIsUndefined() or self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
Note: the expression above is different than in previous versions of this tutorial, and is expected to return to just 'self <> oppositeEnd' when a bug in EMFT OCL is fixed.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but it's in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool. Finally, rename the 'mindmap' tool group to 'Nodes'.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|frame|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Add a new child Label to our Polyline Connection DashedLineOpenArrow and name it DashedLineLabelFigure. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineLabelFigure.<br />
<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Includes' and 'Extends' tools. <br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first verify the tool used by our current Relationship Link Mapping is set to the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). <br />
<br />
Copy/paste your Dependency Link Mapping to create an Include and Extend link mapping, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<br style="clear:both;"/><br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_audit.html here].<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3831Graphical Modeling Framework/Tutorial/Part 22006-04-11T19:29:06Z<p>Rgronback: /* Mapping Definition */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Link Constraints ==<br />
[[Image:link2self.png|frame|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|frame|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: oppositeEnd.oclIsUndefined() or self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
Note: the expression above is different than in previous versions of this tutorial, and is expected to return to just 'self <> oppositeEnd' when a bug in EMFT OCL is fixed.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but it's in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool. Finally, rename the 'mindmap' tool group to 'Nodes'.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|frame|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineOpenArrow polyline connection.<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Includes' and 'Extends' tools. <br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first verify the tool used by our current Relationship Link Mapping is set to the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). <br />
<br />
Copy/paste your Dependency Link Mapping to create an Include and Extend link mapping, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<br style="clear:both;"/><br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_audit.html here].<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3830Graphical Modeling Framework/Tutorial/Part 22006-04-11T19:28:43Z<p>Rgronback: /* Link Constraints */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Link Constraints ==<br />
[[Image:link2self.png|frame|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|frame|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: oppositeEnd.oclIsUndefined() or self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
Note: the expression above is different than in previous versions of this tutorial, and is expected to return to just 'self <> oppositeEnd' when a bug in EMFT OCL is fixed.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but it's in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool. Finally, rename the 'mindmap' tool group to 'Nodes'.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineOpenArrow polyline connection.<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Includes' and 'Extends' tools. <br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first verify the tool used by our current Relationship Link Mapping is set to the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). <br />
<br />
Copy/paste your Dependency Link Mapping to create an Include and Extend link mapping, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<br style="clear:both;"/><br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_audit.html here].<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3828Graphical Modeling Framework/Tutorial/Part 22006-04-11T19:19:35Z<p>Rgronback: /* Mapping Definition */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Link Constraints ==<br />
[[Image:link2self.png|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: oppositeEnd.oclIsUndefined() or self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
Note: the expression above is different than in previous versions of this tutorial, and is expected to return to just 'self <> oppositeEnd' when a bug in EMFT OCL is fixed.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but it's in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool. Finally, rename the 'mindmap' tool group to 'Nodes'.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineOpenArrow polyline connection.<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Includes' and 'Extends' tools. <br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first verify the tool used by our current Relationship Link Mapping is set to the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). <br />
<br />
Copy/paste your Dependency Link Mapping to create an Include and Extend link mapping, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<br style="clear:both;"/><br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_audit.html here].<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3827Graphical Modeling Framework/Tutorial/Part 22006-04-11T19:18:48Z<p>Rgronback: /* Mapping Definition */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Link Constraints ==<br />
[[Image:link2self.png|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: oppositeEnd.oclIsUndefined() or self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
Note: the expression above is different than in previous versions of this tutorial, and is expected to return to just 'self <> oppositeEnd' when a bug in EMFT OCL is fixed.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but it's in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool. Finally, rename the 'mindmap' tool group to 'Nodes'.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineOpenArrow polyline connection.<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Includes' and 'Extends' tools. <br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first verify the tool used by our current Relationship Link Mapping is set to the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). <br />
<br />
Copy/paste your Dependency Link Mapping to create Includes and Extends link mappings, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<br style="clear:both;"/><br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_audit.html here].<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3825Graphical Modeling Framework/Tutorial/Part 22006-04-11T19:14:31Z<p>Rgronback: /* Mapping Definition */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Link Constraints ==<br />
[[Image:link2self.png|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: oppositeEnd.oclIsUndefined() or self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
Note: the expression above is different than in previous versions of this tutorial, and is expected to return to just 'self <> oppositeEnd' when a bug in EMFT OCL is fixed.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but it's in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool. Finally, rename the 'mindmap' tool group to 'Nodes'.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineOpenArrow polyline connection.<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Includes' and 'Extends' tools. <br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first verify the tool used by our current Relationship Link Mapping is set to the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). <br />
<br />
Copy/paste your Dependency Link Mapping to create an Include and Extend link mapping, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<br style="clear:both;"/><br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_audit.html here].<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3824Graphical Modeling Framework/Tutorial/Part 22006-04-11T19:05:48Z<p>Rgronback: /* Tooling Definition */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Link Constraints ==<br />
[[Image:link2self.png|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: oppositeEnd.oclIsUndefined() or self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
Note: the expression above is different than in previous versions of this tutorial, and is expected to return to just 'self <> oppositeEnd' when a bug in EMFT OCL is fixed.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but it's in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool. Finally, rename the 'mindmap' tool group to 'Nodes'.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineOpenArrow polyline connection.<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Includes' and 'Extends' tools. <br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first change the tool used by our current Relationship Link Mapping to use the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). <br />
<br />
Copy/paste your Dependency Link Mapping to create an Include and Extend link mapping, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<br style="clear:both;"/><br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_audit.html here].<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3823Graphical Modeling Framework/Tutorial/Part 22006-04-11T18:49:26Z<p>Rgronback: /* Tooling Definition */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Link Constraints ==<br />
[[Image:link2self.png|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: oppositeEnd.oclIsUndefined() or self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
Note: the expression above is different than in previous versions of this tutorial, and is expected to return to just 'self <> oppositeEnd' when a bug in EMFT OCL is fixed.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but it's in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool. Finally, rename the 'mindmap' tool group to 'Nodes'.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineOpenArrow polyline connection.<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Include' and 'Extend' tools. <br />
<br style="clear:both;"/><br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first change the tool used by our current Relationship Link Mapping to use the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). <br />
<br />
Copy/paste your Dependency Link Mapping to create an Include and Extend link mapping, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<br style="clear:both;"/><br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_audit.html here].<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3822Graphical Modeling Framework/Tutorial/Part 22006-04-11T18:48:37Z<p>Rgronback: /* Graphical Definition */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Link Constraints ==<br />
[[Image:link2self.png|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: oppositeEnd.oclIsUndefined() or self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
Note: the expression above is different than in previous versions of this tutorial, and is expected to return to just 'self <> oppositeEnd' when a bug in EMFT OCL is fixed.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but it's in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool. Finally, rename the Mindmap tool group to 'Nodes'.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineOpenArrow polyline connection.<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Include' and 'Extend' tools. <br />
<br style="clear:both;"/><br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first change the tool used by our current Relationship Link Mapping to use the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). <br />
<br />
Copy/paste your Dependency Link Mapping to create an Include and Extend link mapping, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<br style="clear:both;"/><br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_audit.html here].<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3821Graphical Modeling Framework/Tutorial/Part 22006-04-11T18:44:27Z<p>Rgronback: /* Tooling Definition */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Link Constraints ==<br />
[[Image:link2self.png|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: oppositeEnd.oclIsUndefined() or self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
Note: the expression above is different than in previous versions of this tutorial, and is expected to return to just 'self <> oppositeEnd' when a bug in EMFT OCL is fixed.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but it's in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool. Finally, rename the Mindmap tool group to 'Nodes'.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineOpenArrow polyline connection.<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Include' and 'Extend' tools. <br />
<br style="clear:both;"/><br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first change the tool used by our current Relationship Link Mapping to use the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). <br />
<br />
Copy/paste your Dependency Link Mapping to create an Include and Extend link mapping, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<br style="clear:both;"/><br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_audit.html here].<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3817Graphical Modeling Framework/Tutorial/Part 22006-04-11T18:22:25Z<p>Rgronback: /* Constraints */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Link Constraints ==<br />
[[Image:link2self.png|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: oppositeEnd.oclIsUndefined() or self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
Note: the expression above is different than in previous versions of this tutorial, and is expected to return to just 'self <> oppositeEnd' when a bug in EMFT OCL is fixed.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but its in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool.<br />
<br style="clear:both;"/><br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineOpenArrow polyline connection.<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Include' and 'Extend' tools. <br />
<br style="clear:both;"/><br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first change the tool used by our current Relationship Link Mapping to use the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). <br />
<br />
Copy/paste your Dependency Link Mapping to create an Include and Extend link mapping, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<br style="clear:both;"/><br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_audit.html here].<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3814Graphical Modeling Framework/Tutorial/Part 22006-04-11T18:18:55Z<p>Rgronback: /* Constraints */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Constraints ==<br />
[[Image:link2self.png|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: oppositeEnd.oclIsUndefined() or self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
Note: the expression above is different than in previous versions of this tutorial, and is expected to return to just 'self <> oppositeEnd' when a bug in EMFT OCL is fixed.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but its in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool.<br />
<br style="clear:both;"/><br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineOpenArrow polyline connection.<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Include' and 'Extend' tools. <br />
<br style="clear:both;"/><br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first change the tool used by our current Relationship Link Mapping to use the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). <br />
<br />
Copy/paste your Dependency Link Mapping to create an Include and Extend link mapping, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<br style="clear:both;"/><br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_audit.html here].<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor.</div>Rgronbackhttps://wiki.eclipse.org/index.php?title=Graphical_Modeling_Framework/Tutorial/Part_2&diff=3803Graphical Modeling Framework/Tutorial/Part 22006-04-11T16:50:59Z<p>Rgronback: /* Constraints */</p>
<hr />
<div>In this second part of the GMF Tutorial, some of the more advanced capabilities of the generation and runtime frameworks will be explored. Specifically, information on adding compartments, connections, feature initializers, diagram validation, and nested child nodes will be covered. A project containing the full solution set of projects for this segment is found [http://www.eclipse.org/gmf/tutorial/mindmap_tutorial_2.zip here]. Viewlets will be available after appropriate sections below to focus their content and keep them short.<br />
<br />
<br />
== Compartments ==<br />
[[Image:stickynote.png|frame|right]]<br />
Let's add a compartment to our Topic node to allow discussion threads to be added. In order to illustrate how to allow nodes within compartments, we will represent Thread items as yellow sticky notes and allow ThreadItem elements to appear as list items within them. So, we will have nodes with a compartment list nested within a parent node compartment. A preview of where we're going is seen to the right. And yes, it's a bit contrived, but it does give us an opportunity to combine a lot of features in one section.<br />
<br />
Some of the steps in this section are a bit complex, so the [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial2.html viewlet] should prove helpful in getting things right. Of course, in the future an improved user interface will be provided to hide some of the complexities found here, but for now consider it an opportunity to see how things really work ;)<br />
<br style="clear:both;"/><br />
=== Graphical Definition ===<br />
[[Image:rounded_figure.png|frame|right]]<br />
Open up your graphical definition again and let's first take care of giving our Topics a rounded rectangle. Right-click the Figure Gallery and add a new Rounded Rectangle, naming it RoundedTopicFigure. Adjust the Corner Width and Height property values to 20 (or whatever you'd like). To alter the default line color, right-click on the RoundedTopicFigure and add a new Child | Foreground Color RGB Color with R=220, G=220, B=250 (or whatever you'd like).<br />
<br />
We'll reuse the old TopicFigure rectangle for our sticky note. Rename it StickyNoteFigure and give it a Background Color RGB Color child with values R=250, G=250, B=190 (a pale yellow, but feel free to change to suit your taste). Rename its child Label to StickyNoteNameFigure.<br />
<br />
We'll need to create a child Label on our new Rounded Rectangle named TopicNameFigure, as was the case in the original Rectangle. With that, change the Diagram Label TopicNameLabel to use this new TopicNameFigure as its Figure. Then, just change the Figure property on your TopicNode to use this figure and not the Rectangle TopicFigure.<br />
<br />
Create a new Node on the Canvas to use this figure and name it ThreadNode, along with a new Diagram Label named StickyNoteNameLabel on the Canvas that uses the StickyNoteNameFigure.<br />
<br style="clear:both;"/><br />
[[Image:compartment_graph.png|frame|right]]<br />
As we'd like to have discussion threads within a compartment of our topic nodes, we'll need to add one to our Canvas by right-clicking and selecting New Child | Compartment. Give it the name ThreadCompartment and select RoundedTopicFigure for its Figure property.<br />
<br />
We'd also like to give threads their own compartment to contain a list of thread items for the subject. Create another compartment for our ThreadNode named ThreadItemCompartment which will use StickyNoteFigure as its Figure. So, our topics will be rounded rectangles which will contain child rectangles within a compartment. These child rectangles will also have a compartment, but they will not contain rectangles, but rather, just a simple list of discussion threads. These will be represented with a Label.<br />
<br style="clear:both;"/><br />
[[Image:label_graph.png|frame|right]]<br />
Add a new Rectangle and child Label to the Figure Gallery for our thread items named ThreadItemFigure and ThreadItemLabelFigure, respectively. Create a corresponding Node on the Canvas named ThreadItemNode and set its Figure to the ThreadItemFigure. Likewise, add a Diagram Label to the Canvas named ThreadItemLabel and assign the ThreadItemLabelFigure as its Figure property.<br />
<br />
In summary, you should now have three nodes, one connection, two compartments, and three diagram labels as shown in the figure. These correspond to the Rectangles, child Labels, and our Polyline Connection in the Figure Gallery.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Note''' :</font> In the future, graphical definitions will be done using a designer bootstrapped by GMF itself. The figures you have created here will be done visually, rather than by manipulating a model using the generated EMF editor.<br />
</blockquote><br />
<br style="clear:both;"/><br />
<br />
=== Tooling Definition ===<br />
[[Image:thread_tool.png|frame|right]]<br />
We'll need a tool to add Thread nodes and ThreadItems, so open mindmap.gmftool and copy/paste the Topic tool and rename Thread. Repeat for a ThreadItem tool. Next, we'll need to complete our mappings, so reopen your mindmap.gmfmap file.<br />
<br style="clear:both;"/><br />
<br />
=== Mapping Definition ===<br />
<br />
[[Image:compartment_map.png|frame|right]]<br />
First, we'll need to add a new Compartment Mapping to our TopicNode Node Mapping and select ThreadCompartment for its Compartment property. Also, add a Child Reference to the Node Mapping. In the properties, select 'EReference comments' for its Containment Feature and Compartment Mapping <ThreadCompartment> for the Compartment. <br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> There are 2 'EReference comments' listed in the dropdown list of our Containment Feature. The one we want is from the Topic class in the domain model, and it should be the bottom one on the list. Unless you use a later build of GMF, a way to ensure you've selected the correct feature is to open the mapping model in a text editor and verify the correct parent is in the path.<br />
</blockquote><br />
<br />
Right now, the node that represents our topic has a compartment with a reference to the domain element which will contain its contents. The contents of this compartment we have decided will be thread discussions, which are represented by yellow sticky notes. To represent this in our mapping, add a Node Mapping to our Child Reference. In the properties, select our Thread class for the domain Element, our ThreadNode for the Diagram Node, and our Thread creation tool from the palette.<br />
<br />
The last thing we'll need for our child thread node is a mapping to its label. To our ThreadNode mapping, add a child Label Mapping. Select our ThreadNameLabel for the Diagram Label and the 'EAttribute subject' feature from our Thread class for the label's Feature property. Yes, this dialog is another place where it would help to know from which class these attributes come.<br />
[[Image:run_thread_compartment.png|frame|right]]<br />
At this point, you can regenerate the generator model and diagram plugin to see how things look. As you can tell from the image here, discussion threads are now represented as list items in our topic compartment. Let's continue on and map our thread node compartment to display thread items.<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> In the generator model, you will find a property on the compartment that will allow you to show children as nodes and not a list, if you prefer. The property is 'List Layout' and should be set to 'false' in this case.<br />
</blockquote><br />
<br style="clear:both;"/><br />
[[Image:thread_Item_compartment.png|frame|right]]<br />
We will basically repeat the steps above to add a Compartment Mapping for our ThreadItemCompartment. Also, add a Child Reference for our 'EReference items' feature on our Thread class and select ThreadItemCompartment for its Compartment. <br />
<br />
To our Child Reference, add a child Node Mapping for our ThreadItem class with corresponding ThreadItemNode and ThreadItem tool. Finally, add a Label Mapping to the node for our ThreadItemLabel to display the 'EAttribute body' feature of our ThreadItem class.<br />
<br />
At this point, you can regenerate the mindmap.gmfgen model and diagram plugin code. You should be able to run the diagram and produce a diagram similar to the one shown at the beginning of this section.<br />
<br style="clear:both;"/><br />
<br />
== Constraints ==<br />
[[Image:link2self.png|right]]<br />
<br />
Currently, the diagram will allow you to make a subtopic link from one Topic to itself, as seen here. Clearly, this does not make sense for our Mindmap, so we'd like to prevent this somehow. This section makes for a very short [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_constraint.html viewlet].<br />
<br />
<br style="clear:both;"/><br />
[[Image:link_constraint.png|right]]<br />
<br />
Let's return to our mapping definition, and to the 'Link Mapping' we created earlier. To add a constraint, we begin by right-clicking on the 'Link Mapping' and selecting 'New Child > Link Constraints'. To the Link Constraint, right-click and select 'New Child > Source End Constraint'. The 'Language' property defaults to 'ocl' and we'll need to add the following OCL statement to the 'Body' property: self <> oppositeEnd, as seen in the image below. Then, go through the usual regeneration of mindmap.gmfgen and diagram code and try it out. You will no longer be able to make a link from a Topic to itself.<br />
<br />
So, now to explain what is happening here. As you can tell from the context above, we've added a constraint to the creation of a link, based on its source end; that is, the Topic element from which a link is being created. In the OCL we've specified the only condition that will evaluate to true, and therefore allow the link to be created, is the condition where the source element is not equal to the 'oppositeEnd' of the link (the target). In this case, the context of 'self' is the source Topic, and 'oppositeEnd' is a custom variable added to the parser environment for link constraints.<br />
<br />
Clearly, this is a very simple constraint, and one that could very well have been defined in the domain model itself and respected by the graphical editor automatically. We will look more closely at constraints in future versions of this tutorial as support for their use matures.<br />
<br style="clear:both;"/><br />
<br />
== Another Connection ==<br />
[[Image:dependency_link_def.png|frame|right]]<br />
Let's look now at the 'Relationship' element of our domain model. It specifies a number of possible relationships that may be indicated between Topic elements, in addition to the subtopic relationship we have supported thus far. We will add support for this type of Connection, as it will illustrate more completely the properties available for a Link Mapping within GMF. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_relationship.html here].<br />
=== Graphical Definition ===<br />
Returning to our graphical definition model (mindmap.gmfgraph), let's right-click on our gallery and add a 'New Child > Polyline Connection'. Name it 'DashedLineOpenArrow' and change 'Line Kind' to LINE_DASH. Then add a 'New Child > Polyline Decoration' element to the Figure Gallery and name it 'OpenArrow'. Add three Template Point children to the OpenArrow with X:Y values of -1:1, 0:0, and -1:-1. Finally, add the OpenArrow as a Target Decoration to the DashedLineOpenArrow polyline.<br />
<br />
Now that you have the figure defined, create a corresponding Connection on our Canvas named 'RelationshipLink', selecting our 'DashedLineOpenArrow' as its 'Figure'.<br />
=== Tooling Definition ===<br />
We'll need a tool to create these links, so reopen your mindmap.gmftool model. We already have one link tool for subtopics, but its in the same tool group as our node elements. Let's create a new Tool Group under our Palette for links named 'Links' and add to it new Relationship Creation Tool. Copy/paste the TopicSubtopics tool into this new group and name it simply 'Subtopic'. Delete the old TopicSubtopics tool.<br />
<br style="clear:both;"/><br />
=== Mapping Definition ===<br />
[[Image:dependency_link_mapping.png|right]]<br />
In the mapping definition, due to our changes in the tooling model, you'll need to update your tool selection for the Subtopic Link Mapping to our new Subtopic tool. Then, create a new 'Link Mapping' and fill in its properties to match what's displayed in the image.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Be aware of such limitations when working with multiple models, as until there is true refactoring support, you will need to be conscious of changes in definition models and how they will impact 'downstream' models, such as our mapping model. Drag and drop was available to move the existing TopicSubtopics tool to our new Links group, but would have resulted in a need for more cleanup in our mapping model.<br />
</blockquote><br />
<br />
In this mapping, we'll start with the 'Domain meta information > Element' property. It represents the element represented by this link in the domain, which is simply the 'EClass Relationship' element. Recall that in our previous link mapping, we left this and other properties blank. In that case, our target element for the link was represented by an element (Topic) added to a list of reference held in our source element (also a Topic). In this case, the link is represented in the domain by a class of its own, so more information is required in the link mapping. This class, the Relationship class of the domain model, is contained in a list of references in the Map element, which explains the 'Domain meta feature > Containment Feature' map to 'EReference relations'.<br />
<br />
Continuing the mapping description, the 'Target Feature' in this case is mapped to the 'EReference target' domain model element, indicating that targets of the link are added to this list in the domain when the link is created. Similarly, the 'Source Feature' maps to the 'EReference source' domain model element. And of course, we have our straightforward tool mapping and 'Diagram Link' mapping to our RelationshipLink.<br />
<br />
[[Image:dependency_link.png|right]]<br />
<br />
Now, we can regenerate our diagram code as before, launch our diagram workspace and test this new link. Here is an example of the results. <br />
<br />
What we will now need to do is initialize the link to be of the proper type (dependency, includes, extends) when created. We will use separate tools for each, and could also opt to use distinct visualization. For now, we'll simply add a label to the link to indicate its type and maintain the dashed line with open arrow appearance for each.<br />
<br style="clear:both;"/><br />
<br />
== Feature Initializers ==<br />
<br />
When you create a new element on a diagram, there is typically a domain element created or modified as a result. In some cases, it's necessary to provide additional initialization information to ensure that objects are properly created. For example, the links we create between topics in our mindmap diagram come in three flavors: dependency, includes, and extends. The 'type' attribute of the Relationship class is used to hold the RelationshipType enum value for the new instance. <br />
<br />
In our graphical definition, we will create a figure and corresponding link for each type, along with a creation tool for each in our tooling definition. We'll then use a feature sequence initilizer in our mapping definition to properly initialize our domain objects, depending on the type of link created on the diagram.<br />
<br />
Another initialization we will perform is to set the 'label' attribute of the Relationship. As we've indicate above, this will serve to distinguish between the types as our visualization will remain the same for each. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_init.html here]. <br />
=== Graphical Definition ===<br />
First, we need to add a Label to our graphical definition to use in displaying the relationship type. Right-click on the Canvas and add a new Diagram Label named 'RelationshipLabel' with a Figure assigned to our DashedLineOpenArrow polyline connection.<br />
=== Tooling Definition ===<br />
[[Image:tool_links.png|frame|right]]<br />
Return to our tooling model and rename the 'Relationship' tool to 'Dependency'. Copy/paste this tool in order to create additional 'Include' and 'Extend' tools. <br />
<br style="clear:both;"/><br />
=== Mapping Definition ===<br />
Similarly, in the mapping model, first change the tool used by our current Relationship Link Mapping to use the 'Dependency' tool. After we add the initializers, we will copy/paste this Link Mapping and change the properties to be used for includes and extends links. In the end, we will have a single link in our graphical definition being used by 3 tools with corresponding mappings to the same domain element.<br />
<br />
[[Image:feature_init.png|frame|right]]<br />
In the mapping model, below your dependency Link Mapping, create a 'Feature Seq Initializer' element. This will hold subsequent 'Feature Value Spec' elements as seen in the figure. OCL is the language currently supported, so be careful that the body expressions you enter are valid. In the case of initializing the enumeration field, you'll enter 'RelationshipType::DEPENDENCY' to set the 'EAttribute type' feature of our Relationship class. In the case of initilizing the 'EAttribute label' feature, you'll enter the string value 'depend' (within single quotes). <br />
<br />
Copy/paste your Dependency Link Mapping to create an Include and Extend link mapping, changing their properties as necessary (e.g. 'RelationshipType::INCLUDES' and 'RelationshipType::EXTENDS' with corresponding 'includes' and 'extends' body values).<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> Keep in mind that the order of the 'Feature Value Spec' elements will determine the order in which they are executed.<br />
</blockquote><br />
<br style="clear:both;"/><br />
With these steps complete, we can regenerate our mindmap.gmfgen and code. When the diagram code is generated, below is what willl be generated within the Initializers inner class of MindmapElementTypes:<br />
<br />
<pre><br />
public static final ObjectInitializer Relationship_3003 = new ObjectInitializer(<br />
new FeatureInitializer[] {<br />
new FeatureInitializer(<br />
"RelationshipType::DEPENDENCY", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE.getRelationship_Type()),<br />
<br />
new FeatureInitializer(<br />
"'depends'", //$NON-NLS-1$<br />
MindmapPackage.eINSTANCE.getRelationship(),<br />
MindmapPackage.eINSTANCE<br />
.getRelationship_Label())<br />
<br />
});<br />
</pre><br />
<br />
During link creation, the following code is executed in CreateIncomingRelationship3XXXCommand, found in the TopicItemSemanticEditPolicy class:<br />
<br />
<pre><br />
protected EObject doDefaultElementCreation() {<br />
Relationship newElement = (Relationship) super<br />
.doDefaultElementCreation();<br />
if (newElement != null) {<br />
newElement.setTarget((Topic) getTarget());<br />
newElement.setSource((Topic) getSource());<br />
MindmapElementTypes.Initializers.Relationship_3003<br />
.init(newElement);<br />
}<br />
return newElement;<br />
}<br />
</pre><br />
<br />
This generated code within FeatureInitializer will ultimately be called on each value spec you've added, which as you can see constructs an OCL query for evaluation and uses the result to initialize the field you selected.<br />
<br />
<pre><br />
void init(EObject contextInstance) {<br />
if (this.query == null) {<br />
this.query = QueryFactory.eINSTANCE.createQuery(<br />
expressionBody, contextClass);<br />
}<br />
Object value = query.evaluate(contextInstance);<br />
if (sFeature.getEType() instanceof EEnum<br />
&& value instanceof EEnumLiteral) {<br />
value = ((EEnumLiteral) value).getInstance();<br />
} else if (value != null && sFeature.isMany()) {<br />
value = new BasicEList((Collection) value);<br />
}<br />
contextInstance.eSet(sFeature, value);<br />
}<br />
</pre><br />
<br style="clear:both;"/><br />
[[Image:runtime_init.png|frame|right]]<br />
If you launch your runtime instance and test these new initializers, you will find that the type attribute is set according to the Relationship tool selected, and that the label attribute is preset to the names you defined above.<br />
<br style="clear:both;"/><br />
<br />
== Validation ==<br />
<br />
As we saw with the OCL constraint added in the first part of the tutorial, it is possible to restrict connections made between nodes by declaring constraints in our mapping definition. Sometimes, it is more appropriate to validate connections and other aspects of a diagram content using batch or even "live" validation using the Validation framework provided by the [http://www.eclipse.org/emft EMF Technology] project. In this section, we will add such a validation feature to our mindmap in order to alert us of cyclic dependencies that have been created between Topics.<br />
<br />
[[Image:audit_rule.png|frame|right]]<br />
<br />
To begin, open the mapping definition (mindmap.gmfmap) and right-click the Mapping node. Select 'Audit Container' and give it a name (e.g. Mindmap Audits). Assign it an id and description as well. To the container, add a new 'Audit Rule' named 'Cyclic relationship check'. We are going to target the Map class for the audit, so add a child 'Domain Element' to the Audit Rule and select 'EClass Map' as the Element. Add a new child 'Constraint' to the Audit Rule and enter the following for the Body, leaving the Language set to ocl.<br />
<br />
<blockquote><br />
<font color="darkblue">'''Tip''' :</font> When authoring these constraint expressions in OCL, you may find it helpful to contribute an action to open the OCL Interpreter view on instances of your domain model. See the OCL Interpreter Example in the online documentation for more information.<br />
</blockquote><br />
<br />
<br style="clear:both;"/><br />
<br />
<pre>self.relations->forAll(r1, r2 | r1.target = r2.source and r1.type = r2.type <br />
implies r2.target <> r1.source)<br />
</pre><br />
<br />
This will only detect cycles that exist between two directly linked Topic elements, but is sufficient for our purposes here. If someone more OCL-savvy can provide a statement to detect cycles between more than two Topics (if possible), it would be appreciated ;).<br />
<br />
[[Image:validation_extensions.png|frame|right]]<br />
<br />
After reproducing the mindmap.gmfgen model, you will need to set the 'Validation Enabled' property of the Gen Diagram element to 'true' in order for the new audit to be run. Just below that property is one called 'Validation Provider Priority' that you should set to 'Medium' (something higher than 'Lowest'). Do this and regenerate your editor code. After doing so, you will notice some new extensions listed in your editor's plugin.xml file. Primarily, you should notice the constraintProviders and constraintBindings extension-points to which your editor contributes. Examine these and take a closer look at the EMF Validation framework if you wish.<br />
<br />
An improvement here would be to write validations that identify the offensive element to allow for selection via the problems view. Currently, violations result in the canvas itself being selected, as the context is the Map and not a particular Topic or Relationship.<br />
<br />
<br style="clear:both;"/><br />
<br />
[[Image:audit_violation.png|frame|right]]<br />
<br />
To test the new audit, launch your runtime workspace and create a dependency link between two Topic elements. Then, from the Diagram menu, select 'Validate' and observe an error in the Problems view, as shown here. To enable/disable the audit, you can find it now listed in the preferences dialog under 'Validation Constraints'.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Shortcuts ==<br />
<br />
In order to share content between diagrams, and indeed between domain model instances, GMF provides the capability to allow shortcuts to be added to diagrams. In order to enable this functionality, you'll need to locate the 'Shortcuts Provided For' and 'Contains Shortcuts To' properties of the Gen Diagram root of your generator model (e.g. mindmap.gmfgen). In order to allow the shortcutting of Mindmap elements, set both of these properties to 'mindmap' and regenerate your editor. A viewlet of this section can be found [http://www.eclipse.org/gmf/tutorial/viewlets/tutorial_audit.html here].<br />
<br />
[[Image:shortcut_element.png|frame|right]]<br />
<br />
Test the shortcut capability by creating two new Mindmap diagrams and adding elements to each. On one, right-click and select 'Create Shortcut...' to bring up a selection dialog. Browse to the other diagram and select a Topic node to add as a shortcut.<br />
<br />
There is understandably no viewlet for this section.<br />
<br />
<br style="clear:both;"/><br />
<br />
== Summary ==<br />
<br />
In this section of the tutorial, we saw how to add compartments (including nested nodes), links representing classes, feature initializers, constraints, validation, and shortcuts. The next section of the tutorial will dig deeper and focus on altering generated output and manual extension of the editor.</div>Rgronback