Vous êtes sur la page 1sur 27

Tutoriel sur la création et l'instanciation de

modèles avec Eclipse Modeling Framework (EMF)

Par Mickael Baron

Date de publication : 17 juin 2013

Dernière mise à jour : 18 novembre 2014

Le but de cette série d'exercices est d'apprendre à manipuler le framework de modélisation


d'Eclipse appelé EMF. Nous couvrirons tous les aspects liés aux développements dirigés
par les modèles avec les briques logiciels fournies par la plateforme Eclipse. La version
Eclipse avec le package modeling sera utilisée à cet effet.

• conception de modèles EMF ;


• génération de code Java ;
• manipulation d'API EMF pour instancier le modèle ;
• manipulation du métamodèle Ecore ;
• sauvegarde et chargement de fichiers XMI.

Les sources des exemples sont disponibles ici.

Une version sans illustration est disponible sur Github : https://github.com/mickaelbaron/


emf-tutorial.

Pour réagir à cet article, un espace de dialogue vous est proposé sur le forum Commentez.
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

I - Introduction..............................................................................................................................................................3
I-A - Connaissances requises................................................................................................................................ 3
I-B - Prérequis logiciel............................................................................................................................................3
II - Exercice 1 : Création du modèle EMF d'un carnet d'adresses............................................................................. 3
II-A - But................................................................................................................................................................. 3
II-B - Description.....................................................................................................................................................3
II-C - Étapes à suivre.............................................................................................................................................4
III - Exercice 2 : Génération de codes Java............................................................................................................... 8
III-A - But................................................................................................................................................................ 8
III-B - Description....................................................................................................................................................8
III-C - Etapes à suivre............................................................................................................................................8
IV - Exercice 3 : Création d'instances via l'éditeur généré....................................................................................... 14
IV-A - But..............................................................................................................................................................14
IV-B - Description................................................................................................................................................. 14
IV-C - Étapes à suivre......................................................................................................................................... 14
V - Exercice 4 : Création d'instances via l'API EMF : EarlyBinding.......................................................................... 20
V-A - But...............................................................................................................................................................20
V-B - Description.................................................................................................................................................. 20
V-C - Étapes à suivre.......................................................................................................................................... 20
VI - Exercice 5 : Manipulation du métamodèle Ecore : LateBinding......................................................................... 23
VI-A - But..............................................................................................................................................................23
VI-B - Description................................................................................................................................................. 23
VI-C - Interroger le métamodèle Ecore................................................................................................................24
VI-D - Création d'instances via le métamodèle Ecore......................................................................................... 25
VII - Conclusion et remerciements............................................................................................................................ 27

-2-
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

I - Introduction

Cet article se présente sous la forme d'un atelier composé de cinq exercices guidés :

• un premier exercice s'intéresse à la construction d'un modèle EMF ;


• un deuxième exercice montre comment générer du code Java et des outils d'assistance à partir du modèle
EMF ;
• le troisième exercice explique comment instancier le modèle EMF à partir d'un éditeur graphique généré ;
• le quatrième exercice présente l'instanciation du modèle EMF en utilisant directement les codes Java générés
(technique appelée EarlyBinding) ;
• le dernier exercice présente l'instanciation du modèle EMF en utilisant le métamodèle Ecore (technique
appelée LateBinding).

I-A - Connaissances requises

Cet article suppose que vous possédez quelques notions théoriques sur les aspects liés à l'Ingénierie Dirigée par
les Modèles (IDM). Vous pouvez parcourir cet article pour vous familiariser sur les concepts de modèles et des
métamodèles.

De même sur les aspects pratiques, je vous recommande de parcourir mon support de cours consacré aux
technologies EMF dédiées à l'IDM.

Enfin, quelques notions sur la programmation Java et sur la construction de plugins avec la plate-forme Eclipse
seraient un plus.

I-B - Prérequis logiciel

Pour reproduire les exemples de cet article, vous aurez besoin d'une version Eclipse contenant la plupart des plugins
dédiés à la modélisation. Vous pourrez ainsi vous baser sur la distribution Eclipse Modeling Tools disponible sur
le site de la fondation Eclipse.

II - Exercice 1 : Création du modèle EMF d'un carnet d'adresses

II-A - But

Trois principaux objectifs seront visés :

• démarrer un projet EMF ;


• créer un modèle EMF avec les outils d'Eclipse ;
• manipuler les différents éditeurs.

