Génération d'un éditeur arborescent pour l'édition des instances d'un modèle EMF

Serge Bachmann

Cet article fait suite à l'article traitant de l'édition graphique d'un modèle EMF. Nous nous intéressons ici à concevoir un éditeur arborescent généré automatiquement à partir de la description du modèle EMF.

Pour réagir à cet article, un espace de dialogue vous est proposé sur le forum Commentez .

- Titre : Génération d'un éditeur arborescent pour l'édition des instances d'un modèle EMF

- Auteur : Serge Bachmann

- Parution : 29 février 2012

- Licence : Le contenu de cet article est rédigé par Serge Bachmann et est mis à disposition selon les termes de la Licence Creative Commons Attribution 3.0 non transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2013 Developpez.com.

Sommaire

- I. Introduction

- I-A. Spécification

- I-B. Lancement de la plate-forme Eclipse

- I-C. Passage en perspective « Ecore »

- II. Édition du modèle EMF décrivant un graphe

- II-A. Création du projet

- II-B. Ouverture de l'éditeur

- II-C. Édition

- III. Création projet EMF

- IV. Génération du code associé au modèle

- V. Test de l'éditeur

- V-A. Édition du modèle

- V-A-1. Création « Noeud »

- VI. Accès au modèle édité

- VI-A. Création de la commande « View Model »

- VI-A-1. Création du « package » pour recevoir le code de la commande

- VI-A-2. Création de l'arbre des extensions

- VI-A-3. Le code du « handler »

- VI-B. Test de la commande « View Model »

- VII. Conclusions

- VIII. Licence

I - Introduction

I-A - Spécification

À partir d'un modèle EMF de graphe précédemment défini, on génère un éditeur arborescent de graphe.

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 :

On sélectionne le « workspace » :

« E:\FORMATION_Eclipse\modeling-indigo-SR1\EMT\WS\GenerationEditeurArborescent »

Cliquer « OK ». Fermer la fenêtre « Welcome ».

I-C - Passage en perspective « Ecore »

Faire :

Sélectionner la perspective « Ecore »

Cliquer « OK », on obtient :

II - Édition du modèle EMF décrivant un graphe

II-A - Création du projet

Un nouveau projet est créé :

Nommer le projet :

Cliquer « Finish ». Le projet est créé.

II-B - Ouverture de l'éditeur

Faire :

Initialiser « Domain file name » :

Cliquer « Finish ».

L'éditeur apparaît, on ferme quelques fenêtres, mais on garde les « Properties » :

II-C - Édition

Si nécessaire se reporter à l'article Édition graphique d'un modèle EMF.

Éditer le modèle EMF. Faire une sauvegarde générale :

On peut valider le modèle « Graphe.ecore » :

III - Création projet EMF

Faire :

Sélectionner :

Cliquer « Next > ». Nommer le projet :

Cliquer « Next > ».

Sélectionner « Ecore model »

Cliquer « Next ». Dans « New EMF Project - Ecore Import » utiliser « Browse Workspace... » pour importer le modèle :

Cliquer « OK », on obtient :

Cliquer « Load » puis « Next > ».

Dans « New EMF Project - Package Selection », sélectionner « Graphe.ecore ».

Cliquer « Finish ». Le projet « exemple.graphe.emf » est créé. Double-cliquer « Graphe.genmodel », sélectionner « Graphe » et initialiser « Base Package » à « exemple.graphe » :

Faire une sauvegarde générale.

IV - Génération du code associé au modèle

Dans le menu contextuel de l'éditeur de « model>Graphe.genmodel » sélectionner « Generate All »

Trois nouveaux projets sont générés :

En particulier « exemple.graphe.emf.editors » qui est un éditeur arborescent du modèle défini par le

métamodèle « Ecore »

V - Test de l'éditeur

L'éditeur arborescent correspond au projet « exemple.graphe.emf.editor ».

Nous allons tester cet éditeur sans générer le plugin. Faire :

Dans « Run Configurations - Create, manage, and run configurations » sélectionner « Eclipse Application » par un double-clic . Initialiser « Name: » , « Location : » est mis à jour :

Faire « Apply » puis « Run » Une nouvelle plateforme Eclipse est lancée, son « Workspace » est « runtime-GenerationEditeurArborescent ».

Fermer la fenêtre « Welcome » et quelques vues... :

Faire :

Choisir le type de projet :

Cliquer « Next > »

Nommer le projet :

Cliquer « Finish ».

Faire :

Sélectionner :

Cliquer « Next > »

Nommer le graphe :

Cliquer « Next > ».

Sélectionner l'objet du modèle à créer :

Cliquer « Finish ».

On obtient :

V-A - Édition du modèle

Faire apparaître la vue properties :

V-A-1 - Création « Noeud »

Faire :

Initialiser le nom du nœud dans la vue « Properties ». Cliquer dans la vue « G1.graphe » pour que le nom soit mis à jour, on peut alors faire une sauvegarde.

On édite très simplement le modèle :

Remarque : si une mise à jour des « Properties » n'est pas prise en compte faire un clic dans l'éditeur.

Faire une sauvegarde générale.

Quitter la plateforme de test.

VI - Accès au modèle édité

