Premiers pas avec Eclipse Scout

Jérémie Bresson

Cet article propose une présentation détaillée du framework Eclipse Scout.

Le chapitre II illustre la réalisation complète d'une application à travers un exemple. Le code source de l'exemple est disponible en téléchargement.

Commentez

- Titre : Premiers pas avec Eclipse Scout

- Auteur : Jérémie Bresson

- Parution : 26 mars 2012

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2012 Jérémie Bresson. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Présentation

- I-A. Applications réalisées

- I-B. Partie SDK

- I-C. Partie Runtime

- I-D. Un peu d'histoire

- II. Un exemple complet d'utilisation

- II-A. Aperçu et prérequis

- II-B. Installation

- II-C. Création du projet

- II-D. Formulaire pour lister les questions

- II-E. Connexion à la base de données

- II-F. Formulaire pour ajouter une réponse

- II-G. Relier le formulaire AnswersForm à la base de données

- II-H. Déployer sur un serveur Tomcat

- II-I. Aller plus loin

- III. En conclusion

- IV. Remerciements

- V. Annexes

- V-A. Script SQL

- V-B. Sources de l'application

- V-C. Disclaimer

I - Présentation

Eclipse Scout est un outil de création d'applications métier orientées service en Java. Il se situe dans la lignée des ateliers de génie logiciel, en proposant une approche moderne, ouverte et simple d'accès. Il comprend deux composants : une partie SDK (une perspective de plus dans l'IDE Eclipse pour créer l'application) et une partie runtime (intégrée aux applications). Ces deux composants permettent de guider le développeur pour qu'il utilise une architecture définie. C'est l'idée générale d'Eclipse Scout : utiliser les technologies de la plateforme Eclipse pour simplifier et accélérer la réalisation de logiciels.

Depuis 2010, c'est un projet de la fondation Eclipse disponible en open source sous licence EPL. En 2011, il est livré pour la première fois avec le release train officiel d'Eclipse et est disponible sous forme de package officiel sur la page des téléchargements d'Eclipse.

I-A - Applications réalisées

Les applications réalisées avec Eclipse Scout sont robustes, avec une cohérence pour l'utilisateur. De nombreuses fonctionnalités se retrouvent partout. Par exemple, toutes les listes de données peuvent être réorganisées : modification de l'ordre des colonnes par glissé-déposé, affichage/masquage des colonnes, ajout de filtres.

Au niveau des formulaires de saisie des données, l'utilisateur se retrouve en terrain connu. Il retrouve des champs de saisie classiques. De petites fonctionnalités facilitent le travail au quotidien. Par exemple pour le sélecteur de date, l'utilisateur pourra soit utiliser un calendrier, soit utiliser les flèches du clavier pour faire défiler les jours ou encore écrire « +7 » pour fixer la date dans sept jours.

Les applications sont pensées pour être multilingues dès leur création, facilitant le travail de traduction pour disposer d'une application dans la langue de l'utilisateur.

Eclipse Scout s'utilise traditionnellement pour des applications client-serveur, orientées service, utilisant une base de données comme couche de persistance. Comme le code est accessible et qu'il est ouvert, il est possible de réaliser tout autre type d'applications.

Les applications réalisées sont basées sur Java/Eclipse et s'intègrent facilement dans la majorité des environnements IT.

I-B - Partie SDK

Le code des applications Eclipse Scout est du Java lisible. Il définit l'application et sert de référence : il n'y a pas de fichier de configuration ou de cache supplémentaire. Il est possible d'écrire son code « à la main » à l'aide de n'importe quel IDE Java (voire même un simple éditeur de texte).

Cependant pour faciliter et accélérer le travail du développeur, Eclipse Scout propose une partie SDK. Il s'agit d'une perspective supplémentaire dans l'IDE Eclipse qui va permettre de générer facilement et de manière intuitive le code Java nécessaire. Ainsi le développeur peut se concentrer sur ce qui compte vraiment pour son application : l'affichage et les fenêtres d'édition des données.

L'idée est de partir de l'interface utilisateur : ce que l'utilisateur verra. Cette interface influence l'architecture de l'application : services, permissions, objets de transfert de données… Une partie de ce code peut être générée automatiquement, évitant au développeur d'avoir à s'en soucier.

