Avant-propos

Avant de commencer il nous semble important d'évoquer les difficultés que nous avons rencontrées lors du développement de notre projet. La première, et la principale, découle de l'aspect novateur de notre projet et du faible nombre de précurseurs sur cette voie. En effet le développement de plug-in pour un logiciel tel qu'Eclipse n'est pas une chose commune. Autant, pour le développement d'un site Web, il existe pléthore de sites consacrés à ce sujet et bénéficiant de plus d'une communauté de développeurs réactive et compétente ; autant pour le développement d'un plug-in sous Eclipse, les ressources existantes sont très limitées, quasi-exclusivement anglophones, et d'un très haut niveau technique.

Bien que le travail effectué puisse paraître incomplet et nécessitant encore d'être approfondi pour aboutir à la mise en place d'un plug-in exploitable par des professionnels, nous sommes intimement persuadés de sa valeur et du potentiel considérable qu'il offre si l'on en poursuit le développement.

Remerciements

Nous tenons à remercier en premier lieu notre tuteur, M. Henri BETAILLE, pour l'autonomie qu'il nous a accordé tout au long de cette période.

Pour nous avoir ouvert les yeux sur la difficulté de notre projet, et pour ses conseils concernant le recadrage du sujet, nous voulons remercier M.ROUVIERE, ingénieur spécialiste de Java.

Pour la confiance qu'il nous a témoigné, nous souhaitons remercier M. Hugo ETIEVANT, ingénieur systèmes et réseaux, et responsable Java de www.developpez.com, sans qui il aurait été impossible de mettre notre travail à disposition de tous via le site.

Et enfin, merci à M. Philippe COINDY pour les diverses corrections grammaticales et orthographiques qu'il a effectué sur ce rapport.

1. Introduction

Ce projet a de particulier qu'il n'a pas été proposé par le corps enseignant. A l'inverse de l'an dernier, les professeurs nous ont incité à chercher des sujets par nous-même, ce que nous avons fait.

C'est ainsi que nous avons proposé le développement de l'interface d'administration d'un site e-commerce. Interface qui aurait été basée sur notre projet de deuxième année d'IUT. Sujet malheureusement refusé par l'équipe enseignante du fait qu'il ne nous aurait pas apporté de connaissances supplémentaires.

Lors de notre recherche de sujets, nous en avions trouvé un deuxième qui était le développement d'un éditeur HTML en Java. D'abord mis de côté, nous l'avons repris et proposé.

L'idée est arrivée à maturation au travers de notre sujet actuel : le développement d'un plug-in XHTML pour Eclipse. En effet, pourquoi ne pas utiliser la plateforme Eclipse en y ajoutant un plug-in permettant le développement de pages HTML, et même XHTML comme nous l'a proposé Marie-Laure MUGNIER. Cette idée nous a parut rentrer entièrement dans la philosophie Eclipse, à savoir de ne pas essayer de réinventer la roue, mais plutôt d'utiliser le logiciel existant et d'y ajouter des plug-ins pour en multiplier ses fonctionnalités. Nous verrons ainsi tout au long de ce rapport comment créer un plug-in simple permettant la création et l'édition de fichiers XHTML. Nous espérons que notre travail pourra être repris, permettant ainsi la création d'un éditeur plus complexe aux fonctionnalités multiples.

Dans un premier temps nous parlerons de la plateforme Eclipse et de son architecture construite autour de multiples plug-ins, ce qui la rend tout à fait singulière. Cela fait, nous détaillerons par la suite la création de notre éditeur XHTML ainsi que les résultats obtenus. Nous finirons par une discussion sur l'atteinte de nos objectifs.

2. Présentation générale

2.1. Moyens et méthodes

2.1.1. Le projet Eclipse

Eclipse est un environnement de développement intégré (Integrated Development Environment) dont le but est de fournir une plate-forme permettant de réaliser des développements informatiques. C'est I.B.M. qui est à l'origine de ce projet et qui a fait en sorte que tout le code source d'Eclipse soit donné à la communauté afin d'encourager la poursuite de son développement.

Eclipse utilise le concept de modules nommés plug-ins dans son architecture. D'ailleurs, à l'exception du noyau de la plate-forme nommée "Runtime", tout le reste de la plate-forme est développée sous la forme de plug-ins. Ce concept permet de fournir un mécanisme pour l'extension de la plate-forme et ainsi fournir la possibilité à tout le monde de développer des fonctionnalités qui ne sont pas fournies en standard par Eclipse. Ainsi, par exemple, il peut être utile de développer son plug-in lorsqu'on a besoin d'un outil non encore présent dans Eclipse.

Les principaux modules fournis en standard avec Eclipse concernent Java mais des modules existent ou sont en cours de développement pour d'autres langages notamment C++, Cobol, mais aussi pour d'autres aspects du développement (conception avec UML, base de données, ... ). Ils sont tous développés en Java soit par le projet Eclipse, soit en open source. Les modules agissent sur des fichiers qui sont inclus dans l'espace de travail (Workspace).

2.1.1.1. Les points forts d'Eclipse

Eclipse possède de nombreux points forts qui sont à l'origine de son succès dont les principaux sont :

  • Une plate-forme ouverte pour le développement d'applications et extensible grâce à un mécanisme de plug-ins.
  • Plusieurs versions d'un même plug-in peuvent cohabiter sur une même plate-forme.
  • Un support multi langage grâce à des plug-ins dédiés : C, PHP, C#, ...
  • Support de plusieurs plates-formes d'exécution : Windows, Linux, Mac OS X, ...
  • Malgré son écriture en Java, Eclipse est très rapide.
  • Une ergonomie entièrement configurable qui propose selon les activités à réaliser différentes « perspectives ».
  • Un historique local des dernière modifications.
  • Propose le nécessaire pour développer de nouveaux plug-ins.
  • La plate-forme est entièrement internationalisée dans une dizaine de langue sous la forme d'un plug-in téléchargeable séparément. Le gestionnaire de mise à jour permet de télécharger de nouveaux plug-ins ou nouvelles versions d'un plug-in déjà installées à partir de sites web dédiés.

