I. Introduction▲
I-A. Spécification▲
Un modèle de graphe développé avec EMF a été proposé précédemment, nous souhaitons pouvoir tester dans un graphe la contrainte suivante : « Pour tout nœud du graphe le nombre d'arcs ayant ce nœud pour origine doit être inférieur ou égal à deux ».
Par exemple, dans le graphe ci-dessous :
Les nœuds « N0 » et « N2 » ne répondent pas à la contrainte.
I-B. Lancement de la plate-forme Eclipse▲
Double-cliquer : ou le raccourci vers cet exécutable si vous l'avez créé dans le répertoire destiné à recevoir les « workspaces ». La plate-forme « Eclipse » est lancée :
Sélectionner le workspace :
Cliquer sur le bouton « OK » puis fermer la fenêtre « Welcome ».
I-C. Passer en perspective « Ecore »▲
Faire :
Sélectionner :
II. Installer OCL Tools▲
Faire :
Sélectionner :
Cliquer sur le bouton « Finish ». Nous obtenons le résultat suivant :
Cliquer sur le bouton « Next > » :
Cliquer sur le bouton « Next > ». Puis accepter la licence :
Cliquer sur le bouton « Finish ». Le logiciel s'installe :
Cliquer sur le bouton « Restart Now » :
Eclipse est relancé, ne pas changer de « Workspace ». Cliquer sur le bouton « OK ».
Après les fermetures de quelques vues, nous obtenons le résultat suivant :
III. Création d'un projet EMF▲
Faire :
Sélectionner « Eclipse Modeling Framework > Empty EMF Project » :
Cliquer sur le bouton « Next > », nommer le projet :
Cliquer sur le bouton « Finish ».
IV. Édition du modèle « Ecore »▲
Ouvrir le projet faire un clic droit sur « model » et sélectionner la commande « New > Ecore Diagram » :
Nommer le « Domain File » :
Cliquer sur le bouton « Finish ». Éditer ensuite le modèle et le sauvegarder :
C'est le modèle défini dans les autres documents.
Nous allons créer une référence supplémentaire (Noeud → Graphe) afin de pouvoir accéder au « Graphe » à partir d'un « Nœud » :
Cette référence va être définie comme « EOpposite » de la référence « Graphe → Noeud ».
Pour cela, dans les « properties » de la référence « Noeud → Graphe » cliquer dans le rectangle contenant les trois points :
Dans « Object selection », sélectionner :
Nous obtenons, après quelques modifications de l'aspect du diagramme :
- EReference « graphe » sélectionnée ;
- EReference « listeNoeuds » sélectionnée ;
Si on édite « Graphe.ecore », on obtient :
Remarque : depuis un « Nœud », l'attribut « graphe » permet d'accéder au graphe.Noeud.
V. Aide à la création d'une contrainte▲
V-A. Visualisation de la console OCL▲
Un clic droit dans l'éditeur de « Graphe.ecore » fait monter le menu contextuel, faire :
La console OCL interactive comporte deux zones :
V-B. Création d'une instance dynamique du modèle▲
Sélectionner Graphe puis faire un clic droit sélectionner la commande « CreateDynamicInstance… » :
Ne pas modifier le nom du fichier :
Cliquer sur le bouton « Finish ».
Nous obtenons « Graphe.xmi » :
V-B-1. Saisie d'un modèle▲
Afin de faciliter l'écriture de la contrainte, on saisit un modèle expérimental. Le modèle est construit sous « Graphe ». C'est sur ce modèle que nous testerons les expressions OCL.
Pour créer un « Nœud » :
Initialiser les « properties » du « Nœud » (Nom) pour obtenir : (Cliquer dans la zone d'édition) :
Continuer la saisie du modèle :
L'affichage en mode « Texte » (Open With > Text Editor) permet de visualiser le Graphe et les « properties » des Noeuds et des Arcs :
<?xml version="1.0" encoding="ASCII"?>
<
graphe
:
Graphe
xmi
:
version
=
"2.0"
xmlns
:
xmi
=
"http://www.omg.org/XMI"
xmlns
:
xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns
:
graphe
=
"http://graphe/1.0"
xsi
:
schemaLocation
=
"http://graphe/1.0 Graphe.ecore"
>
<listeNoeuds
nom
=
"Origine"
/>
<listeNoeuds
nom
=
"N1"
/>
<listeNoeuds
nom
=
"N2"
/>
<listeNoeuds
nom
=
"N3"
/>
<listeArcs
nom
=
"OrigineToN1"
origine
=
"//@listeNoeuds.0"
extremite
=
"//@listeNoeuds.1"
/>
<listeArcs
nom
=
"OrigineToN2"
origine
=
"//@listeNoeuds.0"
extremite
=
"//@listeNoeuds.2"
/>
<listeArcs
nom
=
"OrigineToN3"
origine
=
"//@listeNoeuds.0"
extremite
=
"//@listeNoeuds.3"
/>
<listeArcs
nom
=
"N1toN2"
origine
=
"//@listeNoeuds.1"
extremite
=
"//@listeNoeuds.2"
/>
<listeArcs
nom
=
"N2ToN3"
origine
=
"//@listeNoeuds.2"
extremite
=
"//@listeNoeuds.3"
/>
</
graphe
:
Graphe>
V-C. Expression d'une contrainte▲
Le modèle édité va nous aider à écrire l'expression « OCL ». Dans ce modèle, le nœud « Origine » est l'« origine » de trois arcs ce qui ne correspond pas à la contrainte que nous nous sommes fixée : « Pour tout nœud du graphe le nombre d'arcs ayant ce nœud pour origine doit être inférieur ou égal à deux ».
Pour écrire l'expression OCL sélectionner le Noeud « Origine » dans « Graphe.xmi ».
Les expressions sont saisies dans la zone « Enrty of queries » de la console.
La vue du métamodèle facilite l'écriture des expressions OCL.
On adopte la disposition ci-dessous des vues :
Les évaluations se font à partir du nœud « Noeud Origine » sélectionné.
Saisir « graphe » dans la zone « Entry of query » (valider la saisie).
L'évaluation s'affiche dans la zone « Results » :
Saisir « graphe.listeArcs » pour obtenir tous les arcs du graphe :
Nous allons considérer pour chaque arc si la condition suivante est remplie : l'origine de l'arc correspond au nœud sélectionné: « Origine » représenté par « self » dans l'expression.
Pour cela nous allons évaluer :
graphe.listeArcs->
select
(
origine=
self)
Ce qui donne les trois arcs ayant le nœud « Origine » pour origine :
Finalement nous obtenons l'expression recherchée :
V-C-1. Mise en place de la contrainte▲
Fermer « Graphe.xmi » avant toute modification du métamodèle.
Ouvrir « Graphe.ecore » avec l'éditeur OCLinEcore(Ecore) Editor :
Le métamodèle apparaît sous la forme :
module
_'Graphe.ecore'
package
graphe : graphe =
'http://graphe/1.0'
{
class
Graphe
{
property listeNoeuds#graphe : Noeud[*
] {
ordered composes }
;
property listeArcs : Arc[*
] {
ordered composes }
;
}
class
Noeud
{
attribute nom : String[1
] {
ordered }
;
property graphe#listeNoeuds : Graphe[1
] {
ordered }
;
}
class
Arc
{
attribute nom : String[1
] {
ordered }
;
property origine : Noeud[1
] {
ordered }
;
property extremite : Noeud[1
] {
ordered }
;
}
}
On l'édite pour ajouter la contrainte sur les nœuds :
class
Noeud
{
invariant toManyOutput:
graphe.listeArcs->
select
(
origine=
self)->
size
(
)<=
2
;
attribute name : String[1
];
property graphe#listeNoeuds : Graphe[1
];
}
Si on réaffiche « Graphe.xmi » avec (Open with > Sample Reflective Ecore Model Editor) :
Nous obtenons :
Où la contrainte « toManyOuput » apparaît.
V-D. Test du modèle▲
Un clic droit dans la zone d'éditeur de « Graphe.xmi » fait monter le menu contextuel. Sélectionner la commande « Validate » :
Le message suivant s'affiche :
L'arc « Arc OrigineToN3 » est supprimé :
On relance la validation, le modèle maintenant est correct :
VI. Génération éditeur arborescent▲
VI-A. Création « EMF Generation Model »▲
Sélectionner « Graphe.ecore » puis faire :
Sélectionner :
Cliquer sur le bouton « Next > ».
On ne modifie pas le nom du modèle :
Cliquer sur le bouton « Next > ».
Sélectionner :
Cliquer sur le bouton « Next > ».
Dans :
Cliquer sur les boutons « Load » et « Next > » :
Cliquer sur le bouton « Finish ».
« Graphe.genmodel » est ouvert en édition.
Sélectionner la racine « Graphe » et initialiser la « property » du « Model » « Operation Reflection » à « true » :
VI-B. Génération de l'éditeur▲
Dans l'éditeur de « Graphe.genmodel », faire un clic droit et dans le menu contextuel sélectionner « Generate All » :
Après génération trois nouveaux projets sont créés :
VI-C. Test de l'éditeur généré▲
Créer une nouvelle configuration d'exécution, la nommer et faire « Apply » :
Faire « Run ». Une nouvelle plate-forme « Eclipse » est lancée avec pour « workspace » : « runtime-OCLinEcore ». Fermer la fenêtre « Welcome » et quelques vues pour obtenir :
Créer un nouveau projet :
Sélectionner :
Cliquer sur le bouton « Next > ».
Nommer le projet :
Cliquer le bouton « Finish », le nouveau projet est créé :
Pour créer un modèle faire :
Sélectionner :
Cliquer sur le bouton « Next > ».
Nommer le fichier :
Cliquer sur le bouton « Next > ».
Sélectionner « Graphe » :
Cliquer sur le bouton « Finish ».
Éditer un graphe :
On peut ouvrir le graphe avec un éditeur textuel afin de visualiser les arcs.
On a la correspondance :
N0 → @listeNoeuds.0
N1 → @listeNoeuds.1
<?xml version="1.0" encoding="UTF-8"?>
<
graphe
:
Graphe
xmi
:
version
=
"2.0"
xmlns
:
xmi
=
"http://www.omg.org/XMI"
xmlns
:
graphe
=
"http://graphe/1.0"
>
<listeNoeuds
nom
=
"N0"
/>
<listeNoeuds
nom
=
"N1"
/>
<listeNoeuds
nom
=
"N2"
/>
<listeNoeuds
nom
=
"N3"
/>
<listeNoeuds
nom
=
"N4"
/>
<listeArcs
nom
=
"N0ToN1"
origine
=
"//@listeNoeuds.0"
extremite
=
"//@listeNoeuds.1"
/>
<listeArcs
nom
=
"N0ToN2"
origine
=
"//@listeNoeuds.0"
extremite
=
"//@listeNoeuds.2"
/>
<listeArcs
nom
=
"N0ToN3"
origine
=
"//@listeNoeuds.0"
extremite
=
"//@listeNoeuds.3"
/>
<listeArcs
nom
=
"N1toN4"
origine
=
"//@listeNoeuds.1"
extremite
=
"//@listeNoeuds.4"
/>
<listeArcs
nom
=
"N2ToN4"
origine
=
"//@listeNoeuds.2"
extremite
=
"//@listeNoeuds.4"
/>
<listeArcs
nom
=
"N3ToN4"
origine
=
"//@listeNoeuds.3"
extremite
=
"//@listeNoeuds.4"
/>
</
graphe
:
Graphe>
Du nœud N0 partent trois arcs.
Si on demande une validation du graphe, on obtient :
L'erreur est reportée dans la vue « Project Explorer » :
VII. Génération d'un éditeur graphique▲
Se reporter au document « Génération d'un éditeur graphique ».
VII-A. Création projet GMF▲
Faire :
Sélectionner :
Cliquer sur le bouton « Next> ».
Nommer le projet :
Cliquer sur le bouton « Next> ».
Sélectionner le « Dashboard » :
Cliquer sur le bouton « Finish ».
Sélectionner le projet « exemple.graphe.gmf » pour obtenir :
VII-B. Sélection du « Domain Model »▲
Dans le pavé « Domain Model » cliquer « Select » dans :
Sélectionner « Graphe.ecore » :
Cliquer sur le bouton « OK » pour obtenir :
VII-C. Sélection du « Domain Gen Model »▲
Graphe.genmodel existe déjà dans le projet « exemple.graphe.emf ».
Dans le pavé « Domain Gen Model » cliquer « Select » :
Sélectionner « Graphe.genmodel »:
Cliquer sur le bouton « OK » pour obtenir :
VII-D. Génération du « Graphical Def Model »▲
Cliquer « Derive » :
Sélectionner le répertoire « model » du projet « exemple.graphe.gmf » :
Cliquer sur le bouton « Next > ».
Faire « Load » et sélectionner « Graphe » :
Cliquer sur le bouton « Next > ».
Ne rien modifier :
Cliquer sur le bouton « Finish ».
Ajout des flèches aux arcs
Dans le projet « exemple.graphe.gmf », éditer le fichier « model > Graphe.gmfgraph » :
Modifier « property » Name de « Polyline Decoration » :
Modifier « property » « Target Decoration » de « Polyline Connection ArcFigure ».
VII-E. Génération du « Tooling Def Model »▲
Cliquer sur « Derive » :
Sélectionner le répertoire « model » du projet « exemple.graphe.gmf » :
Cliquer sur le bouton « Next > ».
Cliquer sur « Load », sélectionner « Graphe » :
Cliquer sur le bouton « Next > » :
Cliquer sur le bouton « Finish » pour obtenir :
VII-F. Génération du « Mapping Model »▲
Cliquer sur « Combine » :
Sélectionner le répertoire « model » du projet « exemple.graphe.gmf » :
Cliquer sur le bouton « Next > ».
Cliquer « Load », sélectionner « Graphe » :
Cliquer sur le bouton « Next > ».
Cliquer sur « Load » puis sur le bouton « Next > ».
Cliquer sur le bouton « Load » puis sur « Next > », pour obtenir :
Modifier le « mapping » :
Dans « Links », sélectionner « Arc(<unspecified>;listeArcs) » et cliquer « Change... ».
Éditer les « Properties » :
Cliquer sur le bouton « OK ». Dans « Create GMFMap model - Mapping », cliquer sur le bouton « Finish ».
VII-F-1. Génération « Diagram Editor Gen Model »▲
Cliquer sur « Transform », ne pas cocher « RCP ».
On a maintenant dans le répertoire « model » du projet « exemple.graphe.gmf » :
VII-F-2. Génération de l'éditeur de graphes▲
Cliquer dans le « GMF Dashboard » : « Generate diagram editor ».
Le projet « exemple.graphe.emf.diagram » est généré.
VIII. Test modèles édités▲
Faire un clic droit sur le projet : « exemple.graphe.emf.diagram ». Sélectionner la commande « RunAs > Run Configuration ». On retrouve la configuration « OCLinEcore » précédemment créée.
Créer une nouvelle configuration nommée « OCLinEcore », faire « Apply » :
Faire « Run ».
Une nouvelle plateforme Eclipse est lancée. Créer un nouveau projet de type « General > Project » nommé « testGraphe ». Sous le projet créer un graphe de type : « Examples > Graphe Diagram » que l'on nomme « G1.graphe_diagram ». On l'édite et on le sauvegarde.
Valider le graphe :
On sélectionne « G1.graphe » et on utilise le menu contextuel de l'éditeur :
Le message suivant s'affiche :
La première ligne correspond au nombre d'arcs issus du nœud « N1 ».
Les autres lignes indiquent que le métamodèle attend un nom pour chaque arc.
Modifier le modèle :
Seuls les problèmes liés aux noms des arcs sont affichés :
Modifier le modèle en nommant les arcs en utilisant les properties :
La validation donne :
IX. Conclusions et remerciements▲
La console « Interactive OCL » nous a permis de tester la contrainte appliquée au graphe. Cette contrainte intégrée au modèle EMF est utilisée dans les éditeurs graphiques.
Nous tenons à remercier ClaudeLELOUP pour sa relecture attentive de cet article puis _Max_ et Keulkeul pour la mise au gabarit de l'article original.
X. Licence▲
La licence « Creative Commons » s'applique à ce document, veuillez vous référer à ce site pour de plus amples informations : http://creativecommons.org/licenses/by-nc-nd/2.0/fr/.