Cedric Dumoulin Plan Objectifs Elément Ancêtre commun Tout éléments doit être contenu dans un autre sauf la racine Notion de Profile Utiliser le profil Ecore Créer un datatype Utiliser des Strings Dérivés Notion de packages Pour organiser les modèles Union de listes Objectifs Répertorier les bonnes pratiques pour la conception de métamodèles : Avoir un élément ancêtre commun Avoir une notion de ‘package’ pour organiser les modèles Définir des datatypes Utiliser les dérivés afin d’éviter la duplication d’information … Elément Ancêtre commun Permet d’avoir un type représentant n’importe quel concept du MM Tous les concepts du métamodèle héritent directement ou indirectement de ce concept commun Equivalent à la classe java Object Peut servir pour mettre les attributs ou méthodes commun a tous. Elément Ancêtre commun (2) Souvent appelé ‘Element’ ou ‘NamedElement’. Certain MM peuvent avoir les deux, l’un héritant de l’autre NamedElement est l’ancêtre de tous les éléments ayant un nom Tout concept doit avoir un parent Un concept ne peut être instancié que si il est contenu dans un autre concept Notion de ‘parent’ une exception possible : le concept racine du modèle Tous les concepts doivent être contenu dans au moins un autre concept Se traduit dans le métamodèle par une composition Tout concept est accessible depuis l’élément racine du modèle en suivant les compositions Notion de ‘package’ Prévoir la possibilité d’organiser (i.e. ranger) les éléments d’un modèle organiser dans des ‘packages’ Le concept de package ne fait pas toujours partie du métier mais bien pratique pour organiser/ranger Notion de ‘package’ approche simple Concept de Package pouvant contenir n’importe quel Element Avantages convient à des cas simple Inconvénients Tous les concepts peuvent être mis dans le package Difficile de restreindre les concepts pouvant être mis dans le package ils doivent avoir un ancêtre commun Notion de ‘package’ implémentation Deux concepts: le Package le PackageableElement – élément pouvant être rangé dans un package Faire hériter de PackageableElement les éléments pouvant être rangé dans un package Pour faire des package récursif: Package doit hériter de PackageableElement Profil Profil : Un profil permet de définir des <<stéréotypes>> On applique (attache) un profil à un modèle afin de pouvoir utiliser les stéréotypes qu’il contient Stéréotype Un stéréotype permet d’ajouter de l’information à un élément UML C’est un mécanisme permettant d’étendre les éléments existants Un stéréotype peut contenir des attributs appelés ‘tagged values’ (valeurs marquées) Tagged Values (valeurs marquées) attribut d’un stéréotype est typé (par un type définit dans le modèle) l’utilisateur peut lui donner une valeur Profil ECore Définit des stéréotypes pour ajouter de l’information propre à un MM Ecore Papyrus : Appliquer un profil Sélectionner le package racine dans l’explorer Dans la vue properties, choisir l’onglet ‘profil’ Cliquer sur Sélectionner le ou les profils voulus Papyrus : Appliquer un stéréotype Sélectionner l’élément à stéréotyper Dans la vue properties, choisir l’onglet ‘profil’ Cliquer sur Sélectionner le ou les profils voulus Définir des datatypes Lors de la définition d’un modèle, aucun type de base n’existe (String, int, boolean) ! Il faut définir les types de bases On définit les types de base dans un package ‘datatype’ On peut aussi utiliser les types UML prédéfinis Définition de Datatype Dans UML Papyrus créer un ‘primitiveType’ lui donner le nom du type a définir (ici String) Le stéréotyper avec Ecore:: EDatatype Spécifier la classe d’implémentation dans instanceClassName String – java.lang.String int – int Integer – java.lang.Integer boolean - boolean Utiliser des String (à la place des EString) Quand on utilise UML::String ECore remplace par un Estring Pour avoir des String: Définir un datatype String spécifier son implémentation: instanceClassName = java.lang.String Utiliser le nouveau type String défini au lieu de UML::String Notion de Dérivé Une propriété dérivé est une propriété dont la valeur peut être calculée à partir d’autres valeurs Permet de calculer une propriété à partir d’autres propriétés évite la duplication de données Il faut fournir l’implémentation du calcul ! Exemple / qualifiedName : String // Le nom complet (noms des parents + nom de la classe séparé par des points) Propriété dérivé dans le métamodèle Marquer la propriété ‘derived’ Marquer la propriété ‘transient’ afin que sa valeur ne soit pas stocké dans le fichier xml Marquer la propriété ‘readOnly’ Si on veut interdire la modification à partir de la propriété dérivé La modification des autres propriétés est toujours possible Propriété dérivé dans le métamodèle Mettre des snapshoots (voir customMethods.ppt) Propriété dérivé - démo Ajouter attribut (sans /) cocher isDerived Si read only, cocher isReadOnly Marquer transient slides suivant Marquer « transient » (1) Comment ? A l’aide d’un stéréotype et d’une valeur marquée (tagged value) Sélectionner la propriété, ajouter le stéréotype : Si attribut EAttribute Si référence (association) EReference Marquer « transient » (2) 2) utiliser le stéréotype Selectionner l’élément Dans les propriétés, sélectionner l’onglet « profile » Si attribut EAttribute Si référence (association) EReference Propriété dérivé – code EMF généré Implémenter la méthode Marquer @generated NOT implémenter !! public abstract class NamedElementImpl extends EObjectImpl implements NamedElement { … /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public String getQualifiedName() { // TODO: implement this method // Ensure that you remove @generated or mark it @generated NOT throw new UnsupportedOperationException(); } … } Ajout de méthodes au MM Une classe peut contenir des méthodes avec des paramètres Permet d’ajouter des fonctionnalités aux classes Il faut implémenter le corps de la méthode dans la classe générée Customiser le code EMF généré Il est possible de customiser le code EMF généré Nécessaire pour les dérivés et les méthodes Marquer @generated NOT les méthodes customisées Pour empêcher l’écrasement du code lors de la prochaine génération par EMF Construire le métamodèle de Java Ne pas perdre de vue que ce métamodèle est destiné à générer du code Java: l’utilisateur décrira le code Java (fera un modèle instance du métamodèle) l’utilisateur décrit le strict minimum: ex: la liste des import peut être déduite des types utilisés dans une classe. L’utilisateur n’a pas besoin de décrire les imports. Cependant, il peut spécifier explicitement des types à importer. Un moteur générera le code correspondant au modèle Bien se documenter rechercher sur le web la syntaxe de Java http://java.sun.com/docs/books/jls/ autre http://wiki.eclipse.org/MoDisco/Components/Java/Documentation/0.8 Exercice Construire le métamodèle Java Répertorier les concepts nécessaire pour construire un MM de Java. Définir la base de votre métamodèle Java: ancêtre commun, package, … Definir les classifiers Definir une propriete Definir une methode Definir une ‘Unite de Compilation’ Enrichir progressivement avec les autres concepts penser a factoriser ! Exercices Le nom qualifié d’un élément est formé du nom qualifié du paquetage englobant, suivi du nom de l’élément et séparé par un ‘.’ (ou ‘::’). Ex: java.lang.String. Votre métamodèle doit permettre d’obtenir le nom qualifié pour tout élément nommé. Proposé une solution pour pouvoir avoir le nom qualifié d’un élément nommé. Donner l’implémentation de cette solution (MM et corps de méthode).