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é 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ée 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ée, 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ées sur ce rapport.
I. Introduction▲
Ce projet a de particulier qu'il n'a pas été proposé par le corps enseignant. À 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 à maturité 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 paru 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.
II. Présentation générale▲
II-A. Moyens et méthodes▲
II-A-1. Le projet Eclipse▲
Eclipse est un environnement de développement intégré (Integrated Development Environment) dont le but est de fournir une plateforme 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 plateforme nommée « Runtime », tout le reste de la plateforme est développé sous la forme de plug-ins. Ce concept permet de fournir un mécanisme pour l'extension de la plateforme et ainsi fournir la possibilité à tout le monde de développer des fonctionnalités qui ne sont pas fournies en standard par Eclipse. 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).
II-A-1-a. 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 plateforme 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 plateforme ;
- un support multilangage grâce à des plug-ins dédiés : C, PHP, C#… ;
- support de plusieurs plateformes 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ères modifications ;
- propose le nécessaire pour développer de nouveaux plug-ins ;
- La plateforme est entièrement internationalisée dans une dizaine de langues 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.
II-A-1-b. 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.
II-A-1-b-i. 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).
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.
II-A-1-b-ii. 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.
II-A-1-b-iii. 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
II-B. Cahier des charges▲
II-B-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 par 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 a apparu à ce moment précis : pourquoi ne pas développer notre propre plug-in ?
À côté 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 a 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.
II-B-2. Choix du XHTML▲
Comme il est dit ci-dessus, à l'origine nous nous sommes orienté 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 certain nombre d'avantages à 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.
II-B-3. Fonctionnalités requises▲
II-B-3-a. 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.
II-B-3-b. 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.
II-B-3-c. 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.
II-B-3-d. 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 ».
II-C. Programmation▲
II-C-1. PDE▲
II-C-1-a. 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.
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 bibliothèque jar qui sera créée lors de l'étape de déploiement 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.
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 nouveaux fichiers ;
- 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 :
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.
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 :
- Explorateur de package classique avec lequel vous pouvez parcourir et ouvrir les classes et packages souhaités.
- Éditeur multionglet 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.).
- Console permettant d'afficher les éventuelles traces et erreurs que votre plug-in pourra générer.
- Explorateur avancé de la page en cours d'édition.
II-C-1-b. Première exécution▲
À 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é.
La présence de notre « Sample Action » dans le menu nous indique qu'on vient bel et bien d'exécuter notre plug-in. À 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 « À propos », choisissez « Plug-in details ».
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.
II-C-2. Les « Wizards »▲
II-C-2-a. 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 :
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.
II-C-2-b. 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 projets simples 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.
II-C-2-b-i. Création des classes correspondantes▲
Nous nous sommes inspiré 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 projets 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.
// 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
(
);
// 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);
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
(
));
}
/**
* 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é que nous sommes près du but, mais une erreur subsiste toujours :
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 projets qu'Eclipse fournit : File > Import > Existing project in workspace.
II-C-2-b-ii. Modification de plugin.xml en conséquence▲
Comme nous l'avons vu précédemment, PDE dispose d'une interface multionglet 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.
II-C-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 nôtre.
On rajoute donc un attribut public :
public
final
static
String MON_COMMENT =
"__mon_comment"
;
Ainsi que le code suivant au constructeur :
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 » à trois cellules.
Dans XMLDocumentProvider, on rajoute une entrée au tableau de String passé en paramètre à la construction du DefaultPartitionner :
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.
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 :
RGB MON_COMMENT =
new
RGB
(
50
, 220
, 240
);
II-D. Les actions▲
II-D-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 :
<extension
point
=
"org.eclipse.ui.actionSets"
>
<actionSet
label
=
"Sample Action Set"
visible
=
"true"
id
=
"net.eclipse.xhtml.editeur.actionSet"
>
<menu
label
=
"Sample &Menu"
id
=
"sampleMenu"
>
<separator
name
=
"sampleGroup"
></separator>
</menu>
<action
label
=
"&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é :
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.
public
void
run
(
IAction action) {
MessageDialog.openInformation
(
window.getShell
(
),
"Editeur XHTML"
,
"Hello, Eclipse world"
);
}
II-D-2. Modification de l'action par défaut : mettre en gras▲
Maintenant que nous avons vu comment fonctionne l'action « Hello World ! », modifions-la 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.
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 un é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
(
);
}
}
II-D-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, celle contenant des champs texte 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 :
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électionnezprivate
StringgetCodeTableau
(
){
// 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 CRÉATION DES AUTRES « LABEL » A ÉTÉ TRONQUÉE PAR LISIBILITÉ */
// 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 CRÉATION DES AUTRES « TEXT » A ÉTÉ TRONQUÉE PAR LISIBILITÉ */
// 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ères correspondant au code de ce tableau.
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> </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.
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.
II-E. Perspective▲
II-E-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.
II-E-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.
public
class
XHTMLPerspectiveFactory implements
IPerspectiveFactory
{
public
void
createInitialLayout
(
IPageLayout layout)
{
String editorArea =
layout.getEditorArea
(
);
IFolderLayout topLeft =
layout.createFolder
(
"topleft"
,IPageLayout.LEFT,0.25
f,editorArea);
// L'explorateur de ressources.
topLeft.addView
(
IPageLayout.ID_RES_NAV);
// La vue "Tasks".
layout.addView
(
IPageLayout.ID_TASK_LIST,
IPageLayout.BOTTOM, 0.66
f, editorArea);
}
}
II-E-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 donner ce résultat :
Cela revient à rajouter ces lignes dans le fichier plugin.xml :
<
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>
II-F. Déploiement du plug-in▲
Ça 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 :
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 :
eclipse.exe -clean -workspace c:\cheminDuWorkspace
III. Résultats▲
III-A. Wizard « Nouveau projet »▲
III-B. Wizard « Nouveau fichier »▲
III-C. Coloration syntaxique▲
III-D. Assistants d'insertion de code▲
III-E. Perspective dédiée▲
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).
IV. Discussion▲
L'originalité de ce projet avec le faible nombre de précurseurs en la matière a 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 propositions 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 ».
V. 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 satisfait 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'études 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ées 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.
https://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▲
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 actuels.
- 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.
- bibliothèque 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.).