2.1.1.2. Présentation graphique d'Eclipse

L'interface d'Eclipse facilite l'accession aux options les plus courantes. Elle est également plutôt intuitive, dès les premières utilisations elle permet d'avoir des repères clairs. De nombreux raccourcis contribuent à une navigation agréable et facile.

2.1.1.2.1. Les perspectives

Au lancement d'Eclipse, une seule fenêtre s'ouvre contenant le "workbench". Le "workbench" est composé de perspectives dont plusieurs peuvent être ouvertes mais une seule est affichée à un instant « t ». Une perspective contient l'organisation des sous fenêtres qui peuvent contenir des vues (views) ou des éditeurs (editors).

Image non disponible
Affichage de la perspective Java

On choisit la perspective affichée par une icône en haut à droite du workbench. L'icône enfoncée est celle de la perspective affichée. Le titre de la fenêtre du workbench contient le nom de la perspective courante.

2.1.1.2.2. Les vues

Une vue permet de visualiser et de sélectionner des éléments. Il ne peut y avoir qu'une seule fenêtre de vue particulière dans une même perspective. Par contre, il peut y avoir plusieurs vues différentes rassemblées dans une même sous fenêtre. Dans ce cas, l'accès à chaque vue se fait grâce à un onglet.

Image non disponible
La vue Navigator
2.1.1.2.3. Les éditeurs

Un éditeur permet de visualiser, mais aussi de modifier le contenu d'un élément. Un éditeur peut contenir plusieurs éléments, chacun étant identifié par un onglet. Chaque onglet de l'éditeur contient le libellé de l'élément qu'il traite

Image non disponible
Exemple d'un éditeur

2.1.2. Cahier des charges

2.1.2.1. Situation de départ

Dans le cadre de nos études en licence pro informatique option e-business, nous avons eu l'occasion de travailler à plusieurs reprises sur Eclipse. Cet outil performant nous a très vite séduit de part les possibilités qu'il offre, notamment en ce qui concerne la programmation en langage Java. Ainsi depuis le début de l'année, nous avons fait de plus en plus de découvertes à son sujet. C'est par le biais de ces découvertes que nous avons compris qu'Eclipse est en réalité composé d'un ensemble de plug-ins articulés autour d'un noyau. L'idée de départ nous ait apparue à ce moment précis : pourquoi ne pas développer notre propre plug-in ?

A coté de cela, nous avions également une autre idée qui consistait en la conception d'un éditeur HTML dans le cadre de notre projet de licence. Il nous ait alors paru évident de concevoir cet éditeur à l'aide d'un plug-in Eclipse.

L'objectif de notre projet est donc de commencer la réalisation d'un plug-in XHTML sous Eclipse. Cela nous permettra de mieux comprendre les mécanismes du fonctionnement des plug-ins, et par conséquent d'offrir la possibilité aux personnes désirant s'initier aux plugins d'Eclipse, d'avancer plus vite à travers notre expérience.

2.1.2.2. Choix du XHTML

Comme il est dit ci-dessus, à l'origine nous nous sommes orientés vers la conception d'un éditeur HTML simple. Puis nous avons eu connaissance de l'existence du XHTML, ce qui nous a poussé à effectuer des recherches dessus. C'est de cette manière que nous nous sommes aperçu qu'il y a un certains nombres d'avantage à utiliser le XHTML par rapport au HTML :

  • Le HTML est un langage tellement souple que sa compréhension et sa lisibilité en deviennent plus difficiles.
  • Le XHTML étant basé sur le modèle XML, la manipulation de données est facilitée par rapport au HTML. Cela permet également de contrôler facilement la conformité du code.
  • Le XHTML ayant une structure simple, il requiert une puissance de calcul moindre pour l'interpréter. Son utilisation sera donc très largement répandue parmi les ordinateurs de poche ou les futurs téléphones portables.

Enfin, le XHTML étant un pont entre les technologies HTML et XML, il est capable de fonctionner sur tous les outils conçus soit pour le HTML soit pour le XML.

2.1.2.3. Fonctionnalités requises

2.1.2.3.1. Création d'un nouveau projet

Le plug-in doit permettre la création d'un nouveau projet XHTML.

Le projet est l'unité de base du workspace. Chaque fichier doit être inclus directement dans un projet ou indirectement dans un répertoire appartenant à un projet. La création se fera grâce à un assistant qui demandera le nom du nouveau projet. Ce nom ne doit pas contenir de blanc ou des caractères non alphabétiques.

Un clic sur "Fin" déclenchera la création du projet. Le projet apparaîtra dans la vue Navigateur.

2.1.2.3.2. Création d'un nouveau fichier

L'assistant de création de fichiers permettra de choisir le projet et le répertoire dans lequel le fichier XHTML sera créé. Une fois cette localisation choisie il suffira de saisir le nom du fichier et de cliquer sur "Fin". Ce nom ne doit pas contenir de blanc ou des caractères non alphabétiques.

Le fichier XHTML fraîchement crée apparaîtra dans l'arborescence de la vue du Navigateur.

2.1.2.3.3. Insertion de composants XHTML

Ce plug-in devra permettre l'ajout automatique de composants XHTML. Par exemple on pourra insérer un tableau avec les caractéristiques voulues par l'utilisateur, ou alors insérer des balises permettant de mettre la police en gras.

Ces ajouts de composants se feront concrètement par l'ajout d'une portion de code dans le fichier XHTML courant.