II-B - Description

L'exemple qui illustre cet article est un carnet d'adresses. Ce dernier est identifié par un nom et contient une liste
de personnes (contains). Une personne est identifiée par un prénom, un nom et un âge. Une personne contient
obligatoirement une adresse (location). Une adresse est identifiée par un numéro et un nom de rue.

Le modèle UML donné ci-dessous représente graphiquement la modélisation attendue pour cet exercice. Nous nous
intéressons ici à créer le modèle UML présenté via les outils d'Eclipse.

-3-
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

Modélisation UML d'un carnet d'adresses

II-C - Étapes à suivre

• Démarrer l'environnement de développement Eclipse contenant les plugins de modélisation puis créer un
nouveau Workspace (workspaceEMF) afin de disposer d'un répertoire spécifique à la modélisation.
• Pour afficher les vues Eclipse spécifiques à la modélisation EMF, ouvrir la perspective Ecore.

• Créer un nouveau projet EMF vide (File -> New -> Project … -> Eclipse Modeling Framework - > Empty EMF
Project) et nommer le projet eclipse.emf.addressbook.

-4-
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

• Sélectionner le répertoire model et créer un diagramme Ecore (Ecore Diagram). Nommer le fichier ecore
addressbook.ecore.

• Construire les trois classes, définir tous les attributs et créer les associations entre les classes. Veuillez
respecter les contraintes de cardinalités exprimées sur le modèle UML précédent. Aidez-vous de la vue
Properties afin de spécifier les cardinalités voulues.

-5-
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

Vous pouvez visualiser votre modèle sous différentes représentations via l'utilisation
d'éditeurs adaptés : OCLinEcore (Ecore) Editor et Sample Ecore Model Editor. Bien entendu,
cette liste n'est pas exhaustive et d'autres éditeurs sont également disponibles. Il suffira juste
d'installer les plugins adéquates si nécessaires.

Visualisation du modèle EMF Carnet d'adresses via l'éditeur OCLinEcore

-6-
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

Visualisation du modèle EMF Carnet d'adresses via l'éditeur Sample Ecore Model Editor

• Visualiser finalement votre modèle au format XML, vous remarquerez qu'il s'agit d'un fichier XMI dont les
données correspondent à des instances du métamodèle Ecore. Nous reviendrons sur cette notion dans les
prochaines sections.

1. <?xml version="1.0" encoding="UTF-8"?>


2. <ecore:EPackage xmi:version="2.0"
3. xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4. xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="addressbook"
5. nsURI="http://addressbook/1.0" nsPrefix="addressbook">
6. <eClassifiers xsi:type="ecore:EClass" name="AddressBook">
7. <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType
http://www.eclipse.org/emf/2002/Ecore#//EString"/>
8. <eStructuralFeatures xsi:type="ecore:EReference" name="contains" upperBound="-1"
9. eType="#//Person" containment="true"/>
10. </eClassifiers>
11. <eClassifiers xsi:type="ecore:EClass" name="Person">
12. <eOperations name="display" eType="ecore:EDataType http://www.eclipse.org/emf/2002/
Ecore#//EString"/>
13. <eStructuralFeatures xsi:type="ecore:EAttribute" name="familyName" eType="ecore:EDataType
http://www.eclipse.org/emf/2002/Ecore#//EString"/>
14. <eStructuralFeatures xsi:type="ecore:EAttribute" name="firstName" eType="ecore:EDataType
http://www.eclipse.org/emf/2002/Ecore#//EString"/>
15. <eStructuralFeatures xsi:type="ecore:EAttribute" name="age" eType="ecore:EDataType
http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
16. <eStructuralFeatures xsi:type="ecore:EReference" name="location" lowerBound="1"
17. eType="#//Address" containment="true"/>
18. <eStructuralFeatures xsi:type="ecore:EAttribute" name="identifier" eType="ecore:EDataType
http://www.eclipse.org/emf/2002/Ecore#//EString"
19. changeable="false" volatile="true" transient="true" derived="true"/>
20. </eClassifiers>
21. <eClassifiers xsi:type="ecore:EClass" name="Address">
22. <eStructuralFeatures xsi:type="ecore:EAttribute" name="number" eType="ecore:EDataType
http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
23. <eStructuralFeatures xsi:type="ecore:EAttribute" name="street" eType="ecore:EDataType
http://www.eclipse.org/emf/2002/Ecore#//EString"/>
24. </eClassifiers>
25. </ecore:EPackage>

