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 :

Image non disponible

Les nœuds « N0 » et « N2 » ne répondent pas à la contrainte.

I-B. Lancement de la plate-forme Eclipse

Double-cliquer : Image non disponible 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 :

Image non disponible

Sélectionner le workspace :

Image non disponible

Cliquer sur le bouton « OK » puis fermer la fenêtre « Welcome ».

I-C. Passer en perspective « Ecore »

Faire :

Image non disponible

Sélectionner :

Image non disponible

II. Installer OCL Tools

Faire :

Image non disponible

Sélectionner :

Image non disponible

Cliquer sur le bouton « Finish ». Nous obtenons le résultat suivant :

Image non disponible

Cliquer sur le bouton « Next > » :

Image non disponible

Cliquer sur le bouton « Next > ». Puis accepter la licence :

Image non disponible

Cliquer sur le bouton « Finish ». Le logiciel s'installe :

Image non disponible

Cliquer sur le bouton « Restart Now » :

Image non disponible

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 :

Image non disponible

III. Création d'un projet EMF

Faire :

Image non disponible

Sélectionner « Eclipse Modeling Framework > Empty EMF Project » :

Image non disponible

Cliquer sur le bouton « Next > », nommer le projet :

Image non disponible

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 » :

Image non disponible

Nommer le « Domain File » :

Image non disponible

Cliquer sur le bouton « Finish ». Éditer ensuite le modèle et le sauvegarder :

Image non disponible

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 » :

Image non disponible

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 :

Image non disponible

Dans « Object selection », sélectionner :

Image non disponible

Nous obtenons, après quelques modifications de l'aspect du diagramme :

  • EReference « graphe » sélectionnée ;
Image non disponible
  • EReference « listeNoeuds » sélectionnée ;
Image non disponible

Si on édite « Graphe.ecore », on obtient :

Image non disponible

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 :

Image non disponible

La console OCL interactive comporte deux zones :

Image non disponible

V-B. Création d'une instance dynamique du modèle

Sélectionner Graphe puis faire un clic droit sélectionner la commande « CreateDynamicInstance… » :

Image non disponible

Ne pas modifier le nom du fichier :

Image non disponible

Cliquer sur le bouton « Finish ».

Nous obtenons « Graphe.xmi » :

Image non disponible

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 » :

Image non disponible

Initialiser les « properties » du « Nœud » (Nom) pour obtenir : (Cliquer dans la zone d'édition) :

Image non disponible

Continuer la saisie du modèle :

Image non disponible

L'affichage en mode « Texte » (Open With > Text Editor) permet de visualiser le Graphe et les « properties » des Noeuds et des Arcs :

 
Sélectionnez
<?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 :

Image non disponible

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 » :

Image non disponible

Saisir « graphe.listeArcs » pour obtenir tous les arcs du graphe :

Image non disponible

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 :

 
Sélectionnez
graphe.listeArcs->select(origine=self)

Ce qui donne les trois arcs ayant le nœud « Origine » pour origine :

Image non disponible

Finalement nous obtenons l'expression recherchée :

Image non disponible

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 :

Image non disponible

Le métamodèle apparaît sous la forme :

 
Sélectionnez
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 :

 
Sélectionnez
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) :

Image non disponible

Nous obtenons :

Image non disponible

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 » :

Image non disponible

Le message suivant s'affiche :

Image non disponible

L'arc « Arc OrigineToN3 » est supprimé :

Image non disponible

On relance la validation, le modèle maintenant est correct :

Image non disponible

VI. Génération éditeur arborescent

VI-A. Création « EMF Generation Model »

Sélectionner « Graphe.ecore » puis faire :

Image non disponible

Sélectionner :

Image non disponible

Cliquer sur le bouton « Next > ».

On ne modifie pas le nom du modèle :

Image non disponible

Cliquer sur le bouton « Next > ».

Sélectionner :

Image non disponible

Cliquer sur le bouton « Next > ».

Dans :

Image non disponible

Cliquer sur les boutons « Load » et « Next > » :

Image non disponible

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 » :

Image non disponible

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 » :

Image non disponible

Après génération trois nouveaux projets sont créés :

Image non disponible

VI-C. Test de l'éditeur généré

Image non disponible

Créer une nouvelle configuration d'exécution, la nommer et faire « Apply » :

Image non disponible

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 :