2.1.2.3.4. Autres fonctionnalités possibles

Ce plug-in pourrait également permettre la coloration syntaxique, pour une meilleure visibilité lors du codage XHTML, il pourrait aussi intégrer un outil qui vérifierait la conformité du code, ainsi qu'une fonction « aperçu ».

2.2. Programmation

2.2.1. PDE

2.2.1.1. Création de projet plug-in

Eclipse possède par défaut un assistant permettant de développer rapidement un plug-in fonctionnel évitant au programmeur l'écriture de nombreuses classes. PDE, c'est son nom, se lance lorsque l'on crée un nouveau projet de plug-in.

Image non disponible
Assistant « Nouveau projet de plug-in »
Image non disponible
Première étape de création du plug-in

Dans la zone « Project Name », on y saisit le nom complet du projet. Il peut être choisi tout à fait librement. Ici net.eclipse.xhtml.editeur afin de respecter le nommage des plug-ins par défaut d'Eclipse.

La fenêtre qui suit permet de déterminer quelques propriétés du plug-in comme son nom, sa version, ou encore le nom de la librairie jar qui sera créée lors de l'étape de déploiement du plug-in.

Image non disponible
Propriétés du plug-in

Nous arrivons ensuite à une page permettant de créer notre plug-in avec pour base tel ou tel modèle (avec un éditeur, avec des boutons actions, avec des vues, etc.).

Nous souhaitons que notre plug-in soit un éditeur, mais qu'il possède également des boutons d'action, etc. Dans ce cas, il faut sélectionner « Custom plug-in wizard » permettant de cocher les fonctionnalités qu'on souhaite donner à notre composant.

Image non disponible
Modèles de plug-in
Image non disponible
Plug-in personnalisé

Dans notre cas, nous avons coché les options permettant de générer les classes qui auront pour effet de gérer :

  • un éditeur XML simple,
  • un bouton d'action affichant une fenêtre « Hello World ! »,
  • un assistant de création de nouveau fichier,
  • une perspective spécifique au plug-in.

Se suivent quelques autres pages à afficher ne nécessitant pas de commentaires supplémentaires, excepté une, que voici :

Image non disponible
Propriétés du wizard de nouveau fichier

Cette partie de l'assistant permet de définir les attributs du wizard de création d'un nouveau fichier. On veut créer un éditeur XHTML, on change donc l'extension par défaut par un .htm. « nouveau.htm » sera le nom par défaut du fichier ainsi généré par le wizard. Une fois le plug-in exécuté, cette configuration donne le résultat suivant dans la fenêtre regroupant tous les assistants d'Eclipse.

Image non disponible
Arborescence des wizard « Nouveau fichier XHTML » y compris

Une fois la complétion de l'assistant terminée, Eclipse ouvre la perspective de développement associée aux projets de plug-in que voici :

Image non disponible
Perspective de développement de plug-in
  1. Explorateur de package classique avec lequel vous pouvez parcourir et ouvrir les classes et packages souhaités.
  2. Editeur multi onglets permettant d'éditer le fichier de manifeste plugin.xml. Ce fichier est le fichier central dans le développement de plug-in puisque c'est lui qui gère la configuration générale du plug-in (menus, extensions, perspectives, etc.).
  3. Console permettant d'afficher les éventuelles traces et erreurs que votre plug-in pourra générer.
  4. Explorateur avancé de la page en cours d'édition.

2.2.1.2. Première exécution

A la sortie de l'assistant, le plug-in est d'ores et déjà opérationnel. Nous pouvons lancer une première exécution et voir le résultat obtenu. Pour cela, il faut démarrer le plug-in en mode « Runtime workbench ». Une nouvelle fenêtre d'Eclipse s'ouvre alors avec le plug-in exécuté.

Image non disponible
Première exécution du plug-in

La présence de notre « Sample Action » dans le menu nous indique qu'on vient bel et bien d'exécuter notre plug-in. A noter qu'une petite icône d'action est également ajoutée à la barre d'outils. Par curiosité, on peut voir la liste des composants chargés sur la plateforme en cours. Pour cela, dans le menu « A propos », choisissez « Plug-in details ».

Image non disponible
Détail des plug-ins chargés sur la plateforme

Note : le plug-in n'est visible que dans l'instance d'Eclipse exécutée après le Run... ». Il ne sera réellement exploitable que lorsqu'il aura été déployé dans le répertoire source d'Eclipse.

2.2.2. Les « Wizards »

2.2.2.1. Nouveau fichier

Deux classes ont été créées dans le package net.eclipse.xhtml.editeur.wizards. SampleNewWizard et SampleNewWizardPage. Elles permettent de piloter l'assistant qui va générer le fichier HTML. SampleNewWizard est la classe principale. Elle est lancée lorsque l'on choisit de créer un nouveau fichier XHTML, et se sert de SampleNewWizardPage pour créer son contenu.

SampleNewWizard contient le texte par défaut qui sera introduit dans le fichier généré par l'assistant de nouveau fichier. Ce texte est situé dans la méthode OpenContentStream(). Dans notre cas, nous avons remplacé le texte initial par le code suivant qui est celui de base pour une page XHTML :

 
Sélectionnez

private InputStream openContentStream() {
   String contents =
      "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0
      Transitional//EN\" \"transitional.dtd\">\n"+
      "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"+
      "<head>\n"+
      "<title>Document sans nom</title>\n"+
      "<meta http-equiv=\"Content-Type\" content=\"text/html;
      charset=iso-8859-1\" />\n"+
      "</head>\n\n"+
      "<body bgcolor=\"#FFCC99\">\n"+
      "</body>\n"+
      "</html>";
   return new ByteArrayInputStream(contents.getBytes());
}