Nous souhaitons accéder au modèle édité afin de réaliser un traitement de ce modèle.

Nous allons créer une commande qui affiche dans un message le « Graphe » édité.

VI-A - Création de la commande « View Model »

VI-A-1 - Création du « package » pour recevoir le code de la commande

Dans le projet « exemple.graphe.emf.editor » on crée sous « src » un « package » destiné à recevoir le code (Handler) associé à la commande :

Nommer le « package » :

Cliquer « Finish » le « package » est créé.

VI-A-2 - Création de l'arbre des extensions

Nous traiterons rapidement la mise en place de la commande, pour plus de précision se reporter au document « Plug-ins - Premier Plug-in ».

Pour créer la commande dans le projet « exemple.graphe.emf.editor » on ouvre le « plug-in Manifest Editor » onglet « Extension » afin de créer l'arbre des extensions suivant :

On retrouve l'ensemble des « Extension Details » associées aux extensions que l'on vient de créer dans le fichier plugin.xml (onglet « plugin.xml »)

<extension
point="org.eclipse.ui.commands">

<command
id="command.viewModel"
name="View Model">
</command>
</extension>
<extension
point="org.eclipse.ui.handlers">
<handler
class="monCode.ViewModel"
commandId="command.viewModel">
</handler>
</extension>
<extension
point="org.eclipse.ui.menus">
<menuContribution
allPopups="false"
locationURI="menu:org.eclipse.ui.main.menu?after=additions">
<menu
id="processModel"
label="Process Model">
<command
commandId="command.viewModel"
style="push">
</command>
</menu>
</menuContribution>
</extension>

VI-A-3 - Le code du « handler »

package monCode;

import java.util.Iterator;

import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.commands.IHandlerListener;
import org.eclipse.emf.common.util.EList;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.handlers.HandlerUtil;

import exemple.graphe.graphe.Arc;
import exemple.graphe.graphe.Noeud;
import exemple.graphe.graphe.impl.GrapheImpl;

publicclass ViewModel implements IHandler {

@Override
publicvoid addHandlerListener(IHandlerListener handlerListener) {
// TODO Auto-generated method stub

}

@Override
publicvoid dispose() {
// TODO Auto-generated method stub

}

String titre;
Shell shell;

@Override
public Object execute(ExecutionEvent event) throws ExecutionException {

titre = HandlerUtil.getActiveEditor(event).getTitle();
shell = HandlerUtil.getActiveWorkbenchWindow(event).getShell();
ISelection selection = HandlerUtil.getCurrentSelection(event);
Object first = ((TreeSelection) selection).getFirstElement();
GrapheImpl graphe;
try {
graphe = (GrapheImpl) first;
vueModel(graphe);
} catch (Exception e) {
// TODO Auto-generated catch block
MessageDialog.openError(shell,
"Graph Editor", "Sélectionner: Graphe");
}
returnnull;
}

privatevoid vueModel(GrapheImpl graphe){
String message = new String("");
message = "Fichier: "+titre+"\n";
message += "Liste des noeuds\n";
EList<Noeud> listeNoeuds = graphe.getListeNoeuds();
Iterator<Noeud> in = listeNoeuds.iterator();
while (in.hasNext()){
Noeud n = in.next();
message += "   "+n.getNom()+"\n";
}
message += "Liste des arcs\n";
EList<Arc> listeArcs = graphe.getListeArcs();
Iterator<Arc> ia = listeArcs.iterator();
while (ia.hasNext()){
Arc a = ia.next();
message += "   "+a.getNom()+
"("+a.getOrigine().getNom()+
"->"+a.getExtremite().getNom()+")\n";
}

MessageDialog.openInformation(shell, "View Model", message);

}

@Override
publicboolean isEnabled() {
// TODO Auto-generated method stub
returntrue;
}

@Override
publicboolean isHandled() {
// TODO Auto-generated method stub
returntrue;
}

@Override
publicvoid removeHandlerListener(IHandlerListener handlerListener) {
// TODO Auto-generated method stub
}

}

Le modèle édité est récupéré via la sélection. On vérifie que la sélection correspond bien à la sélection d'un graphe. Puis on accède au modèle édité en utilisant les définitions du métamodèle :

Par exemple, à partir du graphe, les méthodes : graphe.getListeNoeuds() et graphe.getListeArcs()

permettent respectivement d'accéder la liste des Nœuds et la liste des Arcs...

VI-B - Test de la commande « View Model »

On lance l'éditeur : , on récupère le modèle précédemment édité :

Sélectionner dans la zone d'édition « Graphe » puis la commande « Process Model > View Model »

Le message suivant s'affiche :

Attention si « Graphe » n'est pas sélectionné un message d'erreur s'affiche :

VII - Conclusions

À partir d'un modèle EMF, un éditeur arborescent est généré. Cette forme d'édition peut conduire à une représentation du modèle peu dense. Les attributs des objets (à part les noms) sont affichés uniquement dans la vue « Properties ». Il n'est donc pas possible de visualiser la totalité du modèle dans l'éditeur.

Ici on voit la définition de l' « Arc 2 » :

Il faut sélectionner l' «Arc 1 » pour voir sa définition :

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