Image non disponible

Créer un nouveau projet :

Image non disponible

Sélectionner :

Image non disponible

Cliquer sur le bouton « Next > ».

Nommer le projet :

Image non disponible

Cliquer le bouton « Finish », le nouveau projet est créé :

Image non disponible

Pour créer un modèle faire :

Image non disponible

Sélectionner :

Image non disponible

Cliquer sur le bouton « Next > ».

Nommer le fichier :

Image non disponible

Cliquer sur le bouton « Next > ».

Sélectionner « Graphe » :

Image non disponible

Cliquer sur le bouton « Finish ».

Éditer un graphe :

Image non disponible

On peut ouvrir le graphe avec un éditeur textuel afin de visualiser les arcs.

On a la correspondance :
N0 → @listeNoeuds.0
N1 → @listeNoeuds.1

 
Sélectionnez
<?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 :

Image non disponible
Image non disponible

L'erreur est reportée dans la vue « Project Explorer » :

Image non disponible

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 :

Image non disponible

Sélectionner :

Image non disponible

Cliquer sur le bouton « Next> ».

Nommer le projet :

Image non disponible

Cliquer sur le bouton « Next> ».

Sélectionner le « Dashboard » :

Image non disponible

Cliquer sur le bouton « Finish ».

Sélectionner le projet « exemple.graphe.gmf » pour obtenir :

Image non disponible

VII-B. Sélection du « Domain Model »

Dans le pavé « Domain Model » cliquer « Select » dans :

Image non disponible

Sélectionner « Graphe.ecore » :

Image non disponible

Cliquer sur le bouton « OK » pour obtenir :

Image non disponible

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 » :

Image non disponible

Sélectionner « Graphe.genmodel »:

Image non disponible

Cliquer sur le bouton « OK » pour obtenir :

Image non disponible

VII-D. Génération du « Graphical Def Model »

Cliquer « Derive » :

Image non disponible

Sélectionner le répertoire « model » du projet « exemple.graphe.gmf » :

Image non disponible

Cliquer sur le bouton « Next > ».

Faire « Load » et sélectionner « Graphe » :

Image non disponible

Cliquer sur le bouton « Next > ».

Ne rien modifier :

Image non disponible

Cliquer sur le bouton « Finish ».

Ajout des flèches aux arcs

Dans le projet « exemple.graphe.gmf », éditer le fichier « model > Graphe.gmfgraph » :

Image non disponible

Modifier « property » Name de « Polyline Decoration » :

Image non disponible

Modifier « property » « Target Decoration » de « Polyline Connection ArcFigure ».

Image non disponible

VII-E. Génération du « Tooling Def Model »

Cliquer sur « Derive » :

Image non disponible

Sélectionner le répertoire « model » du projet « exemple.graphe.gmf » :

Image non disponible

Cliquer sur le bouton « Next > ».

Cliquer sur « Load », sélectionner « Graphe » :

Image non disponible

Cliquer sur le bouton « Next > » :

Image non disponible

Cliquer sur le bouton « Finish » pour obtenir :

Image non disponible

VII-F. Génération du « Mapping Model »

Cliquer sur « Combine » :

Image non disponible

Sélectionner le répertoire « model » du projet « exemple.graphe.gmf » :

Image non disponible

Cliquer sur le bouton « Next > ».

Cliquer « Load », sélectionner « Graphe » :

Image non disponible

Cliquer sur le bouton « Next > ».

Image non disponible

Cliquer sur « Load » puis sur le bouton « Next > ».

Image non disponible

Cliquer sur le bouton « Load » puis sur « Next > », pour obtenir :

Image non disponible

Modifier le « mapping » :

Image non disponible

Dans « Links », sélectionner « Arc(<unspecified>;listeArcs) » et cliquer « Change... ».

Éditer les « Properties » :

Image non disponible

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 » :

Image non disponible

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 » :

Image non disponible

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.

Image non disponible

Valider le graphe :

On sélectionne « G1.graphe » et on utilise le menu contextuel de l'éditeur :

Image non disponible

Le message suivant s'affiche :

Image non disponible

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 :

Image non disponible

Seuls les problèmes liés aux noms des arcs sont affichés :

Image non disponible

Modifier le modèle en nommant les arcs en utilisant les properties :

Image non disponible

La validation donne :

Image non disponible

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/.