SampleNewWizardPage, moins intéressante, s'occupe de la mise en place des composants graphiques sur la fenêtre. Quelques informations peuvent néanmoins être modifiées comme le titre de la page, le nom du fichier par défaut, ou encore le nom des boutons affichés.

2.2.2.2. Nouveau projet

Comme il existe désormais un assistant « Nouveau fichier XHTML », nous avons voulu créer de toute pièce un nouvel assistant « Nouveau projet XHML ». En effet, Eclipse requiert que chaque fichier appartienne à un projet.

La création d'un tel projet n'est pas une nécessité puisque, par défaut, Eclipse dispose d'un assistant de création de projet simple convenant à la plupart des utilisations, dont la nôtre. Mais, rappelons-le, notre objectif était non pas un objectif de résultat, mais plutôt un objectif de découverte de la plateforme. C'est pourquoi nous avons voulu le créer.

2.2.2.2.1. Création des classes correspondantes

Nous nous sommes inspirés des classes générées automatiquement par l'assistant de nouveau fichier, à savoir SampleNewWizard, et SampleNewWizardPage. Nous avons ainsi créé deux nouvelles classes : SampleNewProjet et SampleNewProjetPage.

Un assistant de création de projet s'occupe de trois tâches :

  • Création du répertoire ayant le nom du projet saisi
  • Création et remplissage du fichier « .project » (au format XML) contenant les informations essentielles au fonctionnement du projet.
  • Une fois ces ressources créées, l'assistant se ferme et importe dans la vue « navigateur » le projet que l'on vient de créer.

De la même façon que SampleNewWizardPage n'était pas très intéressante à étudier dans la pratique, SampleNewProjetPage, qui est sa copie quasi-conforme, ne l'est pas non plus. Penchons-nous par conséquent sur SampleNewProjet.

Etape 1 : création du répertoire
Sélectionnez

// création du IPath en fonction du chemin saisi
IPath monIPath = new Path(nomProjet);
// création du File correspondant
File monDir = monIPath.toFile();
// et du répertoire qui contiendra le fichier .project
// répertoire ayant pour nom celui du projet
monDir.mkdir();
Etape 2 : création et remplissage du .project
Sélectionnez

// Création du .project
File monFicProject = new File(nomProjet.toString()+"\\.project");
try {
   monFicProject.createNewFile();
} catch (IOException e2) {
   // TODO Auto-generated catch block
   e2.printStackTrace();
}
[... ]
// Remplissage du .project
this.remplirFicProject(monFicProject);
Etape 2 suite
Sélectionnez

private InputStream openContentStream(String nomProjet){
   System.out.println("je suis dans openContentStream(String nomProjet).");
   String contents = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
   contents += "<projectDescription>\n";
   contents += "\t<name>"+nomProjet+"</name>\n";
   contents += "\t<comment></comment>\n";
   contents += "\t<projects>\n";
   contents += "\t</projects>\n";
   contents += "\t<buildSpec>\n";
   contents += "\t</buildSpec>\n";
   contents += "\t<natures>\n";
   contents += "\t</natures>\n";
   contents += "</projectDescription>\n";
   // on assigne le contenu généré à l'attribut privé dédié à cette fonction
   contenuFicProject = contents;
   return ByteArrayInputStream(contents.getBytes());
}
Etape 2 : fin de cette étape
Sélectionnez

/**
* Remplit le fichier "nom" avec le contenu XML créé dans
openContentStream
* et stocké dans l'attribut contenuFicProject.
*/
public void remplirFicProject(File nom) throws IOException {
   FileOutputStream flotS = new FileOutputStream(nom);
   flotS.write(contenuFicProject.getBytes());
   flotS.close();
}

Malgré tous nos efforts, nous ne sommes pas parvenu à effectuer l'étape 3, à savoir que l'assistant se ferme et que le projet soit automatiquement importé. Nous sommes persuadé comme nous sommes près du but, mais une erreur subsiste toujours :

Image non disponible
Erreur de création d'un nouveau projet

Les ressources sont cependant bel et bien créées. Par conséquent, on peut tout de même importer le projet via l'assistant d'importation de projet qu'Eclipse fournit : File > Import > Existing project in workspace.

2.2.2.2.2. Modification de plugin.xml en conséquence

Comme nous l'avons vu précédemment, PDE dispose d'une interface multi onglets permettant l'édition de plugin.xml. L'onglet « Extensions » permet d'ajouter/supprimer ou modifier les extensions présentes sur le plug-in développé.

Dans notre cas, nous nous intéressons à org.eclipse.ui.newWizards. C'est cette extension qui gère les menus présents lorsque l'on choisit un assistant à exécuter. La catégorie est le dossier dans lequel se trouvent les assistants du plug-in. Pour l'instant, nous n'avons qu'un wizard « Fichier XHTML ». Il faut donc créer une nouvelle entrée de wizard et lui associer la classe que nous venons de créer.

Clic droit sur org.eclipse.ui.newWizards, « new » puis « wizard ». On remplace le nom par « Projet XHTML ». On lui associe la classe SampleNewWizardProjet ainsi que la catégorie « net.eclipse.xhtml.editeur », catégorie correspondant à l'id de la catégorie XHTML à laquelle ce wizard doit appartenir. On peut ensuite éventuellement lui associer une icône.

2.2.3. La coloration syntaxique

Le principe de coloration syntaxique est peut être celui qui fait le plus appel à des connaissances théoriques avancées sur la plateforme Eclipse. Il est basé sur un modèle de destruction, réparation et réconciliation. Lorsque le contenu du document est changé, le réconciliateur détermine la ou les régions affectées par ces modifications et comment les détruire et les réparer.