Scout SDK met à disposition plusieurs vues et assistants. La vue Scout Explorer représente l'application (sous forme d'arborescence). Différents menus permettent d'agir sur l'application (ajouter un formulaire, un champ…). La vue Scout Object Properties va permettre de configurer l'élément actif (choisir le titre d'une fenêtre, l'état par défaut d'un champ). La perspective Scout laisse une grande place à l'éditeur Java : en effet, les vues et assistants créent directement le code Java correspondant. On se situe au même niveau que les outils d'édition du code java proposé par Eclipse (template, refactoring…) avec des possibilités supplémentaires.

Il ne s'agit pas de choisir entre écrire du code à la main (disons dans la perspective Java) ou utiliser la perspective Scout. Les deux approches sont possibles simultanément. Les outils de la perspective créent le code Java, mais ils sont aussi capables de se mettre à jour si le code change par ailleurs. En fonction de ses habitudes et du type de modification à effectuer, il est possible d'utiliser l'une ou l'autre approche.

Cette double approche permet de travailler dans des équipes avec un niveau hétérogène. Un développeur qui ne connaîtrait pas le framework va travailler avec la perspective Scout et apprendre en utilisant les outils. Un développeur plus expérimenté pourra faire le choix de coder directement le code Java.

Le code produit par les outils est propre et lisible. Il respecte une architecture définie, sans que le développeur ait à réfléchir. Les outils du SDK créent, modifient et placent le code au bon endroit.

Les applications Eclipse Scout sont pensées pour être fonctionnelles dès leur création à partir d'un template. Lors des phases de prototypage ou de création d'application, cela permet d'accélérer le développement et de pouvoir présenter les modifications rapidement.

I-C - Partie Runtime

Le runtime est intégré à chaque application réalisée (partie client ou partie serveur). Il utilise les technologies de la plateforme Eclipse pour créer des applications finies et faire communiquer entre elles de manière transparente la partie client et la partie serveur. Ainsi le développeur se concentre sur l'essentiel : côté client la définition des éléments de l'application vue par l'utilisateur (fenêtres, menus, formulaires…), et côté serveur la gestion des données (celles à saisir ou à afficher).

La partie serveur est hébergée sur un serveur d'application Java (Tomcat, Weblogic…). Elle met à disposition du client un certain nombre de services pour afficher et manipuler les données. L'idée est de s'interconnecter à d'autres services JEE et/ou à une base de données (JDBC). Les services sont définis par des interfaces Java et exposés via OSGi. C'est un système de Service Registery disposant d'un mécanisme de priorité. Les Services peuvent être appelés depuis le client ou le serveur, Eclipse Scout se chargeant de transmettre les données de l'un à l'autre si nécessaire.

La partie client est celle que l'utilisateur final voit. Comme dans toute application, on retrouve les éléments traditionnels : fenêtres, menus, formulaires… Pour la navigation dans les données, Eclipse Scout propose un principe d'arborescence de pages couplé à des formulaires de recherche. D'autres formulaires offrent la possibilité d'éditer les données. En fonction du type d'application, on pourra ouvrir ces formulaires dans des fenêtres modales, ou les présenter successivement (à la manière d'un assistant) pour travailler par processus.

Eclipse Scout propose une stratégie multifront-end. Plusieurs bibliothèques graphiques sont supportées (Swing, SWT, Web avec RAP…). Pour arriver à ce but, seul un modèle du client doit être défini (en Java). Le framework se charge de créer et gérer le rendu de l'interface utilisateur. Ainsi le développeur ne programme pas le détail du rendu, mais se concentre sur la manière dont les données vont être affichées (les interactions et la logique métier), évitant le travail de gestion fine de la bibliothèque graphique.

Pour résumer, la partie runtime s'appuie sur la plateforme Eclipse et simplifie sa mise en œuvre. Cette simplification passe par un certain nombre de choix qui pourraient être limitants pour des besoins spécifiques, mais le framework est suffisamment ouvert pour ajouter les éléments manquants.

I-D - Un peu d'histoire

Scout est le framework interne de la société BSI Business System Integration AG depuis plus de dix ans. D'abord basé sur d'autres technologies (notamment des fichiers de configuration XML), c'est un framework 100 % Java depuis 2007.