-7-
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

III - Exercice 2 : Génération de codes Java

III-A - But

Quatre principaux objectifs seront visés :

• Créer un modèle de génération à partir d'un Ecore ;


• Paramétrer le modèle de génération de code ;
• Générer un code Java correspondant au modèle EMF ;
• Mettre à jour modèle, re-générer le code et modifier le code généré.

III-B - Description

Nous nous intéressons maintenant à toutes les étapes de génération de code à partir d'un modèle EMF. Nous
nous intéressons également aux étapes de re-génération et de protection des codes modifiés par le développeur.
Un modèle supplémentaire est requis et dédié à cette tâche. Il contient les informations dédiées uniquement à la
génération et qui ne pourraient pas être intégrées au modèle EMF (chemin de génération, package, préfixe…). Ce
modèle appelé genmodel est également un modèle EMF et chaque classe du modèle de génération est un décorateur
des classes Ecore.

III-C - Etapes à suivre

• Créer un modèle de génération (New -> Other… -> Eclipse Modeling Framework -> EMF Generator
Model), sélectionner ensuite le répertoire model du projet eclipse.emf.addressbook puis nommer le fichier
addressbook.genmodel.

• Sélectionner ensuite Ecore model comme type de modèle utilisé pour créer ce modèle de génération.

-8-
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

• Sélectionner enfin le fichier addressbook.ecore (à partir de la navigation du Workspace courant Browse


Workspace…) puis terminer.

• Modifier le contenu du fichier genmodel pour que le package de génération soit


eclipse.emf.addressbook.model (propriétés : Base Package). Utiliser pour cela la vue Properties en modifiant
l'attribut Base Package.

-9-
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

• Sélectionner depuis le fichier genmodel le package racine Addressbook et générer le code Java
correspondant au modèle (Generate Model Code). Un ensemble de classes Java doivent être générées dans
le package eclipse.emf.addressbook.model.addressbook.
• Examiner les classes générées et remarquer le découpage en trois catégories qui font apparaître une
programmation par contrats : interfaces, implémentations et classes utilitaires.

- 10 -
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

Nous décidons par la suite de modifier le modèle de façon à :

• ajouter un attribut dérivé dans Person appelé identifier de type String qui retourne une chaîne de type
(firstName + familyName + age),
• ajouter une opération String display() qui se chargera d'effectuer un affichage complet d'une instance de
Person.

Le schéma ci-dessous représente graphiquement la modélisation attendue par cette modification.

- 11 -
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