Nous ne détaillerons pas ici la théorie ainsi que chacune des 12 classes générées par l'assistant se trouvant dans le package net.eclipse.xhtml.editeur.editors. Nous préfèrerons nous pencher sur la pratique et sur l'étude des seules classes permettant d'ajouter, de supprimer ou de modifier les options de coloration syntaxique.

Nous allons créer un commentaire personnalisé afin de s'exercer à la manipulation de la coloration.

Par mimétisme, dans XMLPartitionScanner, basons-nous sur l'implémentation du commentaire « XML_COMMENT » pour créer le notre.

On rajoute donc un attribut public :

 
Sélectionnez

public final static String MON_COMMENT = "__mon_comment";

Ainsi que le code suivant au constructeur :

 
Sélectionnez

IToken monComment = new Token(MON_COMMENT);
rules[2] = new MultiLineRule("/debComm","finComm\\",monComment);

Note : il faut bien prendre soin d'augmenter la taille du tableau de règles « rules » à 3 cellules.

Dans XMLDocumentProvider, on rajoute une entrée au tableau de String passé en paramètre à la construction du DefaultPartitionner :

 
Sélectionnez

new String[] {
XMLPartitionScanner.XML_TAG,
XMLPartitionScanner.XML_COMMENT,
XMLPartitionScanner.MON_COMMENT}

Toujours par mimétisme, dans XMLConfiguration, on rajoute le code suivant à la fin de la méthode getPresentationReconciler.

 
Sélectionnez

NonRuleBasedDamagerRepairer ndr2 = new NonRuleBasedDamagerRepairer(
   new TextAttribute(colorManager.getColor(IXMLColorConstants.MON_COMMENT)));
reconciler.setDamager(ndr2, XMLPartitionScanner.MON_COMMENT);
reconciler.setRepairer(ndr2, XMLPartitionScanner.MON_COMMENT);

Et enfin, dans l'interface IXMLColorConstants, on définit la couleur qu'aura notre commentaire en rajoutant la ligne suivante :

 
Sélectionnez

RGB MON_COMMENT = new RGB(50, 220, 240);
Image non disponible
Affichage de notre commentaire personnalisé (en bleu)

2.2.4. Les actions

2.2.4.1. L'action par défaut

L'assistant de création de plug-in a créé une action affichant une fenêtre « Hello world ! ». Comme pour la création d'un nouveau wizard, l'ajout d'une action passe par deux étapes :

  • la création d'une classe exécutant le code désiré,
  • la modification du fichier de manifeste : plugin.xml.

Dans le package net.eclipse.xhtml.editeur.actions, l'assistant a créé la classe SampleAction. Quant au fichier de manifeste, il lui a ajouté l'extension org.eclipse.ui.actionSets permettant de créer les actions voulues. Le code de plugin.xml en est donc modifié.

Voilà les lignes ajoutées :

 
Sélectionnez

<extension point="org.eclipse.ui.actionSets">
   <actionSet label="Sample Action Set"
               visible="true"
               id="net.eclipse.xhtml.editeur.actionSet">
      <menu label="Sample &amp;Menu" id="sampleMenu">
         <separator name="sampleGroup"></separator>
      </menu>
      <action label="&amp;Sample Action"
               icon="icons/sample.gif" 
			   class="net.eclipse.xhtml.editeur.actions.SampleAction" 
			   tooltip="Hello, Eclipse world" 
			   menubarPath="sampleMenu/sampleGroup"
			   toolbarPath="sampleGroup"
			   id="net.eclipse.xhtml.editeur.actions.SampleAction">
      </action>
   </actionSet>
</extension>

Et voilà le résultat obtenu le plug-in une fois démarré :

Image non disponible
Première exécution de l'action élémentaire

Quant à la classe SampleAction, elle possède quelques méthodes, dont une seule nous intéresse réellement, run(). C'est cette méthode qui contient le code qui sera exécuté lors du clic sur l'action.

 
Sélectionnez

public void run(IAction action) {
   MessageDialog.openInformation(
      window.getShell(),
	  "Editeur XHTML",
	  "Hello, Eclipse world");
}

2.2.4.2. Modification de l'action par défaut : mettre en gras

Maintenant que nous avons vu comment fonctionne l'action « Hello World ! », modifions là afin qu'elle ait sa place dans notre éditeur XHTML. Au clic sur l'action, on va insérer la balise permettant de changer la graisse d'un texte dans un document HTML, à savoir : « <b>monTxtEnGras</b> »

On l'insèrera avant la fin du document (repéré par la balise « </body> »).

Afin de mieux s'y retrouver plus tard, nous avons renommé SampleAction en BoldAction. Mais attention, si on modifie le nom de classe, il faut modifier plugin.xml en conséquence (remplacer chaque occurrence de « SampleAction » par « BoldAction »). Sinon l'action ne s'exécutera plus.

 
Sélectionnez

public void run(IAction action)
{
   // on descend dans la hiérarchie des conteneurs
   // à partir de la racine.
   IWorkbench monWB = PlatformUI.getWorkbench();
   IWorkbenchWindow monWBwindow = monWB.getActiveWorkbenchWindow();
   IWorkbenchPage page = monWBwindow.getActivePage();
   IEditorPart monEditeur = page.getActiveEditor();
   // on sait que notre éditeur est une éditeur de texte,
   // on transtype.
   ITextEditor monTXTEditeur = (ITextEditor) monEditeur;
   // ce qui nous permet de récupérer le fournisseur de document
   // associé à cet éditeur.
   IDocumentProvider monDocumentProvider = monTXTEditeur.getDocumentProvider();
   // puis de créer un document qui y est associé.
   IDocument monDocument = monDocumentProvider.getDocument(monTXTEditeur.getEditorInput());
   try
   { 
      /* on crée une instance de FindReplaceDocumentAdapter
	  * afin de pouvoir manipuler monDocument avec des "rechercher /
	  * remplacer"
	  */
	  FindReplaceDocumentAdapter monFindReplaceDocumentAdapter = new
                                                 FindReplaceDocumentAdapter(monDocument);
	  // on localise la région contenant la chaine "</body>" et on se
	  // place dessus.
	  monFindReplaceDocumentAdapter.find(0,"</body>",true,false,false,false);
	  // on remplace ce qu'on vient de chercher par
	  // "<b>monTxtEnGras</b>\n</body>"
	  monFindReplaceDocumentAdapter.replace
	  ("<b>monTxtEnGras</b>\n</body>",true);
	}
	catch (BadLocationException e)
	{
	   e.printStackTrace();
	}
}

