juillet
2009
Dans ce billet nous allons initialiser notre éditeur Eclipse de workflow XML avec EMF et EMF.Edit. Le principe est de partir du schéma XML workflow.xsd et générer son modèle EMF Java et l’éditor Eclipse qui affichera et gérera le contenu XML suivant :
<workflow:workflow xmlns:workflow="http://www.example.org/workflow">
<workflow:state name="state1"/>
</workflow:workflow>
avec l’éditeur suivant :
Vous pouvez télécharger le projet org.example.workflow_step1.zip présenté dans ce billet. Pour suivre ce billet je vous conseille d’utiliser la distribution Eclipse Modeling Tools. La distribution Eclipse IDE for Java EE Developers sera suffisante pour les prochains billets mais pas pour celui-ci.
Model Workflow – EMF
Dans cette section nous allons générer le modèle Java EMF Workflow à partir du schéma XML workflow.xsd :
workflow.xsd
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/workflow" xmlns="http://www.example.org/workflow"
elementFormDefault="qualified">
<xs:element name="workflow">
<xs:complexType>
<xs:sequence>
<xs:element name="state" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="action" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="fromState" type="xs:anyURI" use="required" />
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="toState" type="xs:anyURI" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Ce schéma XML définit deux entités :
- state : état qui est identifié par un nom (name).
- action : action qui est identifiée par un nom (name). Une action a un état d’entrée (fromState) et un état de sortie (toState).
Graphiquement, voici un exemple de workflow que l’éditeur gérera. Cet exemple est constitué de deux états (state1 et state2) et d’une action (action1) :
On peut remarquer que les attributs fromState et toState sont de type xs:anyURI. Cette modélisation ne gère donc pas les liens entre les actions et le states (je ne sais pas comment faire ca avec un schéma XML).
Initialisation projet Workflow EMF
Pour cela nous allons dans un premier temps créer un projet EMF vide en accédant au wizard Empty EMF Project via le menu File/New/Other… puis Eclipse Modeling Framework/Empty EMF Project :
Cliquez sur Next :
Renseignez le nom du projet avec org.example.workflow. Ce projet contiendra le modèle EMF du Workflow. Cliquez sur Finish, le projet org.example.workflow se créé :
Note technique:
- le projet org.example.workflow est un plugin (il contient un fichier MANIFEST.MF).
- le projet org.example.workflow dépend de la librairie Ecore EMF requises org.eclipse.emf.ecore. Cette dépendance s’effectue à l’aide du MANIFEST.MF (voir onglet Dependencies).
- le projet org.example.workflow contient un répertoire model qui contiendra les fichiers EMF *.ecore, *.genmodel…(On est pas obligé de mettre ces fichiers dans ce répertoire).
Le projet org.example.workflow est un plugin Eclipse car c’est un moyen facile de faire référence aux librairies EMF (qui sont aussi des plugins) et ce projet sera aussi utilisé par un editeur Eclipse qui sera un plugin, mais il est possible d’utiliser les classes Java EMF en dehors d’un contexte de plugin.
Schema XML workflow.xsd
Dans le répertoire (à créer) xsd, créez le fichier workflow.xsd :
Génération workflow.ecore & workflow.genmodel
A partir d’un schéma XML, il est possible de générer le fichier ecore et genmodel correspondant. ATTENTION!!! Toutes les distributions ne le permettent pas, utilisez la distribution Eclipse Modeling Tools. Pour cela sélectionnez le schéma XML workflow.xsd, clic sur bouton droit de la souris pour ouvrir le menu contextuel. Sélectionnez le menu New/Other… puis Eclipse Modeling Framework/EMF Model :
Cliquez sur Next :
Le fait d’avoir sélectionné le schéma XML workflow.xsd, le champs File Name se pré-remplit avec workflow.genmodel. Sélectionnez le répertoire model, pour que le fichier workflow.genmodel se génère dans le répertoire model. Cliquez sur Next :
Sélectionnez XML Schéma. Si cet item n’apparaît pas, c’est que vous n’avez pas la distribution Eclipse Modeling Tools. Cliquez sur Next :
Le bouton Next est inaccessible à ce moment là. Cliquez sur le bouton « Load », le bouton Next devient alors accéssible. Cliquez sur Next :
Le package proposé est org.example.workflow. Le wizard se base sur le namespace du schéma XML qui est dans notre cas http://www.example.org/workflow.
Cliquez sur Finish, les 2 fichiers EMF Ecore workflow.ecore et GenModel workflow.genmodel se génèrent :
A mes débuts d’EMF j’avais du mal a comprendre ce qu’était le ecore et le genmodel. Je ne vais pas faire un cours d’EMF sur ce billet car il en existe plein, mais voici de grossières explicatios :
Ecore :
Un schéma que j’aime bien dans le livre officiel EMF est celui-ci :
Il permet de montrer qu’un modèle EMF (ecore) permet d' »unifier » les 3 types de formats UML, Schéma XML et Java. Un ecore peut être considéré comme un format d’échange entre ces 3 types de formats et on peu passer de l’un à l’autre gràce à ce format d’échange.Si vous éditez avec l’éditeur Text le fichier workflow.ecore vous pourrez constater que ce dernier est un fichier XMI (format XML) qui reprend les méta données du schéma XML workflow.xsd. Un Ecore est le format utilisé par EMF pour décrire des modèles (dans notre cas le modèle Workflow).
GenModel :
Le GenModel comme son nom l’indique permet de générer le modèle. Il est lié au Ecore. C’est le fichier qui contient les informations de générations de code pour les classe Java EMF à générer (le repertoire src de sortie, les noms des packages…). L’editeur genmodel re-affiche les meta données du ecore et propose de paramétrer la génération de code. La génération de code s’effectue via le menu contextuel (bouton droit dans l’editeur genmodel) qui permet de générer 3 choses :
- Generate Model Code : génère le modèle Java EMF décrit dans le Ecore.
- Generate Edit Code : génère les providers utilisés dans l’editor générés. Pour plus d’informations, veuillez consultez EMF.Edit.
- Generate Editor Code : génère l’éditor Eclipse qui permet un modèle EMF. Pour plus d’informations, veuillez consultez EMF.Edit.
C’est donc à partir de ce GenModel que nous allons générer les classes Java EMF et l’éditor Eclipse.
Workflow – EMF Model
La génération du modèle EMF Java Workflow, de l’editeur… s’effectue à l’aide de workflow.genmodel. Il est possible de générer directement le code, mais dans notre cas nous allons personnaliser workflow.genmodel pour choisir le nom des package où les classes EMF doivent se générer. Il existe 2 niveaux de personnalisations du genmodel. Après avoir ouvert la vue Properties, et cliquez sur le premier Item Workflow, vous pouvez visualiser ces paramétrages de génération de code :
On peu constater par exemple que :
- Compliance level = 5.0 : siginifie que le code Java généré (modèle EMF…) sera compatible Java 5.
- Model directory = org.example.workflow/src : siginifie que le code Java modèle EMF se générera dans le répertore src du projet org.example.workflow.
Cliquez sur le deuxième item Workflow pour paramétrer les noms des packages dans notre cas comme suit :
- Vérifier que Resource Type = XML.
- Paramétrer Package suffixes comme ci dessous afin d’avoir toutes les classes du modèle Java EMF dans le package org.example.workflow.model au lieu (par défaut) de org.example.workflow.
Il est maintenant possible de générer le model Java EMF du workflow, Pour cela accédez au menu contextuel de l’editeur genmodel qui édite workflow.genmodel puis cliquer sur l’item Generate Model Code du menu :
La génération du modèle Java EMF de Workflow s’effectue dans le répertoire src du projet :
Vous pouvez constarter que :
- chacun des elements du schéma XML ont une classe EMF associée (l’élement workflow est représenté par la classe WorkflowType).
- les sources générées sont dans le répertoire src.
- le package est org.example.workflow.
- est compatible Java5.
- les package exportés (voir MANIFEST.MF) sont org.example.workflow.model.*.
Workflow – EMF Editor
EMF.Edit fournit la possibilité de générer des éditor pour Eclipse qui permettent de gérer un modèle EMF. Pour cela, accédez à nouveau au workflow.genmodel puis cliquer sur les items Generate Edit Code puis Generate Editor Code :
Ces 2 actions permmettent de génerer 2 nouveaux projets (plugins) org.example.workflow.edit et org.example.workflow.editor :
Les noms de ces plugins sont paramétrables dans le workflow.genmodel.
Lancement Workflow Editor
Le projet org.example.workflow.editor est un plugin eclipse qui a un wizard de creation d’un modele EMF de Workflow et un éditor qui permet de le gerer. Pour tester le plugin, ouvrez le MANIFEST.MF du projet org.example.workflow.editor puis cliquer sur le lien Launch an Eclipse application in Debug mode dans la page Overview :
Un deuxième Eclipse s’ouvre. Il a chargé les 3 nouveaux plugin org.example.workflow.*. Pour tester l’éditor, crééer un nouveau projet TestWorkflow puis accéder au wizard Workflow Model via le menu File/New/Other… puis Example Model Creation Wizards/Workflow Model :
Cliquez sur Next, puis sélectionnez le projet TestWorkflow :
Cliquez sur Next :
Cliquez sur Finish. Cette action génère le fichier My.workflow et l’éditor de Workflow s’ouvre :
Cet éditeur est constitué de plusieurs pages qui représentent le modèle workflow de différentes manières (à l’aide d’un Treeview, d’une Table…) Si vous éditez, My.workflow à l’aide de l’éditeur de texte, vous pourrez voir ce contenu :
<workflow:workflow xmlns:workflow="http://www.example.org/workflow"/>
Pour mettre à jour ce fichier à l’aide de l »éditor, sélectionner l’item Type, puis cliquer sur le bouton droit. Ceci ouvre un menu contextuel. Pour ajouter un élement state, Cliquer sur New Child -> State Type :
Enregistrer l’editor, puis vous pourrez voir dans l’éditeur de texte ce contenu :
<workflow:workflow xmlns:workflow="http://www.example.org/workflow">
<workflow:state/>
</workflow:workflow>
Pour mettre a jour le nom (name) de l’état (state) créée, ceci peut s’effectuer à l’aide de la vue Properties. Pour cela sélectionnez l’élement State Type dans l’editor, puis cliquer sur le bouton droit pour ouvrir le menu contextuel, puis cliquer sur Show Properties View :
Modifier la propriété Name par state1, enregistrer puis vous pourrez voir dans l’éditeur de texte ce contenu :
<workflow:workflow xmlns:workflow="http://www.example.org/workflow">
<workflow:state name="state1"/>
</workflow:workflow>
10 Commentaires + Ajouter un commentaire
Articles récents
- Conception d’un client Eclipse RCP et serveur OSGI avec Spring DM [step5]
- Conception d’un client Eclipse RCP et serveur OSGI avec Spring DM [step4]
- Conception d’un client Eclipse RCP et serveur OSGI avec Spring DM [step3]
- Conception d’un client Eclipse RCP et serveur OSGI avec Spring DM [step2]
- Conception d’un client Eclipse RCP et serveur OSGI avec Spring DM [step1]
Commentaires récents
- Conception d’un Editeur Eclipse de workflow XML [step 0] dans
- Conception d’un Editeur Eclipse de workflow XML [step 19] dans
- Conception d’un Editeur Eclipse de workflow XML [step 7] dans
- Conception d’un Editeur Eclipse de workflow XML [step 7] dans
- Conception d’un Editeur Eclipse de workflow XML [step 7] dans
Bonjour kase74 ,
Merci beaucoup de ton retour. Je ne savais pas que l’on pouvait faire comme ca.
Angelo
Bonjour Angelo,
Désolé de ne pas avoir répondu plus tôt.
Alors oui, on peut directement décrire dans le scéma xml les liens qui permettent de créer correctement le ecore (les eReference) :
dans le xsd, rajouter le namespace suivant :
xmlns:ecore= »http://www.eclipse.org/emf/2002/Ecore »
Puis lors de la définition d’un complextype qui comporte un attribut jouant le rôle de « clé étrangère », il faut ajouter à l’attribut les valeurs ecore:reference et ecore:opposite qui font respectivement référence au type et à l’attribut « source ».
J’ai trouvé ça dans un tuto. Il sera plus explicite que moi. Regarde le xsd source library.xsd qui utilise cette notation. Voici le tuto : http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclipse.emf.doc/tutorials/clibmod/clibmod.html
Je l’ai testé et ça marche.
Ca m’a fait plaisir de t’aider un petit peu. C’est un juste retour de l’aide que tu fournis avec cet excellent tuto.
Bien à toi.
Bonsoir kase74,
>As tu trouvé comment gérer les liens dans un schéma xml ?
Non je ne sais pas comment on gere ca en schema XML et si c’est possible, le ecore se genere correctement? Moi je l’ai gere en modifiant le ecore (vori un des billets precedant) mais pas directement dans le schema XML. Si tu connais une autre solution je veux bien que tu m’expliques.
Merci beaucoup.
Angelo
Bonjour Angelo,
As tu trouvé comment gérer les liens dans un schéma xml ?
Si non, je peux te l’expliquer (échange de bon procédé) dès que j’en ai un peu le temps. Je ferai ça depuis chez moi.
A+
Ok merci pour cette info sixroses.
C’est une solution que j’avais déjà testé en fait :s
Comme le MultiPageEditor est créé, Eclipse gère tout seul l’appel de createPages() avec la fonction createControl() qui n’est pas redéfinissable. Donc si aucune page n’est crée dans createPages(), Eclipse appelle quand même automatiquement une fonction qui retournera une erreur à cause d’une valeur nulle.
Une « solution » que j’ai finalement trouvée – elle empêchera d’ouvrir un fichier externe – c’est de fixer le paramètre « default » à FALSE dans plugin.xml -> Le plugin n’ouvrira pas par défaut les fichiers xml, donc ils seront forcément dans un projet et ouvrable avec le plugin en faisant « Open with.. »
Bonjour sixroses,
Tu peux appeler la méthode EditorPart#getEditorInput() qui te retourne le IEditorInput. Dans la méthode MultiPageEditor#createPages () il est bien renseigne.
Mais il faudra aussi faire les tests dans la méthod einit dans le cas ou tu drag/drop un fichier XML du workspace dans ton editeur.
Angelo
Bonjour Angelo,
Je te remercie de ta réponse.
Oui en fait c’est ce que je fait actuellement, mais à ce moment là (à l’appel de la fonction MultiPageEditor#init) le MultiPageEditor est déjà créé, cad que que le constructeur a déjà été appelé. Du coup, si c’est un fichier externe et que je ne retourne pas de Ifile à la fin du init, alors j’ai un beau message d’erreur qui apparait plus tard et que je peux empêcher.
Donc si j’ai bien compris, on ne peut pas tester si c’est un fichier externe avant de construire le MultiPageEditor.
Bonne journée,
Bonjour sixroses,
J’ai moi aussi le problème dont tu parles (du moins dans les billets suivants car j’utilise SSE (faudra que je regarde ce problème quand j’aurrais le temps). Ce qui est sur c’est que tu ne peux pas obtenir de IFile à partir d’un fichier externe. Dans la méthode MultiPageEditor#init(IEditorSite site, IEditorInput editorInput) tu peux tester le type de IEditorInput (si c’est un fichier externe tu as FileStoreEditorInput). Ca te permetrait de detecter si c’est un fichier interne ou externe.
Je ne sais pas si ca pourra t’aider.
Angelo
Bonjour,
Je viens de découvrir ton blog ou plusieurs post sont consacrés à l’édition de fichiers xml que j’ai trouvé très intéressants
Je travaille actuellement sur un plugin d’édition de fichiers xml…qui n’est certainement pas aussi poussé que le tien. Cependant je suis confronté à un problème que tu n’as pas (il me semble) à cause de ta conception :
J’ai un MultiPageEditor qui construit une vue pour le texte et une vue pour un TreeEditorPart.
Ce TreeEditorPart nécessite un IFile (que tu as initialisé dans WorkflowEditor.doSaveAs). Mon problème est que je souhaite pouvoir ouvrir un fichier externe à un projet du workspace (chose que le IFile ne permet pas car c’est un lien par rapport à un projet).
* Sais tu comment je pourrais tester avant la création du MultiPageEditor si le fichier xml que je souhaite ouvrir est interne ou externe aux projets ? Car le multipageEditor se créé dès la sélection du fichier xml dans « Fichier/Open File » et me retourne inévitablement un message d’erreur (NullPointerException sur ce IFile)
Dans l’attente d’une réponse,
Cdt,