• Compléter votre modèle EMF (via l'éditeur Ecore Diagram Editing par exemple) de façon à intégrer les
modifications demandées. Pour l'attribut identifier, déclarer le Derived, Volatile, Transient et non Changeable.

Cela a pour effet pour l'attribut identifier :

• derived : calculé à partir d'autres attributs,


• volatile : ne génère par l'attribut pour stocker l'état, le corps de la méthode est également laissé à vide,
• transient : ne sera pas sauvegardé,
• changeable : valeur pouvant changer

- 12 -
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

• Le fichier addressbook.ecore est automatiquement impacté. Toutefois, le fichier genmodel doit être
explicitement mis à jour. Sélectionner le fichier addressbook.genmodel puis cliquer sur Reload (via le menu
contextuel). Sélectionner ensuite Ecore model et laisser les valeurs par défaut puis valider. Vous remarquerez
que les nouveaux attributs ont été ajoutés et que les anciennes valeurs de configuration de génération (Base
Package en l'occurrence) n'ont pas été supprimées.
• Impacter la classe eclipse.emf.addressbook.model.addressbook.impl.PersonImpl de façon à implémenter les
méthodes getIdentifier() et display(), voir le code ci-dessous.

1. /**
2. * <!-- begin-user-doc -->
3. * <!-- end-user-doc -->
4. * @generated NOT
5. */
6. public String getIdentifier() {
7. return this.getFirstName() + this.getFamilyName() + this.getAge();
8. }
9.
10. /**
11. * <!-- begin-user-doc -->
12. * <!-- end-user-doc -->
13. * @generated NOT
14. */
15. public String display() {
16. StringBuffer sb = new StringBuffer();
17. sb.append("FirstName:").append(this.getFirstName())
18. .append(" FamilyName:").append(this.getFamilyName())
19. .append(" Age:").append(this.getAge())
20. .append(" Address:").append(this.getLocation());
21. return sb.toString();
22. }

- 13 -
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

Remarquer que l'en-tête des méthodes getIdentifier() et display() contient l'annotation @generated NOT. Cette
dernière annotation permet d'empêcher que le code modifié par le développeur soit écrasé par la génération.

• Re-générer les codes Java (Generate Model Code) et s'assurer que le code saisi n'a pas été modifié.

IV - Exercice 3 : Création d'instances via l'éditeur généré

IV-A - But

Quatre principaux objectifs seront visés :

• Générer un éditeur graphique ;


• Exécuter une configuration d'exécution ;
• Créer des instances via l'éditeur généré ;
• Valider des contraintes.

IV-B - Description

Nous allons maintenant générer le code correspondant à un éditeur graphique. Cet éditeur sera utilisé pour créer
graphiquement des instances de notre modèle. Nous vérifierons par ailleurs la validité de notre modèle par rapport
à un jeu d'instances.

IV-C - Étapes à suivre

• À partir du modèle de génération (genmodel), ouvrir l'éditeur EMF Generator et générer le code de l'éditeur
(Generate Edit Code et Generate Editor Code).

Deux plugins doivent être créés (eclipse.emf.addressbook.edit et eclipse.emf.addressbook.editor).

- 14 -
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

• Passer en perspective Java et créer une configuration d'exécution (Run -> Run Configurations…) à partir d'un
type Eclipse Application. Nommer cette configuration AddressBookConfiguration, puis modifier la valeur de
son chemin avec cette valeur (${workspace_loc}/runtime-AddressBookConfiguration).

• Ajouter à cette configuration d'exécution les trois plugins (addressbook, edit et editor).
• Décocher Target Platform puis faites Add Required Plug-ins.
• Ajouter enfin le plugin org.eclipse.ui.ide.application et org.eclipse.ui.navigator.resources et faites une nouvelle
fois Add Required Plug-ins.

- 15 -
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

• Exécuter cette configuration d'exécution. Une nouvelle instance d'Eclipse s'exécute en intégrant votre éditeur
de modèle de carnet d'adresse.
• Créer un simple projet (File -> New -> Project… -> General -> Project) que vous appellerez
AddressBookSampleInstances.
• À partir de cette nouvelle instance, créer une instance du modèle AddressBook (File -> New -> Other… ->
Example EMF Model Creation Wizards -> Addressbook Model) que vous appellerez Sample.addressbook.
Choisir ensuite Address Book comme modèle objet à créer.

- 16 -
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

- 17 -
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

- 18 -
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

• Construire les instances via l'éditeur associé à votre modèle en s'appuyant sur les instances données ci-
dessous.

1. <addressbook:AddressBook ...>
2. <contains familyName="DUPONT" firstName="Raoul" age="37">
3. <location number="1" street="Rue DotNet"/>
4. </contains>
5. <contains familyName="BARON" firstName="Mickael" age="36">
6. <location number="50" street="Place de Java"/>
7. </contains>
8. <contains familyName="SARPOL" firstName="John" age="38">
9. <location number="50" street="Square Express"/>
10. </contains>
11. </addressbook:AddressBook>

- 19 -
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

• Sélectionner le nœud racine de vos instances et valider ces instances en cliquant sur Validate (via le menu
contextuel).

V - Exercice 4 : Création d'instances via l'API EMF : EarlyBinding

V-A - But

Trois principaux objectifs seront visés :

• Créer des instances via l'API EMF ;


• Créer un plugin (fragment) de test ;
• Sauvegarder et charger via l'API EMF des instances via un XMI.

V-B - Description

Nous allons, dans cet exercice, créer des instances d'un modèle de manière programmatique. Dans ce cas les plugins
générés précédemment (Edit et Editor) ne seront pas utilisés. Nous utiliserons un plugin spécifique appelé fragment
(utilisé pour enrichir un plugin existant) pour créer des classes de tests.

V-C - Étapes à suivre

• Créer un nouveau plugin de type fragment (File -> New -> Other…-> Plug-in Development -> Fragment
Project) nommé eclipse.emf.addressbook.test. Choisir comme plugin hôte eclipse.emf.addressbook (créé
dans la section II). Une fois le fragment créé, ajouter la dépendance vers le plugin org.junit (4.8.2) (onglet
Dependencies quand le fichier MANIFEST.MF est en cours d'édition).
• Créer un package eclipse.emf.addressbook.model.test et créer une classe appelée AddressBookTest.

- 20 -
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

• Depuis AddressBookTest compléter la méthode de tests createAddressBookTest en s'assurant que les


assertions associées soient vraies.

1. public class AddressBookTest {


2. @Test
3. public void createAddressBookTest() {
4. AddressBook createAddressBook = AddressbookFactory.eINSTANCE.createAddressBook();
5. createAddressBook.setName("Mon Carnet d'Adresses");
6.
7. Address createMBAddress = AddressbookFactory.eINSTANCE.createAddress();
8. createMBAddress.setNumber(50);
9. createMBAddress.setStreet("Place de Java");
10. Person mickaelBaron = AddressbookFactory.eINSTANCE.createPerson();
11. mickaelBaron.setAge(36);
12. mickaelBaron.setFamilyName("BARON");
13. mickaelBaron.setFirstName("Mickael");
14. mickaelBaron.setLocation(createMBAddress);
15.
16. Address createDRAddress = AddressbookFactory.eINSTANCE.createAddress();
17. createDRAddress.setNumber(1);
18. createDRAddress.setStreet("Rue DotNet");
19. Person raoulDupont = AddressbookFactory.eINSTANCE.createPerson();
20. raoulDupont.setAge(37);
21. raoulDupont.setFamilyName("DUPONT");
22. raoulDupont.setFirstName("Raoul");
23. raoulDupont.setLocation(createDRAddress);
24.
25. Address createSJAddress = AddressbookFactory.eINSTANCE.createAddress();
26. createSJAddress.setNumber(50);
27. createSJAddress.setStreet("Square Express");
28. Person johnSarpol = AddressbookFactory.eINSTANCE.createPerson();
29. johnSarpol.setAge(38);
30. johnSarpol.setFamilyName("SARPOL");
31. johnSarpol.setFirstName("John");
32. johnSarpol.setLocation(createSJAddress);
33.
34. createAddressBook.getContains().add(mickaelBaron);
35. createAddressBook.getContains().add(raoulDupont);
36. createAddressBook.getContains().add(johnSarpol);
37.
38. Assert.assertEquals(3, createAddressBook.getContains().size());
39. Assert.assertEquals("Mon Carnet d'Adresses", createAddressBook.getName());
40. Assert.assertEquals("BARON", mickaelBaron.getFamilyName());
41. Assert.assertEquals("Raoul", raoulDupont.getFirstName());
42. Assert.assertEquals("JohnSARPOL38", johnSarpol.getIdentifier());
43. ...
44. }
45. }

Les instances des classes sont obtenues par l'utilisation de la fabrique AddressbookFactory (ligne 4). Le reste des
modifications ne vous sera pas étranger.

Pour l'exécution du test unitaire, il doit se faire obligatoirement dans un environnement de


plugins (Run As JUnit Plug-in Test).

- 21 -
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

On s'intéresse maintenant à sauvegarder et charger le contenu des instances depuis un fichier XMI.

• Compléter la méthode de tests de manière à sauvegarder les instances créées précédemment (voir code ci-
dessous). Vous adapterez le chemin de sauvegarde du fichier APISample.addressbook (ligne 6) en rapport
avec celui utilisé pour sauvegarder Sample.addressbook. Le fichier d'instances sera stocké dans le répertoire
utilisé par la configuration d'exécution de l'exercice 3.

44. ...
45. ResourceSet resourceSet = new ResourceSetImpl();
46.
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("addressbook",
47. new XMIResourceFactoryImpl());
48.
49. final String apiSamplePath = "D://workspaceEMF_BARON_Mickael//runtime-
50. AddressBookConfiguration//AddressBookSampleInstances//";
51. URI uri = URI.createURI("file:/" + apiSamplePath + "APISample.addressbook");
52. Resource resource = resourceSet.createResource(uri);
53. resource.getContents().add(createAddressBook);
54. try {
55. resource.save(null);
56. } catch (IOException e) {
57. e.printStackTrace();
58. }
59. Assert.assertTrue(new File(apiSamplePath + "APISample.addressbook").exists());
60. ...
61. }
62. }

- 22 -
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

Faites attention à importer le bon package pour la classe URI (import


org.eclipse.emf.common.util.URI; et non import java.net.URI;).

• Ajouter dans votre plugin la dépendance vers le plugin org.eclipse.emf.ecore.xmi et exécuter le test unitaire.
• Compléter la méthode de tests de manière à charger les instances (fichier Sample.addressbook) créées au
début de l'exercice 3, voir ci-dessous le résultat du code.

60. ...
61. resourceSet = new ResourceSetImpl();
62. uri = URI.createURI("file:/" + apiSamplePath + "Sample.addressbook");
63. resource = resourceSet.getResource(uri, true);
64. createAddressBook = (AddressBook) resource.getContents().get(0);
65. Assert.assertEquals("Mon Carnet d'Adresses", createAddressBook.getName());

• Compléter en début de la méthode de façon à ajouter pour les instances de type AddressBook un écouteur
sur les changements. Ainsi à chaque changement opéré sur une instance d'AddressBook, le notifieur
affichera l'ancienne et la nouvelle valeur.

1. public class AddressBookTest {


2. @Test
3. public void createAddressBookTest() {
4. AddressBook createAddressBook = AddressbookFactory.eINSTANCE.createAddressBook();
5. createAddressBook.eAdapters().add(new EContentAdapter() {
6.
7. @Override
8. public void notifyChanged(Notification notification) {
9. System.out.print("Ancienne Valeur : " + notification.getOldValue());
10. System.out.println(" Nouvelle Valeur : " + notification.getNewValue());
11. }
12. });
13. createAddressBook.setName("Mon Carnet d'Adresses");
14. ...
15. }

VI - Exercice 5 : Manipulation du métamodèle Ecore : LateBinding

VI-A - But

Trois principaux objectifs seront visés :

• Manipuler le métamodèle Ecore ;


• Créer des instances via le métamodèle Ecore ;
• Créer des instances via les outils d'Eclipse.

VI-B - Description

Nous allons dans cet exercice manipuler le métamodèle Ecore afin de connaître la structure de notre modèle (puisque
le modèle AddressBook est une instance du métamodèle Ecore). Nous allons également créer et modifier des
instances de notre modèle via le métamodèle Ecore. Finalement nous sauvegarderons et chargerons ces instances
afin d'obtenir un fichier XMI identique à l'exercice 4. L'intérêt de cet exercice est d'utiliser une API de type LateBinding
où le métamodèle Ecore est manipulé. Nous présentons à titre indicatif le métamodèle Ecore.

- 23 -
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

VI-C - Interroger le métamodèle Ecore

Dans la classe AddressBookTest du fragment eclipse.emf.addressbook.test ajouter une méthode appelée


queryAddressBookStructure. L'objectif de cette méthode est d'afficher la structure complète de votre modèle en
interrogeant le métamodèle. Le résultat attendu est donné par la capture d'écran ci-dessous.

Le code donné ci-dessous montre comment obtenir un tel résultat. Vous noterez que le point d'accès au métamodèle
se fait par l'intermédiaire du package AddressbookPackage.

1. @Test
2. public void queryAddressBookStructure() {
3. AddressbookPackage addressbookPackage = AddressbookPackage.eINSTANCE;
4. EList<EClassifier> eClassifiers = addressbookPackage.getEClassifiers();
5.
6. for (EClassifier eClassifier : eClassifiers) {
7. System.out.println(eClassifier.getName());
8. System.out.print(" ");

- 24 -
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

9.
10. if (eClassifier instanceof EClass) {
11. EClass eClass = (EClass) eClassifier;
12. EList<EAttribute> eAttributes = eClass.getEAttributes();
13. for (EAttribute eAttribute : eAttributes) {
14. System.out.print(eAttribute.getName() + "("
15. + eAttribute.getEAttributeType().getName() + ") ");
16. }
17.
18. if (!eClass.getEAttributes().isEmpty()
19. && !eClass.getEReferences().isEmpty()) {
20. System.out.println();
21. System.out.print(" Références : ");
22.
23. EList<EReference> eReferences = eClass.getEReferences();
24. for (EReference eReference : eReferences) {
25. System.out.print(eReference.getName() + "("
26. + eReference.getEReferenceType().getName() + "["
27. + eReference.getLowerBound() + ".."
28. + eReference.getUpperBound() + "])");
29. }
30. }
31.
32. if (!eClass.getEOperations().isEmpty()) {
33. System.out.println();
34. System.out.print(" Opérations : ");
35. for (EOperation eOperation : eClass.getEOperations()) {
36. System.out.println(eOperation.getEType().getName()
37. + " " + eOperation.getName());
38. }
39. }
40. }
41. System.out.println();
42. }
43. }

VI-D - Création d'instances via le métamodèle Ecore

Pour l'instant, nous avons vu que pour créer des instances du modèle nous devions utiliser les classes générées,
approche dite EarlyBinding. Par réflexivité, il est possible de créer et modifier des instances du modèle sans avoir à
manipuler explicitement les classes générées. Nous allons montrer comment réaliser cela.

• Construire un projet EMF vide (File -> Project … -> Eclipse Modeling Framework -> Empty EMF Project) que
vous appellerez eclipse.emf.addressbook.latebinding ;
• Ajouter la dépendance vers les plugin org.junit (4.8.2) et org.eclipse.emf.ecore.xmi ;
• Créer ensuite le package eclipse.emf.addressbook.latebinding et finalement créer la classe
eclipse.emf.addressbook.latebinding.AddressBookLateBinding ;
• Copier votre fichier addressbook.ecore réalisé dans le premier exercice dans le répertoire model de votre
nouveau projet ;

Ce nouveau plugin ne contient aucune dépendance vers les plugins créés précédents.

• Créer une méthode de test appelée queryAddressBookStructureWithoutGeneratedCode dont l'objectif est :


• de charger le fichier addressbook.ecore afin de charger le modèle (accessible via le package racine),
• d'afficher la structure du modèle comme précisée dans la question précédente.

1. @Test
2. public void queryAddressBookStructureWithoutGeneratedCode() {
3. Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
4. Map<String, Object> m = reg.getExtensionToFactoryMap();
5. m.put("ecore", new XMIResourceFactoryImpl());
6. ResourceSet resourceSet = new ResourceSetImpl();
7. URI fileURI = URI.createFileURI("model/addressbook.ecore");
8. Resource resource = resourceSet.getResource(fileURI, true);

- 25 -
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

9.
10. EPackage ePackage = (EPackage) resource.getContents().get(0);
11.
12. EList<EClassifier> eClassifiers = ePackage.getEClassifiers();
13.
14. for (EClassifier eClassifier : eClassifiers) {
15. System.out.println(eClassifier.getName());
16. System.out.print(" ");
17.
18. if (eClassifier instanceof EClass) {
19. EClass eClass = (EClass) eClassifier;
20. EList<EAttribute> eAttributes = eClass.getEAttributes();
21. for (EAttribute eAttribute : eAttributes) {
22. System.out.print(eAttribute.getName() + "("
23. + eAttribute.getEAttributeType().getName() + ") ");
24. }
25.
26. if (!eClass.getEAttributes().isEmpty()
27. && !eClass.getEReferences().isEmpty()) {
28. System.out.println();
29. System.out.print(" Références : ");
30. }
31.
32. EList<EReference> eReferences = eClass.getEReferences();
33. for (EReference eReference : eReferences) {
34. System.out.print(eReference.getName() + "("
35. + eReference.getEReferenceType().getName() + "["
36. + eReference.getLowerBound() + ".."
37. + eReference.getUpperBound() + "])");
38. }
39.
40. if (!eClass.getEOperations().isEmpty()) {
41. System.out.println();
42. System.out.print(" Opérations : ");
43.
44. for (EOperation eOperation : eClass.getEOperations()) {
45. System.out.println(eOperation.getEType().getName()
46. + " " + eOperation.getName());
47. }
48. }
49. }
50. System.out.println();
51. }
52. }

• Créer une méthode appelée createAndSaveAddressBookWithMetaModel (voir code ci-dessous) dont l'objectif
est :
• de charger le fichier addressbook.ecore correspondant à notre modèle (accessible via le package
racine),
• de créer des instances identiques à celles créées pendant l'exercice 4 sans avoir à manipuler
explicitement les classes Java du modèle. Cette façon de procéder est dite Dynamique.

1. @Test
2. public void createAndSaveAddressBookWithMetaModel() throws IOException {
3. Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
4. Map<String, Object> m = reg.getExtensionToFactoryMap();
5. m.put("ecore", new XMIResourceFactoryImpl());
6.
7. ResourceSet resourceSet = new ResourceSetImpl();
8. URI fileURI = URI.createFileURI("model/addressbook.ecore");
9. Resource resource = resourceSet.createResource(fileURI);
10.
11. resource.load(null);
12. EPackage ePackage = (EPackage) resource.getContents().get(0);
13.
14. EClass eAddressBook = (EClass) ePackage.getEClassifier("AddressBook");
15. EReference eContains = (EReference) eAddressBook
16. .getEStructuralFeature("contains");
17. EAttribute eName = (EAttribute) eAddressBook
18. .getEStructuralFeature("name");

- 26 -
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/
Tutoriel sur la création et l'instanciation de modèles avec Eclipse Modeling Framework (EMF) par Mickael Baron

19. EObject addressBookInstance = ePackage.getEFactoryInstance().create(


20. eAddressBook);
21. addressBookInstance.eSet(eName, "Mon Carnet d'Adresses");
22.
23. EClass ePerson = (EClass) ePackage.getEClassifier("Person");
24. EAttribute eFirstName = (EAttribute) ePerson
25. .getEStructuralFeature("firstName");
26. EAttribute eFamilyName = (EAttribute) ePerson
27. .getEStructuralFeature("familyName");
28. EObject personInstance = ePackage.getEFactoryInstance().create(ePerson);
29. personInstance.eSet(eFirstName, "Mickael");
30. personInstance.eSet(eFamilyName, "BARON");
31.
32. List<EObject> containsList = new ArrayList<EObject>();
33. containsList.add(personInstance);
34. addressBookInstance.eSet(eContains, containsList);
35.
36. resourceSet = new ResourceSetImpl();
37. resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap()
38. .put("xmi", new XMIResourceFactoryImpl());
39. URI uri = URI.createURI("file:/addressbookinstancesonlymodel.xmi");
40. resource = resourceSet.createResource(uri);
41. resource.getContents().add(addressBookInstance);
42. resource.save(null);
43.
44. resourceSet = new ResourceSetImpl();
45. resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap()
46. .put("xmi", new XMIResourceFactoryImpl());
47. Registry packageRegistry = resourceSet.getPackageRegistry();
48. packageRegistry.put("http://addressbook/1.0", ePackage);
49.
50. uri = URI.createURI("file:/addressbookinstancesonlymodel.xmi");
51. resource = resourceSet.getResource(uri, true);
52. resource.load(null);
53. DynamicEObjectImpl
addressBookImpl = (DynamicEObjectImpl)(resource.getContents().get(0));
54. EClass addressBook = addressBookImpl.eClass();
55. EAttribute nameAttribute = (EAttribute)(addressBook.getEStructuralFeature("name"));
56. EReference
containsAttribute = (EReference)(addressBook.getEStructuralFeature("contains"));
57. Assert.assertEquals("Mon Carnet d'Adresses", addressBookImpl.eGet(nameAttribute));
58.
59. EcoreEList eGets = (EcoreEList)addressBookImpl.eGet(containsAttribute);
60. DynamicEObjectImpl personImpl = (DynamicEObjectImpl)eGets.get(0);
61. EClass person = personImpl.eClass();
62. EAttribute familyName = (EAttribute)person.getEStructuralFeature("familyName");
63. EAttribute firstName = (EAttribute)person.getEStructuralFeature("firstName");
64. Assert.assertEquals("BARON", personImpl.eGet(familyName));
65. Assert.assertEquals("Mickael", personImpl.eGet(firstName));
66. }

Noter pour la dernière partie du code (ligne 53), l'apparition d'une nouvelle classe appelée DynamicEObjectImpl.
Il s'agit d'une implémentation de l'interface EObject. Cette classe est employée quand l'utilisation dynamique est
utilisée pour la création des instances.

VII - Conclusion et remerciements

Cet atelier vous montre toutes les facettes de la création et de l'instanciation de modèles EMF. La plateforme Eclipse
via son framework EMF fournit un outillage pour faciliter la manipulation. Toutefois, il peut être intéressant de se
détacher des outils graphiques afin de mieux cerner les APIs sous-jacentes.

Dans un prochain atelier, nous ajouterons une couche graphique à notre modèle.

Je tiens à remercier Gueritarish et alain.bernard pour la relecture technique. Je tiens également à remercier ced
pour sa relecture orthographique.

- 27 -
Le contenu de cet article est rédigé par Mickael BARON et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non
transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2018 Developpez.com.
https://mbaron.developpez.com/tutoriels/eclipse/emf/creation-instanciation-modeles/

Vous aimerez peut-être aussi