2.2.4.3. Ajout d'une action : insertion d'un tableau personnalisé

Afin de compléter les notions de Shell et d'insertion de texte dans un document, nous allons cette fois-ci créer un assistant permettant d'insérer le code XHTML d'un tableau à la fin du document.

Pour cela, nous paramètrerons une fenêtre selle contenant des champs textes permettant de définir les données que l'on veut affecter au tableau. Pour cet assistant, nous avons pris exemple sur l'excellent Dreamweaver Mx qui propose ceci :

Image non disponible
Modèle d'insertion de tableau proposé par Dreamweaver

Nous avons donc créé une nouvelle classe dans le package net.eclipse.xhtml.editeur.actions que nous avons appelé TabAction. Elle reprend le code de base de BoldAction avec deux méthodes supplémentaires détaillées ci-dessous :

  • getCodeTableau() :

    Crée la fenêtre Shell avec les écouteurs associés. Au clic sur Ok, demande à buildCodeTableau() de lui fournir le code XHTML du tableau désiré.

     
    Sélectionnez
    
    private String getCodeTableau()
    {
       // Création de la fenêtre
       final Shell shell = new Shell();
       shell.setText("Insérer un tableau");
       shell.setSize(340,180);
       Display display = shell.getDisplay();
       // Création d'une nouvelle instance de CodeXHTML
       final CodeXHTML monCode = new CodeXHTML("");
       // Création des labels
       Label label1 = new Label(shell,1);
       label1.setText("Lignes :");
       label1.setBounds(5,7,60,20);
       /* LA CREATION DES AUTRES « LABEL » A ETE TRONQUEE PAR LISIBILITE */
       // Création des zones de texte
       // final, sinon on ne peut pas y accéder
       // dans l'écouteur interne anonyme
       final Text textAttrLig = new Text(shell, SWT.BORDER);
       textAttrLig.setTextLimit(50);
       textAttrLig.setText("1");
       textAttrLig.setBounds(65,5,40,20);*
       /* LA CREATION DES AUTRES « TEXT » A ETE TRONQUEE PAR LISIBILITE */
       // Création du bouton "OK"
       Button buttonOK = new Button(shell,SWT.BORDER);
       buttonOK.setText("OK");
       buttonOK.setBounds(70,110,80,30);
       // Création d'un listener sur le bouton "OK"
       buttonOK.addSelectionListener(new SelectionAdapter(){
          public void widgetSelected(SelectionEvent e){
    	     shell.setVisible(false);
    		 String sLig = textAttrLig.getText();
    		 String sCol = textAttrCol.getText();
    		 String sCellPadding = textAttrCellPadding.getText();
    		 String sCellSpacing = textAttrCellSpacing.getText();
    		 String sLarg = textAttrLarg.getText();
    		 String sBord = textAttrBord.getText();
    		 String res = buildCodeTableau(sLig, sCol, sCellPadding,sCellSpacing, sLarg, sBord);
    		 monCode.setCode(res);
    		 shell.dispose();
    	 }
       });
       // Création du bouton "Annuler"
       Button buttonCANCEL = new Button(shell,SWT.BORDER);
       buttonCANCEL.setText("Annuler");
       buttonCANCEL.setBounds(190,110,80,30);
       // Création d'un listener sur le bouton "Annuler"
       buttonCANCEL.addSelectionListener(new SelectionAdapter(){
          public void widgetSelected(SelectionEvent e){
    	     shell.dispose();
    	  }
       });
       shell.open();
       while (!shell.isDisposed()) {
          if (!display.readAndDispatch()) display.sleep();
       }
       // on retourne le code créé.
       return monCode.getCode();
    }
    
  • buildCodeTableau(String, String, String, String, String, String) :

    Méthode contenant l'algorithme de construction d'un tableau XHTML. Elle retourne une chaîne de caractère correspondant au code de ce tableau.

     
    Sélectionnez
    
    private String buildCodeTableau(String sLig, String sCol, String sCellPadding, String
    sCellSpacing, String sLarg, String sBord)
    {
       String res = new String();
       // Si les valeurs sont remplies
       if ((sLig.length()>0) && (sCol.length()>0)&& (sLarg.length()>0) && (sBord.length()>0))
       {
          res = "\n<table width=\""+sLarg+"%\" border=\""+sBord+"\"cellspacing=\""+
    	        sCellSpacing+"\" cellpadding=\""+sCellPadding+"\">";
    	  // Boucle des lignes
    	  for(int i=0;i<Integer.parseInt(sLig);i++)
    	  {
    	     res += "\n\t<tr>";
    		 // Boucle des colonnes
    		 for(int j=0;j<Integer.parseInt(sCol);j++)
    		 {
    		    res += "\n\t\t<td>&nbsp;</td>";
    		 }
    		 res += "\n\t</tr>";
    	  }
    	  res += "\n</table>";
    	  }
       return res;
    }
    

Afin de manipuler la chaîne correspondant au code, nous avons créé une classe simple (également placée dans le package net.eclipse.xhtml.editeur.actions). Nommée CodeXHTML, elle est composée d'un attribut privé (la chaîne), d'un accesseur en lecture, et d'un autre en écriture.

 
Sélectionnez

