Actualités

Comment surcharger proprement le code EMF généré ?

Tous les conseils indiqués dans cet article ont été implémentés dans un plugin accessible sur github à cet endroit : https://opcoach.github.io/genModelAddon/

EMF permet de générer du code à partir du modèle. En paramétrant un fichier .genmodel, on peut ainsi générer les trois couches de code : model, edit et editor, qui contiennent les sources java permettant d’exploiter le modèle métier défini.

Pour surcharger le code généré la méthode traditionnelle consiste à modifier directement le code généré en ajoutant un ‘NOT’ derrière les balises @generated. Le plugin ‘mint’ (dans emftool), permet également de distinguer les méthodes surchargées (en rouge), les méthodes ajoutées (en noir) et les méthodes générées (en bleu) :

La surcharge de code avec @generated

 

Cette méthode peut être acceptable si peu de code est modifié, mais dans le cas de projets où beaucoup de code métier doit être ajouté, il est préférable de :

  • séparer clairement le code généré du code manuel
  • générer le code automatiquement dès le process de build
  • retirer le code généré de la gestion de configuration (cvs, svn, git, …) et le régénérer lors de la livraison

EMF et Eclipse proposent des solutions simples pour répondre à ce besoin.

 

1. Séparer le src-gen et le src

Pour travailler proprement, il faut prendre des mesures d’étanchéité, en séparant clairement le répertoire du code généré de celui du code surchargé. Pour le faire, on paramètre le genmodel de la manière suivante :

Paramétrage du genmodel

On peut répéter cette opération pour la couche edit et la couche editor.

Puis on créé un répertoire src (source folder), dédié à la surcharge dans le projet :

Répertoire src pour la surcharge

 

Ce nouveau répertoire de source, va contenir la nouvelle factory EMF pour créer les instances des classes surchargées. Cette factory dérive de la factory générée, et propose des création d’objets avec les nouvelles interfaces :

Nouvelle factory qui créé les nouvelles instances

 

On complétera les méthodes de cette factory au fur et à mesure qu’on surchargera les classes du modèle généré.

L’implémentation de la factory est alors simplement :

Implémentation de la factory surchargée

 

Il ne reste plus qu’à relier cette nouvelle factory à EMF, en utilisant le point d’extension factory_override :

Point d'extension override_factory

Cette nouvelle factory sera alors automatiquement utilisée par EMF lors de la création des objets par un appel à  RentalFactory.eInstance.

 

Il reste alors à surcharger les classes métiers modélisées avec EMF. On peut notamment ajouter des méthodes de confort (add, remote) dans les interfaces … :

Ajout des méthodes d'accès dans l'interface

 

…  et surcharger les opérations modélisées dans l’implémentation :

Implémentation des méthodes métier et de l'interface

 

 

 2. Générer le code durant le build, dans Eclipse

Si on sépare totalement le code généré du code surchargé, il peut être intéressant d’automatiser la génération du code à partir du modèle.

EMF nous propose une tache ant (emf.Ecore2Java)  permettant de générer le code à partir d’un genmodel. Le fichier ant à écrire est trivial :

Fichier ant de génération de code EMF

 

Pour l’exécuter il faudra faire attention d’utiliser le JRE du workspace (paramètre dans le lancement du build, dans l’onglet JRE).

Ce fichier ant peut alors être intégré au builder du projet en le mettant en première position pour être sûr que le code généré sera présent pour la compilation :

 

 

 

3. Générer le code durant le build, hors Eclipse

Dans le processus de build headless, sans avoir un IDE Eclipse lancé, on peut regénérer le code de deux manières

  • par l’application org.eclipse.ant.core.antRunner qui rappelle le ant de génération, pouvant contenir d’autres taches
  • par l’application org.eclipse.emf.codegen.ecore.Generator qui ne fait que de la génération

Dans les deux cas, il faut initialiser l’environnement de lancement :

  • cd {répertoire Installation Eclipse Modeling}
  • export LAUNCHER=plugins/org.eclipse.equinox.launcher_1.2.0.v20110502.jar

Générer  avec le antRunner :

Lancement du build ant avec le antRunner :
java -jar $LAUNCHER -application org.eclipse.ant.core.antRunner -nosplash -buildfile {pathToAntFile}/ecore2java.xml

Cette méthode est intéressante si le fichier ant fait un peu plus que de la génération de code.

Générer avec le ecore.Generator

Cette méthode est intéressante s’il n’y a que du code à générer à partir du modèle :

Les paramètres de l’application sont :  java -jar $LAUNCHER -application org.eclipse.emf.codegen.ecore.Generator
Usage arguments: [-projects ]
[-dynamicTemplates] [-forceOverwrite | -diff]
[-generateSchema] [-nonNLSMarkers]
[-codeFormatting { default | } ]
[-model] [-edit] [-editor] [-tests]
[-autoBuild  true | false ]
genmodel-file [ target-root-directory ]

Exemple d’utilisation :

  • export PROJECT_HOME={path to your project}
  • java -jar $LAUNCHER -application org.eclipse.emf.codegen.ecore.Generator -projects $PROJECT_HOME -model -nosplash $PROJECT_HOME/model/rental.genmodel   $PROJECT_HOME

Pour approfondir ces notions, je vous conseille aussi cet article général sur le sujet, présenté à infoq et écrit par Sven Efftinge (chef de projet XText)

 

N’hésitez pas à commenter cet article si vous avez des remarques !

Laisser un commentaire