Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
Difference between revisions of "Sirius/Tutorials/AdvancedTutorial"
(→Quick Fix) |
(→Validation Rules) |
||
(110 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | = | + | =Overview= |
− | This tutorial | + | This tutorial will guide you extending a basic modeling tool with many advanced features of [http://www.eclipse.org/sirius Eclipse Sirius]: |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | * Edition tools: [[Sirius/Tutorials/AdvancedTutorial#Edge_Creation_Tool |edge creation]], [[Sirius/Tutorials/AdvancedTutorial#Reconnect_Edge_Tool | edge reconnection]], [[Sirius/Tutorials/AdvancedTutorial#Delete_Element_Tool | element deletion]], [[Sirius/Tutorials/AdvancedTutorial#Direct_Edit_Label_Tool | label edition]] | |
+ | * Graphical improvements: [[Sirius/Tutorials/AdvancedTutorial#Style_Customization | styles customization]] | ||
+ | * Complexity management: [[Sirius/Tutorials/AdvancedTutorial#Layers | layers]], [[Sirius/Tutorials/AdvancedTutorial#Filters | filters]],[[Sirius/Tutorials/AdvancedTutorial#Validation_Rules | validation rules]], [[Sirius/Tutorials/AdvancedTutorial#Quick_Fixes | quick fixes]] | ||
+ | * Other kinds of representations: [[Sirius/Tutorials/AdvancedTutorial#Container | containers, bordered nodes]], [[Sirius/Tutorials/AdvancedTutorial#Table | tables]], [[Sirius/Tutorials/AdvancedTutorial#Double-click | navigation between representations]] | ||
+ | * Extensions: [[Sirius/Tutorials/AdvancedTutorial#Java_Services | Java services]] | ||
− | |||
− | The modeling | + | The instructions start from the result of the Sirius [[Sirius/Tutorials/4MinTutorial | Starter Tutorial]], a basic modeling tool which simply allows the user to graphically represent men and women of a family and to create new men. |
[[File:Sirius_4mtuto_01.png]] | [[File:Sirius_4mtuto_01.png]] | ||
− | |||
− | + | The advanced modeling tool that you will create is based on the same simple Domain Model which describes basic concepts about families. | |
− | + | [[File:Sirius_4mtuto_02.png]] | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | [ | + | '''Note:''' The screenshots have been created with [http://www.obeodesigner.com Obeo Designer 10.0] (based on Sirius 5.0). |
− | ===Edge Creation Tool | + | =Install the basic modeling tool= |
+ | |||
+ | If you have followed the [[Sirius/Tutorials/StarterTutorial | Starter Tutorial]] already, you are ready! Directly go to next section: [[#Start_extending_the_basic_modeling_tool |Start extending the basic modeling tool]]. | ||
+ | |||
+ | Otherwise, start by following the instructions to install the sample Domain Model: | ||
+ | * [[Sirius/Tutorials/StarterTutorial#Import_the_projects_containing_the_sample_Domain_Model | Import the projects containing the sample Domain Model]] | ||
+ | * [[Sirius/Tutorials/StarterTutorial#Launch_a_new_runtime_from_your_Eclipse | Launch a new runtime from your Eclipse]] | ||
+ | * [[Sirius/Tutorials/StarterTutorial#Select_the_Sirius_perspective | Select the Sirius perspective]] | ||
+ | * [[Sirius/Tutorials/StarterTutorial#Import_a_sample_model | Import a sample model]] | ||
+ | |||
+ | |||
+ | Now, you should have an Eclipse runtime (started from your first Eclipse) with a sample ''Family'' model installed in your workspace. | ||
+ | |||
+ | [[File:sirius_4mtuto_05-2.png]] | ||
+ | |||
+ | |||
+ | Then, install the solution of the ''Starter Tutorial''. It is implemented by a ''Viewpoint Specification Project'' that you need to import into your workspace. | ||
+ | |||
+ | This project can be easily installed from the provided examples (menu '''File > New > Example...''' : select '''Basic Family Modeler Definition - Starter Tutorial Solution'''). | ||
+ | |||
+ | [[File:Sirius_4mtuto_52.png]] | ||
+ | |||
+ | |||
+ | Once the modeler imported in your workspace, activate the ''persons'' viewpoint by selecting the menu '''Viewpoint Selection'''. | ||
+ | |||
+ | [[File:sirius_4mtuto_27.png]] | ||
+ | |||
+ | |||
+ | You must activate the ''persons'' viewpoint to be able to create the representations which are defined by this viewpoint. | ||
+ | |||
+ | [[File:sirius_4mtuto_28.png]] | ||
+ | |||
+ | |||
+ | Then right-click on the sample model and select the menu '''New Representation / new Persons diagram'''. | ||
+ | |||
+ | [[File:sirius_4mtuto_29.png]] | ||
+ | |||
+ | |||
+ | Sirius should create and open a diagram describing the men and women contained in the sample model. | ||
+ | |||
+ | [[File:sirius_4mtuto_01.png]] | ||
+ | |||
+ | =Start extending the basic modeling tool= | ||
+ | |||
+ | '''Note''': the solution of the following steps can be installed directly from the samples | ||
+ | |||
+ | [[File:sirius_tuto2_03.png]] | ||
+ | |||
+ | |||
+ | ==Edge Creation Tool== | ||
An ''Edge Creation'' tool allows the user to create relationships directly from the diagram, by using the palette. | An ''Edge Creation'' tool allows the user to create relationships directly from the diagram, by using the palette. | ||
Line 48: | Line 80: | ||
[[File:sirius_tuto2_04-01.png]] | [[File:sirius_tuto2_04-01.png]] | ||
+ | |||
Give an Id to this tool (<code>setFather</code>) and associate it to ''fatherEdge'', the ''Edge Mapping'' which defines the ''father'' graphical relation. | Give an Id to this tool (<code>setFather</code>) and associate it to ''fatherEdge'', the ''Edge Mapping'' which defines the ''father'' graphical relation. | ||
[[File:sirius_tuto2_04-02.png]] | [[File:sirius_tuto2_04-02.png]] | ||
+ | |||
+ | |||
+ | Set the icon that will appear in the palette (if you don't specify an icon here, Sirius will use a default one): | ||
+ | |||
+ | [[File:sirius_tuto2_04-02-02.png]] | ||
+ | |||
Then define the operations that will be performed by this tool each time the user will click on it. These operations can use four variables that are automatically set by Sirius: | Then define the operations that will be performed by this tool each time the user will click on it. These operations can use four variables that are automatically set by Sirius: | ||
Line 59: | Line 98: | ||
* '''targetView''': the graphical object representing the target | * '''targetView''': the graphical object representing the target | ||
− | Under the ''Begin'' object, create a ''Change Context'' | + | |
+ | Under the ''Begin'' object, create a ''Change Context''. | ||
[[File:sirius_tuto2_04-03.png]] | [[File:sirius_tuto2_04-03.png]] | ||
+ | |||
+ | |||
+ | Set its ''Browse Expression'' to <code>var:source</code> in order to define the execution context of the next operations. | ||
[[File:sirius_tuto2_04-04.png]] | [[File:sirius_tuto2_04-04.png]] | ||
− | Under the ''Change Context'' create a ''Set'' | + | |
− | + | Under the ''Change Context'' create a ''Set''. | |
− | + | ||
[[File:sirius_tuto2_04-05.png]] | [[File:sirius_tuto2_04-05.png]] | ||
+ | |||
+ | |||
+ | It will set the ''father'' of the first Person clicked (source) to the second Person clicked (target): | ||
+ | * '''Feature Name''': <code>father</code> | ||
+ | * '''Value Expression''': <code>var:target</code> | ||
[[File:sirius_tuto2_04-06.png]] | [[File:sirius_tuto2_04-06.png]] | ||
+ | |||
Save the ''odesign'' file and you will see a new tool ''setFather'' in the palette. | Save the ''odesign'' file and you will see a new tool ''setFather'' in the palette. | ||
Line 77: | Line 125: | ||
[[File:sirius_tuto2_04-07.png]] | [[File:sirius_tuto2_04-07.png]] | ||
− | + | == Precondition== | |
− | To prevent the user to create a ''father'' relationship from a person to itself, or to one of its children, you can add | + | To prevent the user to create a ''father'' relationship from a person to itself, or to one of its children, you can add the precondition expression <code>aql:preTarget.differs(preSource) and preSource.oclAsType(basicfamily::Person).children->excludes(preTarget)</code> (written in AQL). |
[[File:sirius_tuto2_04-08.png]] | [[File:sirius_tuto2_04-08.png]] | ||
Line 86: | Line 134: | ||
* '''preSource''': the object on which the user has clicked first | * '''preSource''': the object on which the user has clicked first | ||
* '''preTarget''': the object under the cursor | * '''preTarget''': the object under the cursor | ||
+ | |||
With this precondition, the tool will prevent the creation of forbidden links by showing a specific icon. | With this precondition, the tool will prevent the creation of forbidden links by showing a specific icon. | ||
Line 91: | Line 140: | ||
[[File:sirius_tuto2_04-09.png]] | [[File:sirius_tuto2_04-09.png]] | ||
− | |||
− | + | Now copy, paste and update the ''setFather'' tool to create the ''setMother'' tool. | |
+ | |||
+ | ==Reconnect Edge Tool== | ||
A ''Reconnect Edge'' tool allows the user to change the end of a relationship by moving it directly from the diagram. | A ''Reconnect Edge'' tool allows the user to change the end of a relationship by moving it directly from the diagram. | ||
Let's create a ''Reconnect Edge'' tool to change the ''father'' and the ''mother'' of a Person. | Let's create a ''Reconnect Edge'' tool to change the ''father'' and the ''mother'' of a Person. | ||
+ | |||
Right click on the ''Section'' and select the menu '''New Element Edition > Reconnect Edge''' | Right click on the ''Section'' and select the menu '''New Element Edition > Reconnect Edge''' | ||
[[File:sirius_tuto2_05-01.png]] | [[File:sirius_tuto2_05-01.png]] | ||
+ | |||
Associate the ''fatherEdge'' to this reconnect tool. | Associate the ''fatherEdge'' to this reconnect tool. | ||
[[File:sirius_tuto2_05-02.png]] | [[File:sirius_tuto2_05-02.png]] | ||
+ | |||
This tool comes with six variables: | This tool comes with six variables: | ||
Line 114: | Line 167: | ||
* '''element''': the object attached to the other end | * '''element''': the object attached to the other end | ||
* '''elementView''': the graphical object representing element | * '''elementView''': the graphical object representing element | ||
+ | |||
Then create a ''Change Context'' and set its expression to <code>var:element</code> (the person who will change his father) | Then create a ''Change Context'' and set its expression to <code>var:element</code> (the person who will change his father) | ||
Line 120: | Line 174: | ||
[[File:sirius_tuto2_05-03.png]] | [[File:sirius_tuto2_05-03.png]] | ||
+ | |||
Copy, paste and update this tool to create a reconnect tool for ''mother'' relationship. | Copy, paste and update this tool to create a reconnect tool for ''mother'' relationship. | ||
− | + | ==Delete Element Tool== | |
A ''Delete Element'' tool specifies which actions have to be performed when the user hits the ''delete'' key on an diagram element. | A ''Delete Element'' tool specifies which actions have to be performed when the user hits the ''delete'' key on an diagram element. | ||
Line 130: | Line 185: | ||
Let's create a ''Delete Element'' tool to specify what to do when the user deletes a paretal relation. | Let's create a ''Delete Element'' tool to specify what to do when the user deletes a paretal relation. | ||
+ | |||
Right click on the ''Section'' and select the menu '''New Element Edition > Delete Element''' | Right click on the ''Section'' and select the menu '''New Element Edition > Delete Element''' | ||
[[File:sirius_tuto2_06-01.png]] | [[File:sirius_tuto2_06-01.png]] | ||
+ | |||
Associate the ''fatherEdge'' to this Delete tool. | Associate the ''fatherEdge'' to this Delete tool. | ||
[[File:sirius_tuto2_06-02.png]] | [[File:sirius_tuto2_06-02.png]] | ||
+ | |||
When deleting an edge, the variable '''element''' refers to the source of the relationship. | When deleting an edge, the variable '''element''' refers to the source of the relationship. | ||
Line 144: | Line 202: | ||
[[File:sirius_tuto2_06-03.png]] | [[File:sirius_tuto2_06-03.png]] | ||
+ | |||
Copy, paste and update this tool to create a ''delete tool'' for ''mother'' relationship. | Copy, paste and update this tool to create a ''delete tool'' for ''mother'' relationship. | ||
− | + | ==Direct Edit Label Tool== | |
A ''Direct Edit Label'' specifies how to interpret the modification of graphical object's label in order to modify the model. | A ''Direct Edit Label'' specifies how to interpret the modification of graphical object's label in order to modify the model. | ||
Let's create a ''Direct Edit Label'' to change the name of a Person directly from the diagram. | Let's create a ''Direct Edit Label'' to change the name of a Person directly from the diagram. | ||
+ | |||
Right click on the ''Section'' and select the menu '''New Element Edition > Direct Edit Label''' | Right click on the ''Section'' and select the menu '''New Element Edition > Direct Edit Label''' | ||
[[File:sirius_tuto2_07-01.png]] | [[File:sirius_tuto2_07-01.png]] | ||
+ | |||
Associate this tool to the objects which have a name: ''ManNode'' and ''WomanNode'' | Associate this tool to the objects which have a name: ''ManNode'' and ''WomanNode'' | ||
[[File:sirius_tuto2_07-02.png]] | [[File:sirius_tuto2_07-02.png]] | ||
+ | |||
This tool comes with a mask that creates variables depending on the label's value. By default, the mask is set to <code>{0}</code>, which means that the variable named ''0'' will contain the full value of the label. | This tool comes with a mask that creates variables depending on the label's value. By default, the mask is set to <code>{0}</code>, which means that the variable named ''0'' will contain the full value of the label. | ||
+ | |||
Create a ''Set'' to indicate the feature of the edited object that will be modified (<code>name</code>) and the value to assign (<code>var:0</code>). | Create a ''Set'' to indicate the feature of the edited object that will be modified (<code>name</code>) and the value to assign (<code>var:0</code>). | ||
Line 167: | Line 230: | ||
[[File:sirius_tuto2_07-03.png]] | [[File:sirius_tuto2_07-03.png]] | ||
− | + | ==Style Customization== | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
Style Customizations change graphical properties of diagram elements (color, label, size, ...) depending on conditions. | Style Customizations change graphical properties of diagram elements (color, label, size, ...) depending on conditions. | ||
Line 199: | Line 238: | ||
* Person having more than one children => set label size to 12 | * Person having more than one children => set label size to 12 | ||
* Person having grandchildren => prefix label with ''Grandpa'' or ''Grandma'' | * Person having grandchildren => prefix label with ''Grandpa'' or ''Grandma'' | ||
+ | |||
Right click on the ''Default Layer'' and select the menu '''New Customization > Style Customizations'''. It will group all the different customizations. | Right click on the ''Default Layer'' and select the menu '''New Customization > Style Customizations'''. It will group all the different customizations. | ||
[[File:sirius_tuto2_09-01.png]] | [[File:sirius_tuto2_09-01.png]] | ||
+ | |||
Right click on the ''Style Customizations'' and select the menu '''New Customization > Style Customization''' to create the first customization. | Right click on the ''Style Customizations'' and select the menu '''New Customization > Style Customization''' to create the first customization. | ||
Line 208: | Line 249: | ||
[[File:sirius_tuto2_09-02.png]] | [[File:sirius_tuto2_09-02.png]] | ||
− | Enter the | + | |
+ | Enter the AQL expression associated to this customization: <code>aql:self.oclAsType(basicfamily::Person).children->size()=0</code> | ||
Then define the graphical properties that will change if the condition is met. | Then define the graphical properties that will change if the condition is met. | ||
+ | |||
Right click on the ''Style Customization'' and select the menu '''New Customization'''. To change the label color, create a ''Property Customization (by selection)''. | Right click on the ''Style Customization'' and select the menu '''New Customization'''. To change the label color, create a ''Property Customization (by selection)''. | ||
[[File:sirius_tuto2_09-03.png]] | [[File:sirius_tuto2_09-03.png]] | ||
+ | |||
On this ''Property Customization'', select the two Workspace Images for the ''Applied On'' field (they hold the label to change), enter ''labelColor'' in the Property Name field, then select the ''gray'' color. | On this ''Property Customization'', select the two Workspace Images for the ''Applied On'' field (they hold the label to change), enter ''labelColor'' in the Property Name field, then select the ''gray'' color. | ||
Line 222: | Line 266: | ||
[[File:sirius_tuto2_09-04.png]] | [[File:sirius_tuto2_09-04.png]] | ||
− | Create a second ''Style Customizations'' with the condition: <code> | + | |
+ | Create a second ''Style Customizations'' with the condition: <code>aql:self.oclAsType(basicfamily::Person).children->size()>1</code> | ||
and add a ''Style Customization (by expression)'' to set the ''labelSize'' to <code>12</code>. | and add a ''Style Customization (by expression)'' to set the ''labelSize'' to <code>12</code>. | ||
[[File:sirius_tuto2_09-05.png]] | [[File:sirius_tuto2_09-05.png]] | ||
− | |||
− | Add a ''Style Customization (by expression)'' for the ''Workspace Image'' corresponding to the Man, enter the property name ''labelExpression'' and the expression <code> | + | Finally, create a third ''Style Customizations'' with the condition: <code>aql:self.oclAsType(basicfamily::Person).children.children->size()>0</code> |
+ | |||
+ | Add a ''Style Customization (by expression)'' for the ''Workspace Image'' corresponding to the Man, enter the property name ''labelExpression'' and the expression <code>aql:'Grandpa '+self.oclAsType(basicfamily::Person).name</code> (to prefix the person name with ''Grandpa''). | ||
[[File:sirius_tuto2_09-06.png]] | [[File:sirius_tuto2_09-06.png]] | ||
− | Do the same with the ''Woman'' image and the expression <code> | + | |
+ | Do the same with the ''Woman'' image and the expression <code>aql:'Grandma '+self.oclAsType(basicfamily::Person).name</code>. | ||
+ | |||
Save the ''odesign'' file and see the result on the diagram. | Save the ''odesign'' file and see the result on the diagram. | ||
Line 239: | Line 287: | ||
[[File:sirius_tuto2_09-07.png]] | [[File:sirius_tuto2_09-07.png]] | ||
− | + | ==Layers== | |
With Sirius it is possible to allocate specific graphical elements to layers that can be activated/deactivated on demand by the user. | With Sirius it is possible to allocate specific graphical elements to layers that can be activated/deactivated on demand by the user. | ||
Let's create two layers: one for the Men and one for the Women. | Let's create two layers: one for the Men and one for the Women. | ||
+ | |||
Right click on ''Persons diagram'' and select the menu '''New Diagram Element > Additional Layer'''. | Right click on ''Persons diagram'' and select the menu '''New Diagram Element > Additional Layer'''. | ||
[[File:sirius_tuto2_10-03.png]] | [[File:sirius_tuto2_10-03.png]] | ||
+ | |||
Call this ''Layer'' <code>Men</code> and check the option ''Active by default''. | Call this ''Layer'' <code>Men</code> and check the option ''Active by default''. | ||
[[File:sirius_tuto2_10-02.png]] | [[File:sirius_tuto2_10-02.png]] | ||
+ | |||
Create a ''Section'' in this layer then drag and drop all the elements related to the ''Man'' type into this layer. | Create a ''Section'' in this layer then drag and drop all the elements related to the ''Man'' type into this layer. | ||
[[File:sirius_tuto2_10-01.png]] | [[File:sirius_tuto2_10-01.png]] | ||
+ | |||
Create a second ''Layer'' <code>Women</code> and drag and drop all the elements related to the ''Woman'' type. | Create a second ''Layer'' <code>Women</code> and drag and drop all the elements related to the ''Woman'' type. | ||
+ | |||
Re-open the sample diagram. You can see the two optional layers Men and Women (selected by default). | Re-open the sample diagram. You can see the two optional layers Men and Women (selected by default). | ||
[[File:sirius_tuto2_10-04.png]] | [[File:sirius_tuto2_10-04.png]] | ||
+ | |||
If you de-activate the ''Men'' layer, only women remain on the diagram. Note that the tools related to men have been hidden too. | If you de-activate the ''Men'' layer, only women remain on the diagram. Note that the tools related to men have been hidden too. | ||
Line 267: | Line 321: | ||
[[File:sirius_tuto2_10-05.png]] | [[File:sirius_tuto2_10-05.png]] | ||
− | + | ==Filters== | |
With ''Filters'', Sirius provides an additional mechanism to automatically show or hide elements of a diagram: a condition determines which elements remain visible. | With ''Filters'', Sirius provides an additional mechanism to automatically show or hide elements of a diagram: a condition determines which elements remain visible. | ||
Let's create a ''Filter'' to hide persons without children. | Let's create a ''Filter'' to hide persons without children. | ||
+ | |||
Right click on ''Persons diagram'' and select the menu '''New Filter > Composite Filter'''. | Right click on ''Persons diagram'' and select the menu '''New Filter > Composite Filter'''. | ||
[[File:sirius_tuto2_11-01.png]] | [[File:sirius_tuto2_11-01.png]] | ||
+ | |||
Set the ''id'' to <code>childrenFilter</code>. | Set the ''id'' to <code>childrenFilter</code>. | ||
+ | |||
Then create a ''Mapping Filter''. | Then create a ''Mapping Filter''. | ||
Line 283: | Line 340: | ||
[[File:sirius_tuto2_11-02.png]] | [[File:sirius_tuto2_11-02.png]] | ||
− | Associate ''ManNode'' and ''WomanNode'' to this filter and define the ''Semantic Condition Expression'' : <code> | + | |
+ | Associate ''ManNode'' and ''WomanNode'' to this filter and define the ''Semantic Condition Expression'' : <code>aql:self.children->size()>0</code> | ||
[[File:sirius_tuto2_11-03.png]] | [[File:sirius_tuto2_11-03.png]] | ||
+ | |||
On the diagram, you can now select the filter ''childrenFilter'' and see that only persons with children remain visible. | On the diagram, you can now select the filter ''childrenFilter'' and see that only persons with children remain visible. | ||
Line 291: | Line 350: | ||
[[File:sirius_tuto2_11-04.png]] | [[File:sirius_tuto2_11-04.png]] | ||
− | + | ==Validation Rules== | |
Validation rules allow the user to evaluate the quality of a model. | Validation rules allow the user to evaluate the quality of a model. | ||
− | For example, despite the precondition | + | For example, despite the precondition existing on the ''Eddge Creation'' tool, users can still create circular parental relations between two persons by using the ''Properties View'': |
+ | * select a person with at least one child | ||
+ | * use the ''Parents'' widget in the ''Properties View'' to add one of the children as a parent | ||
+ | |||
Let's create a ''Validation Rule'' to detect this problem. | Let's create a ''Validation Rule'' to detect this problem. | ||
+ | |||
Right click on ''Persons diagram'' and select the menu '''New Validation > Validation'''. | Right click on ''Persons diagram'' and select the menu '''New Validation > Validation'''. | ||
Line 303: | Line 366: | ||
[[File:sirius_tuto2_12-01.png]] | [[File:sirius_tuto2_12-01.png]] | ||
− | Set the name | + | |
+ | Set the name <code>FamilyValidation</code> to this ''Validation''. Then create a ''Semantic Validation Rule''. | ||
[[File:sirius_tuto2_12-02.png]] | [[File:sirius_tuto2_12-02.png]] | ||
+ | |||
Set the properties of this rule: | Set the properties of this rule: | ||
* '''Level''': <code>Error</code> | * '''Level''': <code>Error</code> | ||
− | * '''Target Class''': <code>basicfamily | + | * '''Target Class''': <code>basicfamily::Person</code> |
− | * '''Message''': <code> | + | * '''Message''': <code>aql:self.oclAsType(basicfamily::Person).father.name+' should not be both the child and the father of '+self.oclAsType(basicfamily::Person).name</code> |
+ | |||
[[File:sirius_tuto2_12-03.png]] | [[File:sirius_tuto2_12-03.png]] | ||
− | Then create an ''Audit'' (a condition corresponding to this rule) with the expression <code> | + | |
+ | Then create an ''Audit'' (a condition corresponding to this rule) with the expression <code>aql:self.children->excludes(self.father)</code>. | ||
[[File:sirius_tuto2_12-04.png]] | [[File:sirius_tuto2_12-04.png]] | ||
− | To test this rule, introduce an error in the model with the ''Property View'': | + | |
+ | To test this rule, introduce an error in the model with the ''Property View'': add the father of a person into the list of his children. | ||
[[File:sirius_tuto2_12-05.png]] | [[File:sirius_tuto2_12-05.png]] | ||
+ | |||
Then right-click on the diagram and select the menu '''Validate diagram'''. | Then right-click on the diagram and select the menu '''Validate diagram'''. | ||
[[File:sirius_tuto2_12-06.png]] | [[File:sirius_tuto2_12-06.png]] | ||
+ | |||
The circular father relationship is detected and a decorator (corresponding to the rule level) is displayed on the persons with this problem. A tootip contains the error message. | The circular father relationship is detected and a decorator (corresponding to the rule level) is displayed on the persons with this problem. A tootip contains the error message. | ||
Line 330: | Line 400: | ||
[[File:sirius_tuto2_12-07.png]] | [[File:sirius_tuto2_12-07.png]] | ||
− | + | ==Quick Fixes== | |
''Fixes'' can be provided to the user for solving the problem automatically. | ''Fixes'' can be provided to the user for solving the problem automatically. | ||
For example, we can propose to unset one of the two ''father'' relations. | For example, we can propose to unset one of the two ''father'' relations. | ||
+ | |||
Right-click on the ''Rule'' and select the menu '''New > Fix'''. | Right-click on the ''Rule'' and select the menu '''New > Fix'''. | ||
[[File:sirius_tuto2_13-01.png]] | [[File:sirius_tuto2_13-01.png]] | ||
+ | |||
Set the ''name'' <code>Unset father</code> to this ''Fix'' and create a ''Begin''. Then create a ''Unset'' and enter <code>father</code> in the ''Feature name''. | Set the ''name'' <code>Unset father</code> to this ''Fix'' and create a ''Begin''. Then create a ''Unset'' and enter <code>father</code> in the ''Feature name''. | ||
[[File:sirius_tuto2_13-02.png]] | [[File:sirius_tuto2_13-02.png]] | ||
+ | |||
If you open the ''Problems View'', you can right-click on one of the errors and select the menu '''Quick Fix'''. | If you open the ''Problems View'', you can right-click on one of the errors and select the menu '''Quick Fix'''. | ||
[[File:sirius_tuto2_13-03.png]] | [[File:sirius_tuto2_13-03.png]] | ||
+ | |||
A dialog opens which proposes the available fixes. | A dialog opens which proposes the available fixes. | ||
[[File:sirius_tuto2_13-04.png]] | [[File:sirius_tuto2_13-04.png]] | ||
+ | |||
Select ''Unset father'' and click on ''Finish'': the father of the selected person is automatically unset and the problem is solved. | Select ''Unset father'' and click on ''Finish'': the father of the selected person is automatically unset and the problem is solved. | ||
Line 356: | Line 431: | ||
[[File:sirius_tuto2_13-05.png]] | [[File:sirius_tuto2_13-05.png]] | ||
− | + | == Object-Centered Diagram== | |
The ''Persons diagram'' is a representation related to the whole model: it displays all the members of the family. This is the reason why it belongs to the ''Family'' instance, as you can see in the ''Model Explorer''. | The ''Persons diagram'' is a representation related to the whole model: it displays all the members of the family. This is the reason why it belongs to the ''Family'' instance, as you can see in the ''Model Explorer''. | ||
[[File:sirius_tuto2_14-01.png]] | [[File:sirius_tuto2_14-01.png]] | ||
+ | |||
With Sirius, you can create a representation on any instance of the model. For example, let's create a person-centered diagram to show only the relationships of a given person. | With Sirius, you can create a representation on any instance of the model. For example, let's create a person-centered diagram to show only the relationships of a given person. | ||
+ | |||
Right-click on the ''persons'' viewpoint and select the menu '''New Representation > Diagram Description'''. | Right-click on the ''persons'' viewpoint and select the menu '''New Representation > Diagram Description'''. | ||
Line 368: | Line 445: | ||
[[File:sirius_tuto2_14-02.png]] | [[File:sirius_tuto2_14-02.png]] | ||
− | + | ||
− | * ''' | + | Associate the ''basicfamily'' metamodel to this diagram (see [[Sirius/Tutorials/4MinTutorial#Define_a_Diagram | Starter Tutorial]]) then set these properties: |
− | * '''Domain Class''': <code>basicfamily | + | * '''Id''': <code>Relationships diagram</code> |
+ | * '''Domain Class''': <code>basicfamily::Person</code> | ||
+ | |||
[[File:sirius_tuto2_14-03.png]] | [[File:sirius_tuto2_14-03.png]] | ||
− | In the ''Advanced'' tab, set the '''Title Expression''' to <code> | + | |
+ | In the ''Advanced'' tab, set the '''Title Expression''' to <code>aql:'Relations of '+self.name</code> in order to customize the name of the diagram with the person's name. | ||
[[File:sirius_tuto2_14-04.png]] | [[File:sirius_tuto2_14-04.png]] | ||
− | + | ||
+ | Save the ''odesign'' file. Now, you can right click on a person in the ''Model Explorer'' and create a new representation of type ''Relationships diagram''. | ||
[[File:sirius_tuto2_14-05.png]] | [[File:sirius_tuto2_14-05.png]] | ||
+ | |||
The result is a blank diagram, since we have not yet specified its content. | The result is a blank diagram, since we have not yet specified its content. | ||
− | + | [[File:sirius_tuto2_14-06.png]] | |
+ | |||
+ | |||
+ | ===Container=== | ||
A ''Container'' is a kind of diagram element that can contain other diagram elements. | A ''Container'' is a kind of diagram element that can contain other diagram elements. | ||
Line 394: | Line 479: | ||
* The siblings of the current person: | * The siblings of the current person: | ||
** each sibling in a list | ** each sibling in a list | ||
+ | |||
Right-click on the ''Layer'' and select the menu '''New Diagram Element > Container'''. | Right-click on the ''Layer'' and select the menu '''New Diagram Element > Container'''. | ||
[[File:sirius_tuto2_15-01.png]] | [[File:sirius_tuto2_15-01.png]] | ||
+ | |||
For this first container, set these properties: | For this first container, set these properties: | ||
− | * ''' | + | * '''Id''': <code>PersonContainer</code> |
− | * '''Domain Class''': <code>basicfamily | + | * '''Domain Class''': <code>basicfamily::Person</code> |
* '''Semantic Candidate Expression''': <code>var:self</code> (the current person) | * '''Semantic Candidate Expression''': <code>var:self</code> (the current person) | ||
* '''Children Presentation''': <code>List</code> | * '''Children Presentation''': <code>List</code> | ||
+ | |||
[[File:sirius_tuto2_15-02.png]] | [[File:sirius_tuto2_15-02.png]] | ||
+ | |||
To define the graphical rendering of this container, right-click on it and select the menu '''New Style > Gradient'''. | To define the graphical rendering of this container, right-click on it and select the menu '''New Style > Gradient'''. | ||
[[File:sirius_tuto2_15-03.png]] | [[File:sirius_tuto2_15-03.png]] | ||
+ | |||
On this style, set these properties: | On this style, set these properties: | ||
Line 415: | Line 505: | ||
** '''Label Size''': <code>12</code> | ** '''Label Size''': <code>12</code> | ||
** '''Label Format''': <code>bold</code> | ** '''Label Format''': <code>bold</code> | ||
+ | |||
[[File:sirius_tuto2_15-04.png]] | [[File:sirius_tuto2_15-04.png]] | ||
+ | |||
* ''Color'' Tab: | * ''Color'' Tab: | ||
** '''Foreground Color''': <code>light_green</code> | ** '''Foreground Color''': <code>light_green</code> | ||
+ | |||
[[File:sirius_tuto2_15-05.png]] | [[File:sirius_tuto2_15-05.png]] | ||
+ | |||
Save the ''odesign'' file and you see a green container appear on the diagram that you have created for a person. | Save the ''odesign'' file and you see a green container appear on the diagram that you have created for a person. | ||
Line 427: | Line 521: | ||
[[File:sirius_tuto2_15-06.png]] | [[File:sirius_tuto2_15-06.png]] | ||
− | + | === Sub Nodes=== | |
Now, to display children inside this container, right-click on the container definition and click on the menu '''New Diagram Element > Sub Node'''. | Now, to display children inside this container, right-click on the container definition and click on the menu '''New Diagram Element > Sub Node'''. | ||
[[File:sirius_tuto2_16-01.png]] | [[File:sirius_tuto2_16-01.png]] | ||
+ | |||
On the ''Sub Node'' set these properties: | On the ''Sub Node'' set these properties: | ||
* '''Id''': <code>ChildrenNode</code> | * '''Id''': <code>ChildrenNode</code> | ||
− | * '''Domain Class''': <code>basicfamily | + | * '''Domain Class''': <code>basicfamily::Person</code> |
* '''Semantic Candidate Expression''': <code>feature:children</code> | * '''Semantic Candidate Expression''': <code>feature:children</code> | ||
+ | |||
[[File:sirius_tuto2_16-02.png]] | [[File:sirius_tuto2_16-02.png]] | ||
+ | |||
Then create a style. Note that the kind of style is not important here: for elements in a list, the style is used only to specify the label. | Then create a style. Note that the kind of style is not important here: for elements in a list, the style is used only to specify the label. | ||
[[File:sirius_tuto2_16-03.png]] | [[File:sirius_tuto2_16-03.png]] | ||
+ | |||
Save the ''odesign'' file, and now you can see the children listed inside the container. | Save the ''odesign'' file, and now you can see the children listed inside the container. | ||
Line 448: | Line 546: | ||
[[File:sirius_tuto2_16-04.png]] | [[File:sirius_tuto2_16-04.png]] | ||
− | Copy paste ''PersonContainer'' to create | + | |
+ | Copy paste ''PersonContainer'' to create another container for siblings. | ||
+ | |||
Change these properties on this new container description: | Change these properties on this new container description: | ||
− | * Container > '''Name''': <code> | + | * Container > '''Name''': <code>SiblingContainer</code> |
* Gradient > '''Label Size''': <code>10</code> | * Gradient > '''Label Size''': <code>10</code> | ||
* Gradient > '''Label Expression''': <code>Siblings</code> | * Gradient > '''Label Expression''': <code>Siblings</code> | ||
Line 458: | Line 558: | ||
And these properties on the ''Sub Node'': | And these properties on the ''Sub Node'': | ||
* '''Id''': <code>Sibling Node</code> | * '''Id''': <code>Sibling Node</code> | ||
− | * '''Semantic Candidates Expression''': <code> | + | * '''Semantic Candidates Expression''': <code>aql:self.parents.children->excluding(self)</code> |
+ | |||
[[File:sirius_tuto2_16-05.png]] | [[File:sirius_tuto2_16-05.png]] | ||
+ | |||
Save the ''odesign'' file, and now you can see the siblings listed inside a second container. | Save the ''odesign'' file, and now you can see the siblings listed inside a second container. | ||
Line 466: | Line 568: | ||
[[File:sirius_tuto2_16-06.png]] | [[File:sirius_tuto2_16-06.png]] | ||
− | + | === Border Node=== | |
Now let's add ''Border Nodes'' to the first container to display the parents of the current person. | Now let's add ''Border Nodes'' to the first container to display the parents of the current person. | ||
+ | |||
Right-click on ''PersonContainer'' and select the menu '''New Diagram Element > Border Node''': | Right-click on ''PersonContainer'' and select the menu '''New Diagram Element > Border Node''': | ||
[[File:sirius_tuto2_17-01.png]] | [[File:sirius_tuto2_17-01.png]] | ||
+ | |||
Set these properties to the border node: | Set these properties to the border node: | ||
* '''Id''': <code>ParentNode</code> | * '''Id''': <code>ParentNode</code> | ||
− | * '''Domain Class''': <code>basicfamily | + | * '''Domain Class''': <code>basicfamily::Person</code> |
* '''Semantic Candidate Expression''': <code>feature:parents</code> | * '''Semantic Candidate Expression''': <code>feature:parents</code> | ||
+ | |||
[[File:sirius_tuto2_17-02.png]] | [[File:sirius_tuto2_17-02.png]] | ||
− | |||
− | |||
− | |||
− | Save the ''odesign'' file | + | Add a ''square'' as style with a ''White'' color. |
+ | |||
+ | Save the ''odesign'' file and now, after manual resizing, you should see the parents attached on the border of the first container : | ||
[[File:sirius_tuto2_17-03.png]] | [[File:sirius_tuto2_17-03.png]] | ||
− | + | === Edge between containers=== | |
Like nodes, ''Containers'' can be linked with ''Edges''. | Like nodes, ''Containers'' can be linked with ''Edges''. | ||
− | Right-click on the ''Default'' | + | |
+ | Right-click on the ''Default'' layer and select the menu '''New Diagram Element > Relation Based Edge'''. | ||
[[File:sirius_tuto2_18-01.png]] | [[File:sirius_tuto2_18-01.png]] | ||
+ | |||
Set these properties to the edge: | Set these properties to the edge: | ||
Line 503: | Line 609: | ||
* '''Target Mapping''': <code>SiblingsContainer</code> | * '''Target Mapping''': <code>SiblingsContainer</code> | ||
* '''Target Finder Expression''': <code>var:self</code> (the second container represents the current person also) | * '''Target Finder Expression''': <code>var:self</code> (the second container represents the current person also) | ||
+ | |||
[[File:sirius_tuto2_18-02.png]] | [[File:sirius_tuto2_18-02.png]] | ||
+ | |||
On the style of the edge (automatically created), you can specify the end's decorators. | On the style of the edge (automatically created), you can specify the end's decorators. | ||
[[File:sirius_tuto2_18-03.png]] | [[File:sirius_tuto2_18-03.png]] | ||
+ | |||
Save the ''odesign'' file, and now you can see a link between the two containers. | Save the ''odesign'' file, and now you can see a link between the two containers. | ||
Line 514: | Line 623: | ||
[[File:sirius_tuto2_18-04.png]] | [[File:sirius_tuto2_18-04.png]] | ||
− | + | ==Double-click== | |
Now we can create a specific diagram for each person. To facilitate the navigation between all these diagrams, let's create a ''Double Click'' tool that allows the user to navigate from any person on a diagram to its dedicated diagram. | Now we can create a specific diagram for each person. To facilitate the navigation between all these diagrams, let's create a ''Double Click'' tool that allows the user to navigate from any person on a diagram to its dedicated diagram. | ||
+ | |||
Go back to the first diagram, right click on the ''Section'' in the first ''Layer'' and select the menu '''New Element Edition > Double Click'''. | Go back to the first diagram, right click on the ''Section'' in the first ''Layer'' and select the menu '''New Element Edition > Double Click'''. | ||
[[File:sirius_tuto2_19-01.png]] | [[File:sirius_tuto2_19-01.png]] | ||
+ | |||
On the ''Mappings'' property of the ''Double Click'' select all the elements of the modeling tool that represent a ''Person'' (except the two containers, since it doesn't make sense to navigate to the current diagram). | On the ''Mappings'' property of the ''Double Click'' select all the elements of the modeling tool that represent a ''Person'' (except the two containers, since it doesn't make sense to navigate to the current diagram). | ||
[[File:sirius_tuto2_19-02.png]] | [[File:sirius_tuto2_19-02.png]] | ||
+ | |||
To specify the action of the ''Double Click'', right-click on the ''Begin'' and select the menu '''New Operation > Navigation'''. | To specify the action of the ''Double Click'', right-click on the ''Begin'' and select the menu '''New Operation > Navigation'''. | ||
[[File:sirius_tuto2_19-03.png]] | [[File:sirius_tuto2_19-03.png]] | ||
+ | |||
Then set these properties to the ''Navigation'' : | Then set these properties to the ''Navigation'' : | ||
* '''Diagram Description''': <code>Relationships diagram</code> | * '''Diagram Description''': <code>Relationships diagram</code> | ||
− | * ''' | + | * '''Create if not Existent''': <code>true</code> |
+ | |||
[[File:sirius_tuto2_19-04.png]] | [[File:sirius_tuto2_19-04.png]] | ||
+ | |||
Save the ''odesign'' file, close and reopen your diagrams. Now you can double-click on persons to open their corresponding ''Relationships diagram''. If this diagram has not been created yet, Sirius will propose to create it. | Save the ''odesign'' file, close and reopen your diagrams. Now you can double-click on persons to open their corresponding ''Relationships diagram''. If this diagram has not been created yet, Sirius will propose to create it. | ||
Line 540: | Line 655: | ||
[[File:sirius_tuto2_19-05.png]] | [[File:sirius_tuto2_19-05.png]] | ||
− | + | ==Table== | |
With Sirius it is also possible to represent model elements with a ''Table''. | With Sirius it is also possible to represent model elements with a ''Table''. | ||
Line 548: | Line 663: | ||
* mother's name | * mother's name | ||
* number of children | * number of children | ||
+ | |||
Right-click on the ''Viewpoint'' and select the menu '''New representation > Edition Table Description'''. | Right-click on the ''Viewpoint'' and select the menu '''New representation > Edition Table Description'''. | ||
Line 553: | Line 669: | ||
[[File:sirius_tuto2_20-01.png]] | [[File:sirius_tuto2_20-01.png]] | ||
− | Set | + | |
+ | Set the ''basicfamily'' metamodel to this table (see [[Sirius/Tutorials/4MinTutorial#Define_a_Diagram | Starter Tutorial]]) then set these properties: | ||
* '''Id''': <code>Persons table</code> | * '''Id''': <code>Persons table</code> | ||
− | * '''Domain Class''': <code>basicfamily | + | * '''Domain Class''': <code>basicfamily::Family</code> |
+ | |||
[[File:sirius_tuto2_20-02.png]] | [[File:sirius_tuto2_20-02.png]] | ||
+ | |||
In this table, you need lines to represent the persons. So, right-click on the ''Table'' and select the menu '''New Table Element > Line'''. | In this table, you need lines to represent the persons. So, right-click on the ''Table'' and select the menu '''New Table Element > Line'''. | ||
[[File:sirius_tuto2_20-03.png]] | [[File:sirius_tuto2_20-03.png]] | ||
+ | |||
Set these properties to the line: | Set these properties to the line: | ||
* '''Id''': <code>PersonLine</code> | * '''Id''': <code>PersonLine</code> | ||
− | * '''Domain Class''': <code>basicfamily | + | * '''Domain Class''': <code>basicfamily::Person</code> |
+ | * '''Semantic Candidates Expression''': <code>feature:members</code> | ||
* '''Header Label Expression''' (''Label'' tab): <code>feature:name</code> | * '''Header Label Expression''' (''Label'' tab): <code>feature:name</code> | ||
+ | |||
[[File:sirius_tuto2_20-04.png]] | [[File:sirius_tuto2_20-04.png]] | ||
+ | |||
Save the ''odesign'' file then right-click on the ''Family'' instance in the ''Model Browser'' and click on the menu '''New Representation'''. You can see a new menu '''new Persons table'''. | Save the ''odesign'' file then right-click on the ''Family'' instance in the ''Model Browser'' and click on the menu '''New Representation'''. You can see a new menu '''new Persons table'''. | ||
[[File:sirius_tuto2_20-05.png]] | [[File:sirius_tuto2_20-05.png]] | ||
+ | |||
If you select this menu, Sirius creates and opens a table with all the family's members. | If you select this menu, Sirius creates and opens a table with all the family's members. | ||
[[File:sirius_tuto2_20-06.png]] | [[File:sirius_tuto2_20-06.png]] | ||
+ | |||
Now, let's add columns to this table to display more information for each person. So, right-click on the ''Table'' and select the menu '''New Table Element > Feature Column'''. | Now, let's add columns to this table to display more information for each person. So, right-click on the ''Table'' and select the menu '''New Table Element > Feature Column'''. | ||
[[File:sirius_tuto2_20-07.png]] | [[File:sirius_tuto2_20-07.png]] | ||
+ | |||
Set these properties to the column: | Set these properties to the column: | ||
* '''Id''': <code>fatherCol</code> | * '''Id''': <code>fatherCol</code> | ||
* '''Feature Name''': <code>father</code> | * '''Feature Name''': <code>father</code> | ||
+ | |||
[[File:sirius_tuto2_20-08.png]] | [[File:sirius_tuto2_20-08.png]] | ||
+ | |||
Select the ''Label'' tab and set these properties: | Select the ''Label'' tab and set these properties: | ||
* '''Header Label Expression''': <code>Father</code> | * '''Header Label Expression''': <code>Father</code> | ||
− | * | + | * <strong>Label Expression</strong>: <code>aql:self.father.name</code> |
+ | |||
+ | |||
+ | [[File:sirius_tuto2_20-10.png]] | ||
− | |||
Copy and paste ''fatherCol'' then rename <code>father</code> by <code>mother</code> in all the properties. | Copy and paste ''fatherCol'' then rename <code>father</code> by <code>mother</code> in all the properties. | ||
− | [[File:sirius_tuto2_20- | + | [[File:sirius_tuto2_20-09.png]] |
+ | |||
Save the ''odesign'' file and see the two new columns. | Save the ''odesign'' file and see the two new columns. | ||
[[File:sirius_tuto2_20-11.png]] | [[File:sirius_tuto2_20-11.png]] | ||
+ | |||
Finally, add a new ''Feature Column'' to display the number of children. | Finally, add a new ''Feature Column'' to display the number of children. | ||
Line 607: | Line 739: | ||
* '''Id''': <code>childrenCol</code> | * '''Id''': <code>childrenCol</code> | ||
* '''Feature Name''': <code>children</code> | * '''Feature Name''': <code>children</code> | ||
+ | |||
[[File:sirius_tuto2_20-12.png]] | [[File:sirius_tuto2_20-12.png]] | ||
+ | |||
Select the ''Label'' tab and set these properties: | Select the ''Label'' tab and set these properties: | ||
* '''Header Label Expression''': <code>Children</code> | * '''Header Label Expression''': <code>Children</code> | ||
− | * '''label Expression''': <code> | + | * '''label Expression''': <code>aql:self.children->size()</code> |
+ | |||
[[File:sirius_tuto2_20-13.png]] | [[File:sirius_tuto2_20-13.png]] | ||
+ | |||
Save the ''odesign'' file and see the third column. | Save the ''odesign'' file and see the third column. | ||
Line 620: | Line 756: | ||
[[File:sirius_tuto2_20-14.png]] | [[File:sirius_tuto2_20-14.png]] | ||
− | + | ==Java Services== | |
− | When | + | When expressions become complex, you should write ''Java Services'' instead. |
For example, let's create a ''Java Service'' to compute the number of cousins and display this information in the table. | For example, let's create a ''Java Service'' to compute the number of cousins and display this information in the table. | ||
− | + | Add a method named <code>getCousinsNumber</code> in the Java class ''Services.java'' (in ''src/org.eclipse.sirius.sample.basicfamily.design''). | |
− | |||
− | |||
− | |||
<pre> | <pre> | ||
Line 640: | Line 773: | ||
import org.eclipse.sirius.sample.basicfamily.Person; | import org.eclipse.sirius.sample.basicfamily.Person; | ||
− | public class | + | /** |
− | + | * The services class used by VSM. | |
+ | */ | ||
+ | public class Services { | ||
+ | |||
public int getCousinsNumber(Person person) { | public int getCousinsNumber(Person person) { | ||
List<Person> cousins=new ArrayList<Person>(); | List<Person> cousins=new ArrayList<Person>(); | ||
Line 660: | Line 796: | ||
return cousins.size(); | return cousins.size(); | ||
} | } | ||
+ | |||
} | } | ||
</pre> | </pre> | ||
− | |||
− | + | To use the service ''getCousinsNumber'' in the table, create a new ''Feature Column'' named <code>cousinsCol</code> and invoke the service in the expression (<code>service:getCousinsNumber</code>). | |
− | [[File:sirius_tuto2_21- | + | [[File:sirius_tuto2_21-04.png]] |
− | |||
− | + | '''Note''': The ''Feature Name'' property can be set with any valid feature name (name, parents, ...), since the label will be computed independently (just based on the current person). | |
− | + | '''Note''': Since Sirius 6.0, you can select a service from an expression field, then hit ''F3'' to open the source code of this service. | |
− | + | In the table, now you can see a new column ''Cousins'' containing the number of cousins for each person (zero in the sample model). Use the diagram creation tools for creating more persons such as some of them have cousins: Sirius will automatically update the number of cousins in the table. | |
− | + | [[File:sirius_tuto2_21-06.png]] | |
− | + | = Going Further = | |
− | + | This advanced tutorial is now finished, congratulations! If you wish to go further and explore other Sirius features, you can continue with the [[Sirius/Tutorials/CompartmentsTutorial|Compartments Tutorial]] which explains how to create compartments within a container. | |
− | + | [[File:Sirius_tuto3-1-1.png]] | |
− | [[ | + | [[Category:Sirius]] |
Latest revision as of 08:32, 5 July 2018
Contents
- 1 Overview
- 2 Install the basic modeling tool
- 3 Start extending the basic modeling tool
- 4 Going Further
Overview
This tutorial will guide you extending a basic modeling tool with many advanced features of Eclipse Sirius:
- Edition tools: edge creation, edge reconnection, element deletion, label edition
- Graphical improvements: styles customization
- Complexity management: layers, filters, validation rules, quick fixes
- Other kinds of representations: containers, bordered nodes, tables, navigation between representations
- Extensions: Java services
The instructions start from the result of the Sirius Starter Tutorial, a basic modeling tool which simply allows the user to graphically represent men and women of a family and to create new men.
The advanced modeling tool that you will create is based on the same simple Domain Model which describes basic concepts about families.
Note: The screenshots have been created with Obeo Designer 10.0 (based on Sirius 5.0).
Install the basic modeling tool
If you have followed the Starter Tutorial already, you are ready! Directly go to next section: Start extending the basic modeling tool.
Otherwise, start by following the instructions to install the sample Domain Model:
- Import the projects containing the sample Domain Model
- Launch a new runtime from your Eclipse
- Select the Sirius perspective
- Import a sample model
Now, you should have an Eclipse runtime (started from your first Eclipse) with a sample Family model installed in your workspace.
Then, install the solution of the Starter Tutorial. It is implemented by a Viewpoint Specification Project that you need to import into your workspace.
This project can be easily installed from the provided examples (menu File > New > Example... : select Basic Family Modeler Definition - Starter Tutorial Solution).
Once the modeler imported in your workspace, activate the persons viewpoint by selecting the menu Viewpoint Selection.
You must activate the persons viewpoint to be able to create the representations which are defined by this viewpoint.
Then right-click on the sample model and select the menu New Representation / new Persons diagram.
Sirius should create and open a diagram describing the men and women contained in the sample model.
Start extending the basic modeling tool
Note: the solution of the following steps can be installed directly from the samples
Edge Creation Tool
An Edge Creation tool allows the user to create relationships directly from the diagram, by using the palette.
Let's use this tool to allow the user to set the father and the mother relations of a Person.
Right click on the Section and select the menu New Element Creation > Edge Creation
Give an Id to this tool (setFather
) and associate it to fatherEdge, the Edge Mapping which defines the father graphical relation.
Set the icon that will appear in the palette (if you don't specify an icon here, Sirius will use a default one):
Then define the operations that will be performed by this tool each time the user will click on it. These operations can use four variables that are automatically set by Sirius:
- source: the first object on which the user has clicked (the source of the relation he is going to create)
- target: the second object on which the user has clicked (the target of the relation he is going to create)
- sourceView: the graphical object representing the source
- targetView: the graphical object representing the target
Under the Begin object, create a Change Context.
Set its Browse Expression to var:source
in order to define the execution context of the next operations.
Under the Change Context create a Set.
It will set the father of the first Person clicked (source) to the second Person clicked (target):
- Feature Name:
father
- Value Expression:
var:target
Save the odesign file and you will see a new tool setFather in the palette.
Precondition
To prevent the user to create a father relationship from a person to itself, or to one of its children, you can add the precondition expression aql:preTarget.differs(preSource) and preSource.oclAsType(basicfamily::Person).children->excludes(preTarget)
(written in AQL).
This expression uses two new variables:
- preSource: the object on which the user has clicked first
- preTarget: the object under the cursor
With this precondition, the tool will prevent the creation of forbidden links by showing a specific icon.
Now copy, paste and update the setFather tool to create the setMother tool.
Reconnect Edge Tool
A Reconnect Edge tool allows the user to change the end of a relationship by moving it directly from the diagram.
Let's create a Reconnect Edge tool to change the father and the mother of a Person.
Right click on the Section and select the menu New Element Edition > Reconnect Edge
Associate the fatherEdge to this reconnect tool.
This tool comes with six variables:
- source: the object currently attached to the moved end
- target: the object going to be attached to the moved end
- sourceView: the graphical object representing source
- targetView: the graphical object representing target
- element: the object attached to the other end
- elementView: the graphical object representing element
Then create a Change Context and set its expression to var:element
(the person who will change his father)
Finally, create a Set to assign the new selected parent (var:target
) as father of this person.
Copy, paste and update this tool to create a reconnect tool for mother relationship.
Delete Element Tool
A Delete Element tool specifies which actions have to be performed when the user hits the delete key on an diagram element.
It is necessary on elements which deletion can't be interpreted by Sirius (for example edges) or if you need to perform specific actions.
Let's create a Delete Element tool to specify what to do when the user deletes a paretal relation.
Right click on the Section and select the menu New Element Edition > Delete Element
Associate the fatherEdge to this Delete tool.
When deleting an edge, the variable element refers to the source of the relationship.
So, create a Change Context and set its expression to var:element
(the person which is the children). Then create a Unset on the feature father to remove this relation.
Copy, paste and update this tool to create a delete tool for mother relationship.
Direct Edit Label Tool
A Direct Edit Label specifies how to interpret the modification of graphical object's label in order to modify the model.
Let's create a Direct Edit Label to change the name of a Person directly from the diagram.
Right click on the Section and select the menu New Element Edition > Direct Edit Label
Associate this tool to the objects which have a name: ManNode and WomanNode
This tool comes with a mask that creates variables depending on the label's value. By default, the mask is set to {0}
, which means that the variable named 0 will contain the full value of the label.
Create a Set to indicate the feature of the edited object that will be modified (name
) and the value to assign (var:0
).
Style Customization
Style Customizations change graphical properties of diagram elements (color, label, size, ...) depending on conditions.
For example, let's change the label of a Person depending on the number of its children:
- Person without children => color label in gray
- Person having more than one children => set label size to 12
- Person having grandchildren => prefix label with Grandpa or Grandma
Right click on the Default Layer and select the menu New Customization > Style Customizations. It will group all the different customizations.
Right click on the Style Customizations and select the menu New Customization > Style Customization to create the first customization.
Enter the AQL expression associated to this customization: aql:self.oclAsType(basicfamily::Person).children->size()=0
Then define the graphical properties that will change if the condition is met.
Right click on the Style Customization and select the menu New Customization. To change the label color, create a Property Customization (by selection).
On this Property Customization, select the two Workspace Images for the Applied On field (they hold the label to change), enter labelColor in the Property Name field, then select the gray color.
Note that you can use the automatic-completion to select the applicable property.
Create a second Style Customizations with the condition: aql:self.oclAsType(basicfamily::Person).children->size()>1
and add a Style Customization (by expression) to set the labelSize to 12
.
Finally, create a third Style Customizations with the condition: aql:self.oclAsType(basicfamily::Person).children.children->size()>0
Add a Style Customization (by expression) for the Workspace Image corresponding to the Man, enter the property name labelExpression and the expression aql:'Grandpa '+self.oclAsType(basicfamily::Person).name
(to prefix the person name with Grandpa).
Do the same with the Woman image and the expression aql:'Grandma '+self.oclAsType(basicfamily::Person).name
.
Save the odesign file and see the result on the diagram.
Layers
With Sirius it is possible to allocate specific graphical elements to layers that can be activated/deactivated on demand by the user.
Let's create two layers: one for the Men and one for the Women.
Right click on Persons diagram and select the menu New Diagram Element > Additional Layer.
Call this Layer Men
and check the option Active by default.
Create a Section in this layer then drag and drop all the elements related to the Man type into this layer.
Create a second Layer Women
and drag and drop all the elements related to the Woman type.
Re-open the sample diagram. You can see the two optional layers Men and Women (selected by default).
If you de-activate the Men layer, only women remain on the diagram. Note that the tools related to men have been hidden too.
Filters
With Filters, Sirius provides an additional mechanism to automatically show or hide elements of a diagram: a condition determines which elements remain visible.
Let's create a Filter to hide persons without children.
Right click on Persons diagram and select the menu New Filter > Composite Filter.
Set the id to childrenFilter
.
Then create a Mapping Filter.
Associate ManNode and WomanNode to this filter and define the Semantic Condition Expression : aql:self.children->size()>0
On the diagram, you can now select the filter childrenFilter and see that only persons with children remain visible.
Validation Rules
Validation rules allow the user to evaluate the quality of a model.
For example, despite the precondition existing on the Eddge Creation tool, users can still create circular parental relations between two persons by using the Properties View:
- select a person with at least one child
- use the Parents widget in the Properties View to add one of the children as a parent
Let's create a Validation Rule to detect this problem.
Right click on Persons diagram and select the menu New Validation > Validation.
Set the name FamilyValidation
to this Validation. Then create a Semantic Validation Rule.
Set the properties of this rule:
- Level:
Error
- Target Class:
basicfamily::Person
- Message:
aql:self.oclAsType(basicfamily::Person).father.name+' should not be both the child and the father of '+self.oclAsType(basicfamily::Person).name
Then create an Audit (a condition corresponding to this rule) with the expression aql:self.children->excludes(self.father)
.
To test this rule, introduce an error in the model with the Property View: add the father of a person into the list of his children.
Then right-click on the diagram and select the menu Validate diagram.
The circular father relationship is detected and a decorator (corresponding to the rule level) is displayed on the persons with this problem. A tootip contains the error message.
Quick Fixes
Fixes can be provided to the user for solving the problem automatically.
For example, we can propose to unset one of the two father relations.
Right-click on the Rule and select the menu New > Fix.
Set the name Unset father
to this Fix and create a Begin. Then create a Unset and enter father
in the Feature name.
If you open the Problems View, you can right-click on one of the errors and select the menu Quick Fix.
A dialog opens which proposes the available fixes.
Select Unset father and click on Finish: the father of the selected person is automatically unset and the problem is solved.
Object-Centered Diagram
The Persons diagram is a representation related to the whole model: it displays all the members of the family. This is the reason why it belongs to the Family instance, as you can see in the Model Explorer.
With Sirius, you can create a representation on any instance of the model. For example, let's create a person-centered diagram to show only the relationships of a given person.
Right-click on the persons viewpoint and select the menu New Representation > Diagram Description.
Associate the basicfamily metamodel to this diagram (see Starter Tutorial) then set these properties:
- Id:
Relationships diagram
- Domain Class:
basicfamily::Person
In the Advanced tab, set the Title Expression to aql:'Relations of '+self.name
in order to customize the name of the diagram with the person's name.
Save the odesign file. Now, you can right click on a person in the Model Explorer and create a new representation of type Relationships diagram.
The result is a blank diagram, since we have not yet specified its content.
Container
A Container is a kind of diagram element that can contain other diagram elements.
On the Relationships diagram, let's use two containers to represent:
- The current person (who owns the diagram) with:
- each children in a list
- its parents as border nodes
- The siblings of the current person:
- each sibling in a list
Right-click on the Layer and select the menu New Diagram Element > Container.
For this first container, set these properties:
- Id:
PersonContainer
- Domain Class:
basicfamily::Person
- Semantic Candidate Expression:
var:self
(the current person) - Children Presentation:
List
To define the graphical rendering of this container, right-click on it and select the menu New Style > Gradient.
On this style, set these properties:
- Label Tab:
- Label Size:
12
- Label Format:
bold
- Label Size:
- Color Tab:
- Foreground Color:
light_green
- Foreground Color:
Save the odesign file and you see a green container appear on the diagram that you have created for a person.
Sub Nodes
Now, to display children inside this container, right-click on the container definition and click on the menu New Diagram Element > Sub Node.
On the Sub Node set these properties:
- Id:
ChildrenNode
- Domain Class:
basicfamily::Person
- Semantic Candidate Expression:
feature:children
Then create a style. Note that the kind of style is not important here: for elements in a list, the style is used only to specify the label.
Save the odesign file, and now you can see the children listed inside the container.
Copy paste PersonContainer to create another container for siblings.
Change these properties on this new container description:
- Container > Name:
SiblingContainer
- Gradient > Label Size:
10
- Gradient > Label Expression:
Siblings
- Gradient > Foreground Color:
light_yellow
And these properties on the Sub Node:
- Id:
Sibling Node
- Semantic Candidates Expression:
aql:self.parents.children->excluding(self)
Save the odesign file, and now you can see the siblings listed inside a second container.
Border Node
Now let's add Border Nodes to the first container to display the parents of the current person.
Right-click on PersonContainer and select the menu New Diagram Element > Border Node:
Set these properties to the border node:
- Id:
ParentNode
- Domain Class:
basicfamily::Person
- Semantic Candidate Expression:
feature:parents
Add a square as style with a White color.
Save the odesign file and now, after manual resizing, you should see the parents attached on the border of the first container :
Edge between containers
Like nodes, Containers can be linked with Edges.
Right-click on the Default layer and select the menu New Diagram Element > Relation Based Edge.
Set these properties to the edge:
- Id:
SiblingsEdge
- Source Mapping:
PersonContainer
- Target Mapping:
SiblingsContainer
- Target Finder Expression:
var:self
(the second container represents the current person also)
On the style of the edge (automatically created), you can specify the end's decorators.
Save the odesign file, and now you can see a link between the two containers.
Double-click
Now we can create a specific diagram for each person. To facilitate the navigation between all these diagrams, let's create a Double Click tool that allows the user to navigate from any person on a diagram to its dedicated diagram.
Go back to the first diagram, right click on the Section in the first Layer and select the menu New Element Edition > Double Click.
On the Mappings property of the Double Click select all the elements of the modeling tool that represent a Person (except the two containers, since it doesn't make sense to navigate to the current diagram).
To specify the action of the Double Click, right-click on the Begin and select the menu New Operation > Navigation.
Then set these properties to the Navigation :
- Diagram Description:
Relationships diagram
- Create if not Existent:
true
Save the odesign file, close and reopen your diagrams. Now you can double-click on persons to open their corresponding Relationships diagram. If this diagram has not been created yet, Sirius will propose to create it.
Table
With Sirius it is also possible to represent model elements with a Table.
Let's create a table that lists all the persons, with this information for each:
- father's name
- mother's name
- number of children
Right-click on the Viewpoint and select the menu New representation > Edition Table Description.
Set the basicfamily metamodel to this table (see Starter Tutorial) then set these properties:
- Id:
Persons table
- Domain Class:
basicfamily::Family
In this table, you need lines to represent the persons. So, right-click on the Table and select the menu New Table Element > Line.
Set these properties to the line:
- Id:
PersonLine
- Domain Class:
basicfamily::Person
- Semantic Candidates Expression:
feature:members
- Header Label Expression (Label tab):
feature:name
Save the odesign file then right-click on the Family instance in the Model Browser and click on the menu New Representation. You can see a new menu new Persons table.
If you select this menu, Sirius creates and opens a table with all the family's members.
Now, let's add columns to this table to display more information for each person. So, right-click on the Table and select the menu New Table Element > Feature Column.
Set these properties to the column:
- Id:
fatherCol
- Feature Name:
father
Select the Label tab and set these properties:
- Header Label Expression:
Father
- Label Expression:
aql:self.father.name
Copy and paste fatherCol then rename father
by mother
in all the properties.
Save the odesign file and see the two new columns.
Finally, add a new Feature Column to display the number of children.
Set these properties to the column:
- Id:
childrenCol
- Feature Name:
children
Select the Label tab and set these properties:
- Header Label Expression:
Children
- label Expression:
aql:self.children->size()
Save the odesign file and see the third column.
Java Services
When expressions become complex, you should write Java Services instead.
For example, let's create a Java Service to compute the number of cousins and display this information in the table.
Add a method named getCousinsNumber
in the Java class Services.java (in src/org.eclipse.sirius.sample.basicfamily.design).
package org.eclipse.sirius.sample.basicfamily.design; import java.util.ArrayList; import java.util.List; import org.eclipse.sirius.sample.basicfamily.Person; /** * The services class used by VSM. */ public class Services { public int getCousinsNumber(Person person) { List<Person> cousins=new ArrayList<Person>(); List<Person> parents=person.getParents(); for (Person parent: parents) { for (Person grandParent: parent.getParents()) { for (Person uncleOrAunt: grandParent.getChildren()) { if (!parents.contains(uncleOrAunt)) { for (Person cousin:uncleOrAunt.getChildren()) { if (!cousins.contains(cousin)) cousins.add(cousin); } } } } } return cousins.size(); } }
To use the service getCousinsNumber in the table, create a new Feature Column named cousinsCol
and invoke the service in the expression (service:getCousinsNumber
).
Note: The Feature Name property can be set with any valid feature name (name, parents, ...), since the label will be computed independently (just based on the current person).
Note: Since Sirius 6.0, you can select a service from an expression field, then hit F3 to open the source code of this service.
In the table, now you can see a new column Cousins containing the number of cousins for each person (zero in the sample model). Use the diagram creation tools for creating more persons such as some of them have cousins: Sirius will automatically update the number of cousins in the table.
Going Further
This advanced tutorial is now finished, congratulations! If you wish to go further and explore other Sirius features, you can continue with the Compartments Tutorial which explains how to create compartments within a container.