public class CodeXHTML
{
   private String monCode = null;
   public CodeXHTML(String monCode)
   {
      this.monCode = monCode;
   }
   public String getCode()
   {
      return monCode;
   }
   public void setCode(String monCode)
   {
      this.monCode = monCode;
   }
}

Note : une Javadoc des classes et méthodes créées est disponible en annexe.

2.2.5. Perspective

2.2.5.1. Définition

Une perspective est un ensemble de vues et d'éditeurs affiché à un instant « t » par Eclipse. Pour développer du XHTML, nous n'avons pas besoin d'un ensemble complexe de vues. Nous composerons notre perspective d'une vue « Navigator » permettant d'explorer l'arborescence de la ressource en cours (à la manière de l'explorateur windows) à laquelle nous ajouterons une vue « Tasks », pour l'exemple.

Comme nous l'avons vu tout au long de ce chapitre, l'ajout de fonctionnalités à notre plug-in se divise très souvent en deux parties : l'ajout de classe et la modification du fichier plugin.xml. La définition d'une nouvelle perspective ne déroge pas à la règle.

2.2.5.2. La classe XHTMLPerspectiveFactory

Pour notre perspective, nous avons créé un nouveau package. Comme il existe net.eclipse.xhtml.editeur.actions, ou net.eclipse.xhtml.editeur.editors, nous avons créé net.eclipse.xhtml.editeur.perspectives.

Une perspective se génère grâce à une classe implémentant l'interface IPerspectiveFactory. C'est pourquoi nous avons affecté à notre nouveau package une classe XHTMLPerspectiveFactory qui l'implémente. On y définit les vues qui vont être associées à notre perspective.

 
Sélectionnez

public class XHTMLPerspectiveFactory implements IPerspectiveFactory
{
   public void createInitialLayout(IPageLayout layout)
   {
      String editorArea = layout.getEditorArea();
	  IFolderLayout topLeft = layout.createFolder("topleft",IPageLayout.LEFT,0.25f,editorArea);
	  // L'explorateur de ressources.
	  topLeft.addView(IPageLayout.ID_RES_NAV);
	  // La vue "Tasks".
	  layout.addView(IPageLayout.ID_TASK_LIST,
	  IPageLayout.BOTTOM, 0.66f, editorArea);
	}
}

2.2.5.3. Modification du plugin.xml

Une fois la classe créée, il faut construire les entrées de menu qui permettront de passer à cette nouvelle perspective.

Pour cela, il faut ajouter à l'onglet « Extension » un point d'extension org.eclipse.ui.perspective, lui ajouter une nouvelle perspective (clic droit > new > perspective), et définir que c'est notre classe XHTMLPerspectiveFactory située dans le package net.eclipse.xhtml.editeur.perspectives qui devra être exécutée lorsque cette perspective sera sélectionnée. Ce qui doit donné ce résultat :

Image non disponible
Insertion d'une extension perspective avec PDE

Cela revient à rajouter ces lignes dans le fichier plugin.xml :

 
Sélectionnez

<extension point="org.eclipse.ui.perspectives">
   <perspective
      id="net.eclipse.xhtml.editeur.perspectives.XHTMLPerspectiveFactory"
	  name="XHTML"
	  icon="icons/sample.gif"
	  class="net.eclipse.xhtml.editeur.perspectives.XHTMLPerspectiveFactory">
   </perspective>
</extension>

2.2.6. Déploiement du plug-in

Ca y est, notre plug-in est terminé, on ne peut alors résister à l'envie de vouloir le partager avec la terre entière. PDE rend l'étape de déploiement du plug-in très abordable. Une fois tous les fichiers de vos différents packages enregistrés, il faut ouvrir l'assistant exportation (« Fichier » > « Exporter »), choisir « Exportation de plug-ins et fragments ».

La page suivante s'ouvre :

Image non disponible
Exportation du plug-in en un fichier zip

Il faut donc cocher notre plug-in pour l'exporter, choisir l'option de déploiement d'un simple fichier zip, c'est encore le plus pratique. Il ne reste plus qu'à donner un nom à notre archive, de choisir si oui ou non on désire inclure les sources à l'archive, puis de terminer l'assistant.

On obtient ainsi un zip qu'il suffit de décompresser dans le répertoire « plugins » de votre plateforme Eclipse.

Il y a cependant certaines chances pour que le plug-in ne se démarre pas. Pour éviter cela, démarrer votre plug-in avec l'option « - clean ». Pour ce faire, clic droit sur l'exécutable d'Eclipse, choisissez « Propriétés ». Enfin, changez « eclipse.exe » par :

 
Sélectionnez

eclipse.exe -clean -workspace c:\cheminDuWorkspace 	

3. Résultats

3.1. Wizard « Nouveau projet »

Image non disponible
Nouveau projet

3.2. Wizard « Nouveau fichier »

Image non disponible
Nouveau fichier

3.3. Coloration syntaxique

Image non disponible
Exemple de coloration de la syntaxe dans l'éditeur

3.4. Assistants d'insertion de code

3.4.1. Texte en gras

Image non disponible
Code inséré après exécution de l'action mettre en gras

3.4.2. Tableau XHTML

Image non disponible
Assistant d'insertion de tableau de dreamweaver
Image non disponible
Assistant que nous avons créé
Image non disponible
Exemple de code de tableau généré par notre assistant

3.5. Perspective dédiée

Image non disponible
Perspective XHTML

Elle est constituée de trois vues, d'un éditeur, et d'un jeu d'action dédié (mettre en gras et insertion de tableau).

4. Discussion

L'originalité de ce projet avec le faible nombre de précurseurs en la matière ont fait que nous avons passé énormément de temps à comprendre comment développer les fonctionnalités dont nous voulions que notre plug-in soit pourvu. Ce n'est que récemment que nous avons pu nous débloquer et donner à notre application des fonctions essentielles comme l'ajout d'assistants d'insertion de code. C'est dommage que nous ayons dû arrêter le développement pour bien avancer le rapport alors que nous commencions tout juste à bien comprendre les rouages d'Eclipse.

Ainsi, on aurait pu imaginer un bouton d'action s'occupant de déterminer si un document HTML était conforme ou non à la norme XHTML, ainsi que diverses autres fonctionnalités qui auraient pu permettre un codage simplifié et agréable. Nous pensons plus particulièrement à des outils comme une vue « Aperçu de la page en cours » et un assistant de contenu permettant de choisir parmi une liste de proposition de syntaxe durant l'écriture du code.

Nous avons détaillé plus haut dans ce rapport l'ajout d'un nouveau wizard à notre plug-in qui crée un nouveau projet. Or, comme nous l'expliquions également plus haut, ce wizard n'est pas tout à fait opérationnel. Les ressources physiques (dossier et fichier .project) sont bel et bien créées et remplies, mais le wizard plante toujours. Cela n'empêche pas l'utilisation du projet (en l'important via l'assistant d'importation habituel), mais on se serait bien passé de l'affichage d'une erreur et du fait que l'assistant ne se ferme pas automatiquement après le clic sur « Finish ».

5. Conclusion

Le livre "Eclipse, principes patterns et plug-in" (voir bibliographie) nous prévient dès les premières pages : "Débuter avec Eclipse peut se comparer à un parachutage les yeux bandés au dessus de Bangkok.", "Préparez-vous à des séances de programmation à l'efficacité croissante constituée de six heures de lecture de code et d'une seule heure de programmation au sens classique".

Bref, débuter le développement de plug-in sous Eclipse n'est pas une mince affaire. Or, une fois notre sujet recadré, nous nous étions fixé la création d'un éditeur aux fonctionnalités les plus élémentaires et les résultats sont là : un plug-in fonctionnel, disposant de wizards, d'une perspective, et d'assistants d'insertion de code. C'est pourquoi nous sommes satisfaits du travail accompli, et ce, en un temps si réduit.

Rappelons que cette publication est à l'origine notre rapport de projet de fin d'étude en licence professionnelle "développeur d'applications e-business" à l'IUT de Montpellier. Notre motivation et notre détermination pour mener à bien ce projet n'ont été que galvanisé par la mise en ligne de celui-ci. C'est en effet la première fois que nous travaillons un projet avec la réelle certitude que d'autres développeurs reprendront notre travail là où on l'a laissé, ce qui en fait un projet à la fois original et très enrichissant.

Annexes

Références bibliographiques et réseaugraphiques

Références bibliographiques :
Erich Gamma & Kent Beck (2004), Eclipse : Principes, patterns et plug-in, CampusPress
Claude Delannoy (2004), Programmer en Java, Eyrolles
Fichier d'aide et Javadoc d'Eclipse

Références réseaugraphiques :
http://www.eclipse.org
Site officiel du projet Eclipse. Regorge d'articles complets et intéressants mais ... en anglais.
http://www.developpez.com
Site d'entraide des développeurs francophones (tout langage, tout niveau).
http://www.eclipse.audaly.com/
Tutoriaux « Développer un plug-in Eclipse » et « Développer un éditeur Eclipse »
http://igm.univ-mlv.fr/~dr/XPOSE2004/vforel/index.html
Création par un élève ingénieur d'un plug-in gérant la création d'une méthode get() et set() pour un attribut donné.

Dossier d'analyse

Image non disponible
Cas d'utilisation générique
Image non disponible
Diagramme de séquence de l'action « Insérer un tableau »
Image non disponible
Implémentation d'une ressource
Image non disponible
Implémentation d'un document
Image non disponible
Implémentation d'une sélection dans un TextViewer

Glossaire des sigles et abréviations

  • Classe : ensemble d'attributs et de méthodes décrivant un type d'objet qui pourra être manipulé avec les méthodes présentes dans celle-ci.
  • Dreamweaver mx : un des meilleurs logiciels de conception web actuel.
  • HTML : « HyperText Markup Language ». Langage statique permettant de mettre en forme des documents complexes comme les pages web.
  • IDE : « Integrated Development Environment ». Dans ce genre d'environnement, le programmeur dispose à partir de la même interface d'outils comme l'éditeur, le compilateur ou le débogueur.
  • Java : langage orienté objet créé en 1991 dans les laboratoires de Sun. C'est ce langage qui a été utilisé pour développer Eclipse, c'est donc celui-ci que nous avons utilisé pour développer le plug-in.
  • Librairie jar : au même titre que « rar » ou « zip », « jar » est un fichier d'archive contenant les ressources nécessaires à la bonne exécution d'une application Java.
  • Package : dossier regroupant un ensemble de classes.
  • Plug-in : de l'anglais « to plug : brancher ». Composant indépendant de l'application principale venant se rajouter à celle-ci pour lui apporter une nouvelle fonctionnalité.
  • Shell : type de fenêtre pouvant être généré par du code Eclipse. Elle pourrait se comparer à une « JFrame » en code Java.
  • Wizard : en français « Magicien ». Assistant divisant la création d'une tâche complexe en plusieurs étapes simples et rapides.
  • Workbench : plan de travail qui s'affiche au lancement d'Eclipse.
  • XHTML : « eXtended HyperText Markup Language ». Successeur de HTML, sa construction est plus rigoureuse ce qui le rend plus facile à interpréter par des périphériques multimédias ayant une faible capacité de calcul (smart phone, PocketPC, etc.).

Téléchargements