En 2010, il est soumis à la fondation Eclipse sous forme de proposal, ce qui donne naissance au projet Eclipse Scout. Après plusieurs mois pour franchir toutes les étapes du Eclipse Development Process, le code source est rendu disponible sur les serveurs de la fondation sous licence EPL vers la fin 2010.

En 2011, Eclipse Scout participe au release trainannuel d'Eclipse. Avec la version 3.7 (Eclipse Indigo), une distribution packagée est proposée au téléchargement.

II - Un exemple complet d'utilisation

Voici un exemple complet d'utilisation d'Eclipse Scout : de l'installation au déploiement sur un serveur Tomcat. Nous allons créer pas à pas une petite application de QCM (questionnaire à choix multiples).

II-A - Aperçu et prérequis

L'application doit afficher la liste des questions et proposer d'ajouter de nouvelles réponses. Une réponse est définie par un nom et une série de choix (on présente une ListBox à l'utilisateur). On déploiera l'application réalisée sur un serveur Tomcat. Voici la maquette de ce à quoi doit ressembler cette application :

Le code généré par Eclipse Scout est en Java, il faut donc en posséder les rudiments. Comme les données sont stockées dans une base de données, il est préférable de connaître un minimum le SQL. Ce tutoriel utilise principalement les outils du SDK, il peut donc s'adresser à des développeurs débutants.

La base de données Derby doit déjà être installée et contenir quelques questions. Cette base est rudimentaire, mais contient le nécessaire pour l'application de QCM : une table pour les questions, reliée avec des choix et des réponses. Chaque réponse peut contenir plusieurs choix. Un script de création de la base et de remplissage de données est fourni en annexe (voir V-A). Sans base de données il faudra ignorer l'étape III-5 et certaines parties de l'étape III-6. Dans ce cas, l'application sera fonctionnelle, mais ne gardera pas mémoire des modifications.

II-B - Installation

Le moyen le plus simple pour obtenir une version d'Eclipse avec les outils d'Eclipse Scout est de télécharger la version dédiée « Eclipse for Scout developpers » sur la page des téléchargements d'Eclipse.

Pour les connaisseurs d'Eclipse, il est également possible d'utiliser l'update site d'Eclipse Indigo. http://download.eclipse.org/releases/indigo. Dans ce cas, il faudra ajouter la perspective Scout manuellement après avoir relancé Eclipse.

II-C - Création du projet

Dans la perspective Scout, se trouve sur la gauche la vue Scout Explorer. Dans le menu contextuel sur le dossier « Scout projects » sélectionner « New Scout Project… ».

Dans la fenêtre qui s'ouvre, choisir un nom pour le projet : « mcq » et un alias pour le projet : « MCQ ». À cette étape, il est possible de sélectionner quel moteur de rendu (SWT ou Swing) va être utilisé. Par défaut les deux sont cochés, mais il est possible de n'en garder qu'un des deux. À l'étape 2, vérifier que le type d'application est bien « Application with a single form »

Il est d'ores et déjà possible de démarrer l'application : dans la vue Scout Explorer sélectionner la partie serveur « server ». Dans la vue Scout Object Properties cliquer sur l'icône debug (le petit cafard vert) du mode « development ».

La même chose avec la partie client rendue avec SWT « ui.swt ». L'application (une fenêtre vide) apparaît après l'écran d'accueil.

II-D - Formulaire pour lister les questions

Le premier (et pour l'instant le seul) formulaire, créé par le SDK avec l'application se nomme DesktopForm. Nous allons ajouter une table qui contiendra la liste des questions.

Naviguer dans la vue Scout Explorer jusqu'à ce formulaire (Scout Projects > mcq > client > Forms > DesktopForm). En le sélectionnant, la liste des propriétés s'affiche dans la vue « Scout Object ». Saisir « Questions » dans la propriété « Title », valider en sélectionnant « New translated text… ». La fenêtre qui s'ouvre permet de saisir les traductions pour une application multilingue. Valider avec OK, le code Java correspondant, ainsi que les ajouts dans les fichiers de traduction sont effectués.

De la même manière, nous allons ajouter un champ TableField qui contiendra la liste des questions. Dans la MainBox du DesktopForm, sélectionner « New Form Field… » avec le menu contextuel. Dans la liste des types de champ, choisir « table field » et cliquer sur « next > ». Donner un nom (name) « Questions » (si tout va bien la traduction ajoutée juste avant est à nouveau proposée). « Type Name » est le nom de la classe Java qui va définir ce champ, le SDK propose QuestionsField par défaut.

Le code Java est ajouté et le champ apparaît dans l'arborescence de l'application. Déplier l'arborescence : QuestionField > Table > Columns et choisir « New columns… » dans le menu contextuel. La première colonne sert à stocker l'id de la question. Sélectionner Integer Column. Donner un nom « Nr », et un Type Name « QuestionNrColumn ».

Dans les propriétés de la colonne QuestionNrColumn créée, cocher « primary key » et décocher la propriété « visible » (par défaut cette colonne ne sera pas affichée).

De la même manière ajouter une StringColumn : name : « Question » (au singulier maintenant) et Type Name : « QuestionColumn ».

Il s'agit maintenant d'ajouter du code dans la partie serveur. Déplier l'arborescence de l'application Scout Projects > mcq > server > Process Services > DesktopProcessService et double-cliquer sur la fonction load pour ouvrir le code Java correspondant à la fonction.

Voici le code permettant d'ajouter deux questions (il s'agit de faire un essai, nous connecterons la base de données dans l'étape suivante) :

public DesktopFormData load(DesktopFormData formData) throws ProcessingException {
formData.getQuestions().addRow(new Object[]{1, "Quel est le meilleur IDE ?"});
formData.getQuestions().addRow(new Object[]{2, "Quel est le meilleur smartphone sous Android ?"});
return formData;
}

Lancer l'application.

Note : pour une question de cosmétique, dans les versions récentes du code, le formulaire par défaut a été renommé (QuestionsListForm) ainsi que le FormData, et le ProcessService.

II-E - Connexion à la base de données

Nous allons maintenant remplacer le ProcessService de test de l'étape précédente par une connexion à la base de données. Il s'agit tout d'abord d'ajouter le Service SQL qui sera utilisé par les process services du serveur. Déplier l'arborescence de l'application : server > Common Services > Sql Services. Sélectionner « New Sql Service… » dans le menu contextuel.

Donner un nom (Type Name) : McqDerbySqlService et sélectionner la classe parente correspondant à Derby comme Super Type : AbstractDerbySqlService.

Le Service ainsi créé n'est pas encore configuré. Pour le faire, il faut le sélectionner dans l'arborescence (Scout Explorer View) : server > Common Services > Sql Services > McqDerbySqlService. Dans la vue Scout Object Properties, il faut paramétrer les attributs suivants :

- Jdbc Mapping Name : le chemin de connexion à la base de données (construit sur le modèle « jdbc:derby:[chemin vers le fichier] ») ;

- Username : le nom de l'utilisateur de la base de données ;

- Password : le mot de passe de cet utilisateur.

Il reste à utiliser ce service SQL pour réécrire le process service de l'étape III-D. Dans la liste contenant le numéro de question et le titre de la question, il faut charger le contenu de la table « questions ». La requête SQL est tout simplement :

select question_id, question_text from questions

Scout met à disposition une surcouche à l'interface JDBC traditionnelle en permettant de réaliser un binding vers des objets Java (un formdata par exemple). Ceci est réalisé à l'aide du mot-clé 'into' ajouté à la requête SQL. Le mapping s'effectue en indiquant le nom de l'objet précédé d'un deux-points. Cela fonctionne avec les variables ou les champs des formdata (sans le suffixe « Property » ou « Field »), les colonnes des tables (sans le suffixe « Column ») ou encore les setters d'un POJO (sans le préfixe « set »). Scout se charge d'effectuer la conversion et l'affectation de la valeur de la base de données dans l'objet java.

La requête s'écrit :

select question_id, question_text from questions into :QuestionNr, :QuestionText

La requête doit être passée au service sql (qu'il est possible d'atteindre avec la classe SQL) comme paramètre de la fonction selectInto(..). Il faut aussi passer à cette fonction les objets Java que l'on souhaite affecter. La fonction load du process service devient :

public QuestionsListFormData load(QuestionsListFormData formData) throws ProcessingException {
SQL.selectInto(" select question_id, question_text " +
" from  questions " +
" into :QuestionNr, :QuestionText",
formData.getQuestions());
return formData;
}

Relancer l'application. Les données proviennent maintenant de la base de données.

II-F - Formulaire pour ajouter une réponse

Nous allons maintenant ajouter le formulaire permettant de répondre à une question. Dans l'arborescence, sélectionner client > forms et choisir « New Form… » dans le menu contextuel. Donner un nom (Name) « Réponse » (avec le mécanisme de traduction). Le nom technique (Type Name) est « AnswerForm ». La classe parente (Super Type) reste « AbstractForm » et laisser cochée la case pour la génération d'un Form ID (cet identifiant correspondra à la valeur answer_id dans la base de données).

Comme dans le premier formulaire de l'étape III-D, se trouve déjà un champ de type GroupBox nommé MainBox. Toujours de la même manière il faut configurer ce champ et lui ajouter des champs fils. Voici les paramètres de configuration des champs :

Champ

Configuration dans l'assistant de création

Configuration dans la vue « Scout Object Properties »

MainBox (racine du formulaire, de type GroupBox)

-

- GridColumnCount : 1 (pour ne pas avoir deux colonnes de champs)

QuestionNrField (affiche le numéro de la question, non modifiable)

- Type : Integer Field

- Name : Question Nr

- Type Name : QuestionNrField

- Enabled : décoché (ce n'est pas une valeur modifiable)

QuestionTextField (affiche le numéro de la question, non modifiable)

- Type : String Field

- Name : Question

- Type Name : QuestionTextField

- Enabled : décoché (ce n'est pas une valeur modifiable)

- Grid H : 2 (pour que le champ ait une hauteur de 2)

- Multiline Text : coché (pour afficher le texte sur plusieurs lignes)

- Wrap Text : coché (pour activer la césure des lignes longues)

YourNameField (champ obligatoire pour saisir son nom)

- Type : String Field

- Name : Votre nom

- Type Name : YourNameField

- Mandatory : décoché (ce n'est pas une valeur modifiable)

ChoicesField (réponses à sélectionner)

- Type : List Box

- Name : Réponses

- Type Name : AnswersField

- Generic Type : Long

- Code Type : (aucun)

- Grid H : 6 (pour que le champ ait une hauteur de 6)

- Master Field : QuestionNrField (permet d'indiquer au LookupService que les réponses proposées doivent être celles d'une question particulière)

- Lookup Call : (il faudra le créer, voir III-G)

Il faut maintenant relier ce formulaire au formulaire listant les questions. Naviguer dans l'arborescence jusqu'à client > Forms > DestokpForm > MainBox > QuestionsField > Table > Menus, sélectionner « New Menu… » puis renseigner le nom (Name) « Ajouter une réponse… » et le nom technique (Type Name) « AddAnAnswerMenu ». Laisser la classe parente (Super Type) à « AbstractMenu ».

Il reste à ajouter le code java qui permet d'ouvrir notre formulaire. Dans l'arborescence sélectionner le menu nouvellement créé, et ajouter l'événement action en cliquant sur le + en face de « Exec Action ». La fonction Java est créée au bon endroit du code. Il faut ajouter un petit peu de logique pour instancier le formulaire de réponse, y affecter le numéro de question (afin de servir de clé), et lancer le formulaire pour créer une nouvelle réponse (startNew). Ajouter le code suivant :

@Override
protected void execAction() throws ProcessingException {
AnswerForm form = new AnswerForm();
form.getQuestionNrField().setValue(getQuestionNrColumn().getSelectedValue());
form.startNew();
}

Il est possible de lancer l'application pour observer le résultat. Dans le premier formulaire, un menu contextuel a été ajouté. Il ouvre le formulaire de réponse vide (il ne contient que le numéro de question dans le champ nom modifiable correspondant).

II-G - Relier le formulaire AnswersForm à la base de données

Il s'agit maintenant de remplir le formulaire créé à l'étape précédente avec les données de la base de données. Il y a trois choses à faire : ajouter l'intitulé de la question lors du chargement du formulaire, ajouter les choix disponibles dans la ListBox, enregistrer le formulaire dans la base de données.

Lors de la création du formulaire, nous avons choisi de générer le ProcessService associé. Dans l'arborescence de l'application « Scout Projects > mcq > server > Process Services » le service AnswerProcessService a été ajouté. Il contient par défaut quatre méthodes dont prepareCreate qui est appelée à l'ouverture du formulaire démarré avec startNew. La fonction prepareCreate contient déjà du code qui vérifie que l'utilisateur possède la permission de créer une réponse (ce code a été ajouté lors de la création du formulaire, car nous avons laissé les réglages par défaut.) Nous allons utiliser un appel SQL pour charger l'intitulé de la question correspondant au numéro QuestionNr.

@Override
public AnswerFormData prepareCreate(AnswerFormData formData) throws ProcessingException {
if (!ACCESS.check(new CreateAnswerPermission())) {
throw new VetoException(Texts.get("AuthorizationFailed"));
}

SQL.selectInto(" select question_text " +
" from  questions " +
" where question_id = :QuestionNr " +
" into  :questionText", formData);

return formData;
}

En relançant l'application, la question s'affiche dans le formulaire à son ouverture.

Pour le champ choix, nous utilisons une ListBox. Nous allons lui associer un Lookup Service, pour définir le contenu de cette liste. Dans l'arborescence de l'application sélectionner Scout Projects > mcq > server > Process Services et choisir « New Lookup Service… » dans le menu contextuel. Choisir « ChoicesLookupService » comme « Type Name » et sélectionner « AbstractSqlLookupService » comme « Super Type » dans la première étape et ne rien changer dans la deuxième.

Ce Lookup Service permet de lister les choix (clé/valeur) correspondants à une question (le numéro de question sera la valeur master du LookupCall). Comme nous avons choisi d'étendre AbstractSqlLookupService, il suffit d'indiquer le code SQL réalisant cette requête dans la propriété SqlSelect.

Naviguer jusqu'au service nouvellement créé (Scout Projects > mcq > server > Process Services > ChoicesLookupService) et double-cliquer sur celui-ci.

Ajouter le code :

@Override
public String getConfiguredSqlSelect() {
return "select choice_id, choice_text from choices where question_id = :master";
}

La requête SQL apparaît également dans la vue Scout Object Properties (la représentation n'est pas parfaite, au besoin on pourra ouvrir cette vue en grand pour obtenir une meilleure représentation).

Le LookupService existe côté serveur, il manque un objet dans shared (présent dans le client et le serveur) permettant de transférer les données entre le formulaire (côté client) et le LookupService (côté serveur). Cet objet se nomme LookupCall, il s'agit de le créer. Naviguer dans l'application : « Scout Projects > mcq > shared > LookupCalls » et sélectionner « new LookupCall… ». Choisir comme nom (« Type Name ») « ChoicesLookupCall » et sélectionner l'option « use existing lookup service » en indiquant l'interface du service nouvellement créé « IChoicesLookupService ». Il n'y a rien à changer dans la deuxième étape.

Il nous faut aussi indiquer que le champ ListBox du formulaire de réponse utilise ce Lookup Call. Sélectionner cette ListBox dans l'arborescence : « Scout Projects > mcq > client > Forms > AnswerForm > MainBox > ChoicesField ». Dans la vue des propriétés indiquer « ChoicesLookupCall » pour la propriété « Lookup Call ».

Dernière étape : compléter la fonction create() du process service pour persister les données saisies. Ouvrir à nouveau AnswerProcessService (avec le menu « Navigate > Open Type… (CTRL+Shift+T) » ou en navigant « Scout Projects > mcq > server > Process Services > AnswerProcessService »). Modifier la fonction create(..) de cette manière :

@Override
public AnswerFormData create(AnswerFormData formData) throws ProcessingException {
if (!ACCESS.check(new CreateAnswerPermission())) {
throw new VetoException(Texts.get("AuthorizationFailed"));
}

SQL.insert(" insert into answers (name, question_id) " +
" values (:YourName, :QuestionNr) ", formData);

SQL.selectInto(" values IDENTITY_VAL_LOCAL() " +
" into  :AnswerNr", formData);

if (formData.getChoices().isValueSet() && formData.getChoices().getValue() != null) {
for (Long choiceId : formData.getChoices().getValue()) {
SQL.insert(" insert into answers_choices (answer_id, choice_id) " +
" values (:AnswerNr, :ChoiceId) ", formData, new NVPair("ChoiceId", choiceId));
}
}
}

Il reste à relancer l'application pour constater que le formulaire est opérationnel.

II-H - Déployer sur un serveur Tomcat

Le déploiement sur un serveur Tomcat en compilant l'application depuis Eclipse est très simple. Sélectionner le serveur « Scout Projects > mcq > server » et sélectionner dans le menu contextuel « Export as war… ».

Dans l'assistant ainsi ouvert, choisir le fichier *.product qui doit être compilé (Product file : mcq.server/products/production/MCQ-server.product) et le ficher de destination (war file : MCQ.war dans n'importe quel dossier). Il est possible de compiler le client, qui sera inclus dans le serveur comme application à télécharger et à installer. Cocher : « Include Client application » et sélectionner le produit (Client product to include : mcq.ui.swt/products/production/MCQ-swt-client.product). Valider avec OK, la compilation commence.

Installer le war ainsi généré dans le dossier webapps du serveur Tomcat. Démarrer Tomcat, ouvrir l'URL correspondant au nom du war sur le serveur Tomcat (en local : http://localhose:8080/MCQ). La page d'accueil du serveur s'ouvre :

Dans la page se trouve un lien vers un zip à télécharger. Dans ce zip se trouve l'application que chaque utilisateur doit exécuter.

II-I - Aller plus loin

Pour améliorer l'application, il est possible d'ajouter ou de compléter des formulaires (ajout de questions, liste des réponses par question, édition/suppression des réponses et des questions, statistiques). Il faudra également ajouter certaines règles métier : par exemple, il est interdit de modifier une question qui comporte déjà des réponses. On pourra également identifier les utilisateurs et définir des rôles (utilisateur, rédacteur, administrateur…) Il manque enfin un certain nombre de finitions cosmétiques (icône, splash screen, fenêtre « À propos de ce logiciel », etc.).

III - En conclusion

Cet exemple illustre bien les avantages d'Eclipse Scout : facile à apprendre, la perspective Eclipse Scout permet d'écrire son code très rapidement. Les applications Eclipse Scout sont fonctionnelles immédiatement, permettant des cycles d'itération courts.

Il existe également certains inconvénients : comme avec tout framework, on se trouve limité par les fonctionnalités prévues par celui-ci (à moins d'étendre le framework, ce qui reste possible). Un autre inconvénient est la dépendance forte avec la partie runtime d'Eclipse Scout. Cela peut être pénalisant si la vision diverge avec celle du projet ou lors des grosses mises à jour. Dans sa version 2011, ce runtime propose le meilleur rendu en étant utilisé avec Swing sous Windows. Enfin, le projet en tant que produit open source, est encore jeune. La communauté d'utilisateurs se forme tout juste. La documentation n'a pas encore un niveau suffisant dans certains domaines. La gouvernance du projet est gérée par une seule entreprise.

Eclipse Scout peut néanmoins d'ores et déjà répondre à un certain nombre de besoins. La feuille de route est intéressante, aussi bien à court terme (Eclipse Juno 2012) qu'à plus long terme. Le soutien de la société créatrice est bon (puisqu'une grande partie de ses applications reposent sur cet outil). C'est un projet qu'il faut essayer.

IV - Remerciements

Je tiens à remercier l'équipe de developpez.com pour leurs précieux conseils, suggestions ou corrections, et tout particulièrement keulkeul, ClaudeLELOUP, FirePrawn et jacques_jean.

V - Annexes

V-A - Script SQL

Ce tutoriel nécessite l'installation d'une base de données Derby (comprenant déjà certaines données). Voici les scripts SQL correspondants. Pour la structure :

CREATE TABLE MCQ.QUESTIONS
(
QUESTION_ID INTEGER NOT NULL UNIQUE GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
QUESTION_TEXT varchar(512) NOT NULL
);

CREATE UNIQUE INDEX QUESTIONS_INDEX ON MCQ.QUESTIONS (QUESTION_ID);

CREATE TABLE MCQ.CHOICES
(
CHOICE_ID INTEGER NOT NULL UNIQUE GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
CHOICE_TEXT varchar(256) NOT NULL,
QUESTION_ID int NOT NULL
);

CREATE UNIQUE INDEX CHOICES_INDEX ON MCQ.CHOICES(CHOICE_ID);

CREATE TABLE MCQ.ANSWERS
(
ANSWER_ID INTEGER NOT NULL UNIQUE GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
NAME varchar(128),
QUESTION_ID int NOT NULL
);

CREATE UNIQUE INDEX ANSWERS_INDEX ON MCQ.ANSWERS(ANSWER_ID);

CREATE TABLE MCQ.ANSWERS_CHOICES
(
ANSWER_ID int NOT NULL,
CHOICE_ID int NOT NULL
);

CREATE UNIQUE INDEX ANSWERS_CHOICES_INDEX ON MCQ.ANSWERS_CHOICES (ANSWER_ID, CHOICE_ID);

ALTER TABLE MCQ.CHOICES
ADD FOREIGN KEY (QUESTION_ID)
REFERENCES MCQ.QUESTIONS(QUESTION_ID);

ALTER TABLE MCQ.ANSWERS
ADD FOREIGN KEY (QUESTION_ID)
REFERENCES MCQ.QUESTIONS(QUESTION_ID);

ALTER TABLE MCQ.ANSWERS_CHOICES
ADD FOREIGN KEY (ANSWER_ID)
REFERENCES MCQ.ANSWERS(ANSWER_ID);

ALTER TABLE MCQ.ANSWERS_CHOICES
ADD FOREIGN KEY (CHOICE_ID)
REFERENCES MCQ.CHOICES(CHOICE_ID);

Pour les données :

INSERT INTO MCQ.QUESTIONS (QUESTION_TEXT)
VALUES
('Quel est votre IDE préféré ?');

INSERT INTO MCQ.CHOICES
(QUESTION_ID, CHOICE_TEXT)
VALUES
(IDENTITY_VAL_LOCAL(), 'Eclipse'),
(IDENTITY_VAL_LOCAL(), 'NetBeans'),
(IDENTITY_VAL_LOCAL(), 'IntelliJ'),
(IDENTITY_VAL_LOCAL(), 'RAD / WSAD'),
(IDENTITY_VAL_LOCAL(), 'JDeveloper'),
(IDENTITY_VAL_LOCAL(), 'JCreator'),
(IDENTITY_VAL_LOCAL(), 'JBuilder'),
(IDENTITY_VAL_LOCAL(), 'BEA Workshop Studio'),
(IDENTITY_VAL_LOCAL(), 'Editeurs de texte avancés (Emacs, VI, JEdit, UltraEdit...)');

INSERT INTO MCQ.QUESTIONS (QUESTION_TEXT)
VALUES
('Quel est le meilleur smartphone sous Android ?');

INSERT INTO MCQ.CHOICES
(QUESTION_ID, CHOICE_TEXT)
VALUES
(IDENTITY_VAL_LOCAL(), 'Google Nexus S'),
(IDENTITY_VAL_LOCAL(), 'HTC Desire S'),
(IDENTITY_VAL_LOCAL(), 'HTC Desire Z'),
(IDENTITY_VAL_LOCAL(), 'HTC Incredible S'),
(IDENTITY_VAL_LOCAL(), 'HTC Sensation'),
(IDENTITY_VAL_LOCAL(), 'LG Optimus One'),
(IDENTITY_VAL_LOCAL(), 'LG Optimus 2X LGP990'),
(IDENTITY_VAL_LOCAL(), 'LG Optimus Black P970'),
(IDENTITY_VAL_LOCAL(), 'Motorola Atrix'),
(IDENTITY_VAL_LOCAL(), 'Motorola Defy'),
(IDENTITY_VAL_LOCAL(), 'Samsung Galaxy Ace GT-S5830'),
(IDENTITY_VAL_LOCAL(), 'Samsung Galaxy S'),
(IDENTITY_VAL_LOCAL(), 'Samsung Galaxy S II'),
(IDENTITY_VAL_LOCAL(), 'Sony Ericsson Xperia Arc');

V-B - Sources de l'application

L'application réalisée dans ce tutoriel est hébergée sur eclipselabs.org : projet MCQS. Les différentes étapes de ce tutoriel sont proposées dans la branche tutorial du dépot git. Le projet a évolué depuis. Certains points évoqués dans le paragraphe (II-I) Aller plus loin ont été implémentés.

V-C - Disclaimer

L'auteur, Jérémie Bresson, travaille pour BSI Business System Integration AG, la société créatrice du framework Eclipse Scout. Cet article et les opinions défendues sont personnels et n'engagent pas cette entreprise.