Skip to topic | Skip to bottom
Home
Minfo03
Minfo03.DocFinalr1.46 - 15 Jun 2004 - 07:37 - MandrioliDamientopic end

Start of topic | Skip to actions

Plan

Introduction

Le sujet de ce TER consiste à ajouter à l'outil web coopératif TWiki un éditeur WYSIWYG online/offline et un outil de refactoring permettant le renommage, le déplacement et la suppression d'un ensemble de pages www de manière plus efficace que la méthode standard.

Ce TER est co-encadré par Michel Buffa et par M. Colas Nahaboo de la société ILOG. L'outil TWiki est au coeur de l'intranet du département informatique de l'UNSA et de la société ILOG, il est par ailleurs très utilisé dans le monde.

TWiki est un "outil web collaboratif" permettant à plusieurs personnes de créer/modifier des pages web, partager des documents attachés aux pages, etc... Un article résumant ses fonctionalités et l'usage qui en est fait au département informatique est disponible dans le numéro 10 de la revue ISDM (http://www.isdm.org).

Le principal reproche que l'on fait à twiki est la pauvreté de l'éditeur de pages www standard : une simple text area HTML dans un navigateur. L'avantage évident est que si un utilisateur voit une page www, il peut la modifier simplement en pressant le bouton "edit" et modifier son contenu au sein même de son navigateur www. Cependant, l'édition se fait en mode texte, et une syntaxe certes simple mais rebutante pour les non initiés est utilisée. Un projet réalisé au premier semestre par des étudiants de l'IUP Miage a débouché sur la possibilité d'utiliser un éditeur WYSIWYG écrit en javascript en lieu et place de l'éditeur standard. Un traducteur utilisant XML comme syntaxe intermédiaire a été développé, permettant la traduction de la syntaxe TWikiML vers HTML et vice-versa. L'idée consistant à ce que le contenu des pages twiki, qu'il soit édité par l'éditeur standard ou par un éditeur HTML quelconque, ne change pas radicalement. Il est en effet fondamental que l'on puisse re-éditer une page à l'aide de l'éditeur standard, après qu'elle ait été modifiée par un éditeur HTML, sans qu'elle soit "polluée" par des tags HTML en surnombre.

La solution développée par les élèves de la Miage fonctionne mais l'éditeur javascript a plusieurs défauts :

  • Il ne permet pas une édition offline,
  • Il s'agit d'un éditeur HTML et sa gui propose de nombreuses options qui n'existent pas en syntaxe TWiki. Par conséquent, le traducteur HTML vers TWikiML? se trouve dans l'obligation soit d'insérer du HTML dans la page TWikiML? finale, soit d'ignorer ces spécificités. En outre le code est complexe et difficile d'accès, donc très difficile à personnaliser en y apportant des options propres à TWiki, comme la complétion automatique des noms des liens locaux, etc...

Dans le cadre de ce projet nous avons réalisé un éditeur WYSIWYG écrit en java, se lançant automatiquement en cliquant sur un nouveau lien "edit with WYSIWYG editor". L'éditeur s'installe sur le disque dur de l'utilisateur via la technologie java Webstart (qui assure que tout le monde a bien une version à jour) et communique avec le serveur TWiki via des web services que nous avons également développés. Cet éditeur propose trois vues distinctes et synchronisées : la vue WYSIWYG, la vue TWikiML? et la vue HTML. La gui de l'éditeur de permet que de faire en WYSIWYG que ce que la syntaxe TWikiML? peut supporter : gras, italique, tableaux, liens, etc...

Par ailleurs un outil de "refactoring" permettant d'organiser la structure globale du contenu du serveur TWiki a été développé, via les mêmes technologies : java web start et web services. Il permet beaucoup plus facilement que via l'interface web de déplacer/renommer/supprimer des pages ou des ensembles de pages.

Dans une première partie nous présentons l'architecture de TWIKI, ainsi que la manière dont nous avons implanté une couche de services web permettant de l'exploiter à distance.

Dans une seconde partie nous présentons l'éditeur WYSIWYG, et dans une troisème partie l'outil de refactoring est détaillé. Enfin, dans une dernière partie nous faisons le bilan de ce projet : adéquation avec le chahier des charges, état du logiciel livré, etc...

Finalement, dans la conclusion, nous tirons un bilan personnel de cette expérience.

Vous trouverez en annexe des détails sur les technologies utilisées ainsi que les ressources web que nous avons répertoriées...

Première partie : Twiki et les web services

Architecture de twiki

TWiki est avant tout un site web écrit en Perl. Il repose essentiellement sur des scripts CGI et des modules. Ces derniers constituent des bibliothèques de fonctions Perl réutilisables par les scripts mais aussi par d’éventuels plugins qui peuvent se greffer à TWiki. Ces modules en constituent le cœur. Les fonctions qui y sont implémentées gèrent la manipulation de topics et d’attachements, la gestion des autorisations, la gestion de RCS pour empiler les versions des topics et attachements ainsi que beaucoup d’autres toutes aussi nécessaires.

Les scripts CGI contiennent aussi du code Perl mais celui-ci n’est pas réutilisable. C’est le code exécuté directement lors de l’utilisation de TWiki. Par exemple, visualiser un topic consiste à faire appel au script « view » et l’éditer à faire appel au script « edit ».

Contrairement à un site web traditionnel où les scripts sont en quelque sorte les pages, ici ils travaillent (en général) sur les pages : les topics. Ces derniers constituent un autre fondement de TWiki. Ce sont les pages que l’on peut voir lorsqu’on utilise TWiki. Ils sont classés dans des dossiers appelés webs. Au niveau implémentation, les webs sont représentés par des dossiers et les topics par des fichiers textes. La mise en forme est plus ou moins exclue de l’information contenue dans les topics, ils ont pour objectif de contenir uniquement l’information. Leur présentation est faite par des « templates » (pour être global, des fichiers HTML avec des macros). Voici un schéma illustrant un cas concret, la visualisation de topics:

Schéma illustrant la visualisation de topics:
twiki.jpg

Lors de la visualisation, on fait appel au script « view » avec en paramètre dans l’url la location du topic. Une fois lancé, « view » va aller récupérer le contenu texte du topic. Ici, le fichier va être cherché dans le dossier data/Main (le web). Une fois le contenu textuel récupéré, le script va le mettre en forme avec l’aide d’un template, qui peut être général ou spécifique à un web. La transformation réalisée sera affichée dans le navigateur. En fonction de leur rôle, les scripts fonctionnent plus ou moins selon ce système. Vous pouvez voir dans ce schéma des fichiers .txt,v accompagnant les topics : il s’agit des piles de versions RCS. En ce qui concerne les attachements, ils sont sauvegardés dans un autre répertoire « pub » dans une hiérarchie de type pub/web/topic/attachement_name. Etant donné qu'il ne peut y avoir deux topics de même nom dans un web, il n'y a pas de conflit.

Pour en revenir aux scripts, nous avons illustré avec le schéma précédent comment fonctionnait « view » uniquement. Il y en a évidemment d'autres parmi lesquels « edit » pour éditer des topics et qui fonctionne suivant le même modèle, « rename » pour le refactoring en général, « save » pour la sauvegarde de topics, « upload » pour l'upload d'attachements et « password » pour l'authentification.

Les web services

Définition

Un service Web est une technologie permettant à des applications de dialoguer à distance via Internet (par le protocole HTTP), et ceci indépendamment des plates-formes et des langages sur lesquelles elles reposent. Pour ce faire, les services Web s'appuient sur un ensemble de protocoles standardisant les modes d'invocation mutuels de composants applicatifs. On parle alors de WSDL, de message SOAP et d'annuaire UDDI :
  • La WSDL ou Web Service Description Language fournit un modèle et un format XML pour décrire les Web Services. Elle permet de décrire précisément les fonctionnalités offertes par le service, en nous indiquant, par exemple, comment et où les appeler.
  • SOAP ou Simple Object Acces Protocol permet de définir les messages que l'on va pouvoir envoyer et recevoir du Service Web. Cette spécification encapsule des messages XML. C'est pour cette raison que les applications peuvent être écrite dans des langages différents.
  • L'UDDI représente un annuaire électronique référençant les services Web. C'est par cet annuaire qu'on arrive connaître l'Id (ou adresse) des Services Web disponible qui va nous permettre de les appeler dans nos applications.

Fonctionnement

Principe général

  • Un client recherche un service dans l'annuaire UDDI
  • Il appelle le Service Web à partir de son application
  • le serveur traite la demande et renvoie le résultat au client
  • le client utilise le résultat

Le schéma ci-dessous illustre ce fonctionnement :
WSImg.GIF

En ce qui concerne nos applications:

  • Le client n'a pas besoin de rechercher les services dont il a besoin dans l'annuaire, puisqu'ils ont été développés pour lui.
  • Le client récupere un stub, généré automatiquement avec WSDL2Java à partir de la WSDL.
  • Le client peut appeller les services comme une fonction locale à partit du stub.

Interfacage avec TWiki

TWiki est écrit en Perl, il était donc intéressant de développer nos services dans ce langage afin que nos applications s'intègrent mieux avec le serveur. Même si l'apprentissage de ce langage n'est pas intuitif, il nous a permis d'utiliser directement certaines fonctions de TWiki ce qui se traduit par un gain de temps de développement. L'interfaçage avec TWiki s'est fait par le biais de la toolkit SOAP::Lite et de l'application que nous avons développé qui est décrite ci-après ...

Application réalisée

Principe

Les services développés ne sont pas des fonctions réparties au sein du code source de TWiki mais font l’objet d’une application à part entière. Elle est constituée d’un ensemble de modules (principalement) et de scripts dont les fonctions utilisent elles-mêmes ce qui est réutilisable dans les modules de TWiki. Mais ce n’est pas tout.

Cette partie du TER n’a pas consisté uniquement à faire appel à des fonctions TWiki mais à bâtir bel et bien une application afin que l’interfaçage entre TWiki et nos applications clientes soit réussi, en prenant en compte certains aspects non fonctionnels. Un système de connexions avec authentification, un mécanisme de gestion de verrous bâti au-dessus de celui de TWiki et un « verrou administratif » pour gérer la concurrence entre applications de refactoring ont été ainsi réalisés afin d’avoir des clients qui interfacent correctement avec TWiki. La "documentation pour développeurs" située en annexe 4 donne des détails concernant les choix d'implémentations et ce qui a été fait dans ce sens.

Du point de vue du serveur, l’application s’initialise lors de l’interception d’une requête et se termine une fois le traitement effectué; les requêtes pouvant être une demande d’opération de refactoring, de récupération de topic, de sauvegarde etc. Voici un schéma illustrant ce qu’il se passe entre ces deux instants clefs:

Schéma illustrant le cycle de vie de notre application:
application.jpg

Dans ce schéma, ce qui est décrit comme "process" (étape 5) concerne le corps de ce que sont les services web. C’est durant cette étape que les appels aux fonctions TWiki sont faits, en plus d’autres traitements que nous avons faits nous-mêmes. Le serveur SOAP a pour objectif d’écouter sur un port donné afin d’intercepter des messages SOAP. Une fois le message intercepté, il le désérialise et transmet la requête à un module Service. Ce module se charge d’initialiser la configuration du service en paramétrant des variables globales, de la même manière que TWiki. Une fois la configuration effectuée, le module répartit les requêtes dans des sous modules et renvoie le résultat (au serveur SOAP). Il agit en quelque sorte comme un skeleton de serveur. Le serveur lui-même retourne un message SOAP contenant la(les) valeur(s) de retour au client.

Services fonctionnels proposés

Dans cette partie sont présentés succinctement les services principaux proposés par notre application et qui ont été developpés selon les besoins des clients. Ils sont le résultat d'études et de réflexion de la part de toute l'équipe du TER. Le manuel en annexe 4 décrit tous les services proposés de manière plus détaillée.

Pour le refactoring

A ce niveau, il y a deux types de services: les services d'accès aux données pour connaître les propriétés d'un topic, d'un web et les services de traitement.
  • Envoi de données
Ces derniers permettent d'envoyer au client une représentation concrète de l'arbre correspondant à leurs requêtes.
  • Opérations
Les opérations de refactoring réalisées avec l’outil doivent être validées sur le serveur TWiki. Cette « validation » fait l’objet de cinq services web qui correspondent aux opérations de refactoring proposées par l’outil:

    • renommage de topics
    • déplacement de topics
      • déplacement inter-webs
      • changement de topic parent
    • suppression de topics
    • fusion de topics
    • copie de topics

Ces services proposent plusieurs options, notamment pour certains la gestion des attachements et la mise à jour des liens. Ils constituent le coeur de ce qui a été fait dans le refactoring; l’outil Java en est l'interface graphique.

Pour l'édition WYSIWYG

Au niveau WYSIWYG, deux services majeurs "symétriques" ont été développés. L'un permet d'envoyer le contenu d'un topic à l'éditeur WYSIWYG, l'autre de sauvegarder le résultat de l'édition sur TWiki.
  • Envoi de données
Les services permettent de fournir à l'éditeur WYSIWYG les données telles quelles sont décrites sur le serveur. De plus, certains services permettent de gérer les attachements.
  • Sauvegarde
Un service a été développé afin de permettre à l'éditeur WYSIWYG de sauvegarder un topic sur TWiki. L'upload d'attachements est aussi géré.

Déroulement

Méthodologie

La première étape d'un développement d'un service Web est de demander au client les services dont il a besoin, les fonctions qui lui permettront d'accéder aux données. Cette première phase, est donc une phase de dialogue, de réflexion entre les membres de l'équipe afin de bien cerner les besoins, mais aussi les contraintes de chacun.
La phase de développement commence par une période d'analyse de TWiki. Il s'agit en fait de mieux comprendre son fonctionnement afin d'interagir avec lui. Cette analyse est portée sur les packages que nous avons pu utiliser afin de s'intégrer parfaitement au serveur, mais cela nous permettait aussi un gain de temps considérable au niveau du développement.
Pour finir, afin d'exporter nos fonctions, nous devons décrire les services dans la WSDL. A partir de ce fichier, nous allons générer des stubs afin que les applications clientes puissent utiliser nos fonctions.
Lors du développement, nous testions nos programmes sur notre TWiki, installé en local sur nos machines. Une fois l'application stable, nous l'étendions sur le TWiki de test de la miage de Nice afin que ceux qui développent les applications clientes puissent interagir avec les services Web. Cela nous permettait également de tester nos services avec les contraintes d'un véritable serveur. Dans cette partie, sont détaillées les taches les plus importantes qui ont participé à la réalisation de cette application.

Prototype service

  • Effectifs
1 personne, 1 semaine et demi de travail, estimation : 3h/jour en moyenne.
  • Choix

    • Développer un prototype du service avant le début du TER
Etant donné l’ambition du projet, les risques auxquels nous devions faire face et le peu de connaissances que nous avions concernant les technologies à utiliser, un prototype du service a été développé avant le début du TER.
    • Ecrire une description WSDL dès le départ
La description WSDL fut envisagée dès le départ pour jouer le rôle de contrat avec les clients des services sur les structures de données et les signatures des méthodes. Ce ne fut qu’utopique étant donné qu’elle a évolué en permanence durant ce projet. Par contre, elle nous a servi à générer les stubs automatiquement pour l’éditeur et l’outil de refactoring Java, chose que nous n’envisagions pas lors de la rédaction du cahier des charges.
    • Etablir un système de connexion à l’application
Cette décision fut prise peu après la rédaction du cahier des charges. Ce système a pour ambition d’améliorer l’interfaçage entre nos outils (et peut-être d’autres à l’avenir) et TWiki sur des aspects non fonctionnels tels que la concurrence et la gestion des verrous.
    • Faire nous-mêmes l’authentification
Nous pouvions nous baser sur l’authentification d’Apache ou la faire nous-même. Ayant voulu faire un service « général » et pas spécifiquement dédié aux applications lancées par Web Start par exemple, nous avons opté pour la deuxième solution.
    • Bâtir un système de gestion de verrous au-dessus de celui de TWiki
Cela a été fait peu après la réalisation du prototype. Ne trouvant pas la gestion des verrous suffisamment précise pour nos services Web, il fut développé un système au-dessus n’altérant en rien le bon fonctionnement de TWiki. Le manuel en annexe 4 donne plus de précisions à ce sujet. Ceci n’était pas prévu initialement.
    • Proposer une trace d’exécution
Le développement d’une application serveur s’étant soldé par un récent échec (pour l’un d’entre nous), un module pour faire des traces d’exécution a de suite été développé.

Envoi de la représentation arborescente des topics à l'outil de refactoring

  • Effectifs
1 personne, 2 semaines, environ 8h/jour. Il s’agissait au départ de fournit un premier service pour tester la communication puis de le modifier selon les besoins des applications clientes.
  • Difficultés
    • Performance
Comme son nom l’indique, un Service Web utilise le Web (protocole HTTP) pour transmettre ses messages (appels de fonctions, réception de résultat). L’inconvénient majeur dans notre cas est le problème de performance, même sur des connexions hauts débits. A l’origine, il fallait faire un appel au service pour chaque topic ce qui rendait l’application pratiquement inutilisable. Pour palier à cela, nous avons essayé de faire une représentation arborescente des topics au niveau serveur et de la transmettre au client. Ce dernier fait donc moins d’appels au serveur, réalise moins de traitement et son rôle est donc de fournir une représentation graphique des données, ce qui améliore les performances.

Opérations de refactoring

  • Effectifs
1 personne, 2 semaines, environ 8h/jour. Cela comprend les analyses et la mise en place de systèmes qui leur sont liés tels le "verrou administratif".
  • Difficultés

    • Analyser les scripts et modules de TWiki
N’ayant pas trouvé de tutoriel expliquant TWiki dans les moindres détails, il fut nécessaire de se baser sur son code source pour comprendre. Des traces d’exécution furent ainsi utilisées, ainsi que des modifications pour voir son comportement. Ce n’était pas réellement une difficulté, TWiki était suffisamment clair dans son code. Au final, la réalisation des opérations de refactoring s’est très bien passée, beaucoup plus que ce à quoi nous nous attendions lors de la rédaction du planning initial. Les analyses faites y sont aussi pour beaucoup.
    • Copie d’attachements pour la fusion et la copie
Toutes les opérations concernant les attachements se basent sur le déplacement. Pour faire la copie, il a fallu reprendre ce qu’il y avait de plus « bas » dans TWiki, les opérations au niveau fichier et répertoire. Il ne fut pas nécessaire de descendre aussi bas pour les autres opérations, TWiki proposant des opérations de haut niveau parfaitement adaptées.

Rapatriement de topics vers l'éditeur

  • Effectifs
1 personne, 2 semaines, environ 8h/jour. Les fonctions de ces services sont de rechercher les informations nécessaire et de les formater afin qu’elles soient directement intégrable dans l’application.
  • Difficultés
    • Passage d’accent
Pour faire transiter nos messages à travers le protocole HHTP, les services web utilisent le XML. Pour générer nos messages, nous utilisions le package SOAP ::Lite. Or ce denier utilise l’encodage UTF8 , ce qui ne permet pas le passage de caractère accentué. Pour palier à ce problème, il est possible dépasser le codage en iso-8859-1 mais il faudrait ajouter et modifier un certain nombre de package et le temps qu’il nous restait ne nous le permettait pas. Cependant, pour permettre la transmission de données « accentuées » nous avons développé des fonctions pour remplacé tout caractères spéciaux par leur représentation unicode. (é -> & eacute; )

Sauvegarde de topics

  • Effectifs
1 personne, 3 jours, environ 8h/jour.
  • Choix

    • Etablir un protocole de communication autour des attachements
Un protocole de communication autour des attachements a été établi afin que l’éditeur WYSIWYG puisse les gérer simplement avec les services relatifs aux topics. Ce protocole est détaillé en annexe 4 dans la section consacrée à la sauvegarde de topics.
  • Difficultés

    • Upload d’attachements et données binaires
L’upload d’attachements sur TWiki repose en partie sur Apache. En ce qui concerne le service de sauvegarde de topics, il attend les données binaires des attachements dans le message. La difficulté résidait d'une part à comprendre comment les attachements étaient gérés par TWiki après l'upload et d'autre part à convertir des données binaires sauvegardées dans un texte en données pour un fichier binaire. Pour ce dernier, le problème a été vite résolu en cherchant dans les forums de discussions (qui ont constituées une grande partie des sources de recherche de ce TER).
  • Evolutions
La sauvegarde doit sans doute être adaptée afin de pouvoir sauvegarder de nouveaux topics. Un ou deux jours supplémentaires auraient été suffisants.

Notifications

  • Effectifs
1 personne, 3 jours, environ 8h/jour.
  • Choix
Ce système est un choix en lui-même et n'était pas prévu lors de la rédaction du cahier des charges. Les notifications sont gérées uniquement au sein du service, pas dans TWiki en général car cela aurait nécessité de modifier son code (donc de faire un patch). Dans ce sens, ce système n’est pas terminé mais s’avère être un projet ouvert à d’autres développeurs.
  • Evolutions
Il faudrait généraliser les notifications à TWiki (et donc faire un patch) et intégrer les fonctionnalités à l'outil de refactoring. Deux semaines semblent nécessaires.

Deuxième partie : l'éditeur WYSIWYG standalone

La solution Java Web Start

Java Web Start est une technologie qui permet de lancer une application Java (pas une applet) simplement en cliquant sur un lien dans une page HTML. Le mécanisme de téléchargement et d'installation est entièrement automatisé, cela permet de véritablement installer et exécuter une application en un seul clic. Contrairement aux applets, le téléchargement n'est pas systématique : si l'utilisateur à déjà lancé l'application et si l'application n'a pas changé sur le serveur, les classes java en cache localement sont utilisées. Pour déployer une application avec cette technologie, il faut créer une archive jar signée et exécutable contenant l'application ainsi qu'un descripteur de déploiement qui porte pour extension JNLP (Java Network Launching Protocol). Ci dessous un exemple de descripteur JNLP:
<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="http://miageprojet.unice.fr/twikitestnice/"> (Définition du codebase de l'application : l'emplacement ou télécharger le jar)
  <information>
    <title>TWiki WYSIWYG Editor</title>
    <vendor>* * * *</vendor>
    <homepage href="http://miageprojet.unice.fr/twikitestnice/view/%WEB%/%TOPIC%"/> 
  </information>
<security>
    <all-permissions/> (Demande tous les droits sur la machine cliente, l'application doit être signée)
  </security>
<resources>
    <j2se version="1.3+" />
    <jar href="twe.jar" /> (la référence au fichier de l'application)
  </resources>
<offline-allowed/>
  <application-desc main-class="twe.gui.MainFrame"> (Classe principale de l'application)
  <argument>%ENDPOINT%</argument> (Arguments passé à l'application)
  <argument>%WEB%.%TOPIC%</argument>
  </application-desc>
</jnlp>

Choix de conception

L'éditeur proposé est avant tout un éditeur de contenu. Il a pour but d'aider l'utilisateur à composer ses documents TWiki à l'aide de la souris et d'un rendu visuel mais ce rendu ne correspond pas à ce qui sera affiché sur le site une fois l'édition terminée. Ainsi, seules les commandes nécessaires à l'édition d'un document TWiki sont disponible. On ne peux pas par exemple centré un paragraphe ce qui est possible en HTML mais pas en syntaxe TWiki.

L'éditeur permet de composer des documents offline. Ceci peut s'avérer pratique pour un utilisateur qui n'aurait pas toujours accès à Internet.

Concernant la stratégie de développement avec l'API Java, nous avons choisis d'utiliser les composants Swing tel quel, sans créer de classes héritant de ces derniers. Ce choix est dans certains cas une limite mais il s'est imposé du fait du manque de temps et de main d'oeuvre (une seule personne).

Le traducteur utilisé n'a pas été modifié, certaines imperfections de l'éditeur proviennent de certaines lacunes du traducteur.

Deux composants Swing sous licence GNU ont été utilisés :

  • La fenêtre de dialogue pour l'authentification
  • La fenêtre de dialogue pour la recherche - suppression

Communication avec « TWiki »

Ci dessous, un diagramme de séquence représentant une session d'édition du début à la fin :

NB : Les appels à getTopic() et getAll() sont réalisés en parallèle.

Fonctionnalités de l'éditeur

  • screenshot vue wysiwyg:
    twe1.gif

  • screenshot vue html:
    twe2.gif

  • screenshot vue syntaxe twiki:
    twe3.gif

On trouvera en Annexe 2 : Manuel utilisateur de l'éditeur wysiwyg la liste des fonctionnalités de l'éditeur ainsi qu'un exemple d'utilisation.

Troisième partie : l'outil de refactoring

Le refactoring c'est quoi ?

Le refactoring est une methode qui consiste à modifier la structure d'une arborescence de fichers, en appliquant diverses actions comme le renommage, le déplacement et la supression de fichiers par exemple. De nombreux environnements de programmation professionnels, comme JBuilder, Eclipse ou Dreamweaver, possède un outil de refactoring. Nous avons donc développé un outil, s'inspirant de celui de JBuilder, mais adapté à TWiki. Il permet le renommage, la suppression, la copie, le déplacement et la fusion d'un ou de plusieurs topics de l'arborescence de TWiki et effectue les modifications adéquates dans les fichiers concernés, grâce aux Web services.

Fonctionnement de l'outil

L'outil de refactoring est exécuté à partir d'une page web en cliquant sur le lien "Refactoring tool", grâce à la technologie Java Web Start décrite précedemment. Une boîte de dialogue d'authentification s'affiche puis, une fois que l'utilisateur a saisi ses paramètre de connexion, la fenêtre principale apparaît. On peut voir sur celle-ci deux arborescences et des boutons d'action (renommage, ...). Pour ne pas surcharger les performances, l'arborescence n'est pas chargée entièrement. En effet les webs sont chargés dans un premier temps, puis au fur et à mesure que l'on déploie les noeuds des arbres, les niveaux suivant de l'arborescence sont téléchargés (les noms de topic et de web) puis stockés en mémoire afin d'éviter de refaire des appels au serveur. De la même façon, lorsque l'on clique sur un élément de l'arbre de gauche, les propriétés correspondantes sont également téléchargées puis stockées en mémoire sous forme d'objet (Topic ou Web), de telle sorte qu'un si on reclique sur l'élément les propriétés sont affichées instantanément sans refaire appel au serveur.

Le schéma suivant montre plus en détail, à travers un diagramme de séquence simplifié, les communications entre l'application et les web services lorsque l'utilisateur déplace un topic

La description détaillée des fonctionnalités et de l'utilisation de l'application se situe en Annexe 3 dans le guide de l'utilisateur.

Difficultés rencontrées

Les principales difficultés que nous avons rencontrées pendant le développement de l’outil de refactoring, sont liées aux performances.

Pour éviter les problèmes de performances dus au chargement de l’arborescence, nous avons décidé de ne charger l’arborescence qu’au fur et à mesure que les nœuds des arbres étaient déployés. Malheureusement nous étions trop optimiste puisque lors de l’intégration des appels de fonctions au serveur dans l’application, nous nous sommes aperçu que les performances étaient très mauvaises et que l’application était inutilisable. En effet, lors du déploiement d’un nœud de l’arbre, nous avons besoin de savoir si un topic est parent ou non pour pouvoir afficher un nœud ou une feuille. Il faut donc explorer un niveau de plus de l’arborescence, c’est-à-dire appeler une fonction du serveur pour chaque topic du nœud afin de savoir s’il a un fils. Sachant qu’un appel de fonction prend une à deux secondes et qu’un topic peut avoir plusieurs centaines de fils, cette méthode n’était pas adaptée. La première solution que nous avons envisagée, était de réduire le nombre d’appel au serveur. Pour cela la fonction qui renvoie la liste des topics fils pour un topic donné a été modifiée : si un topic possède un ou plusieurs fils, son nom est suffixé par le caractère ‘#’. Cette solution permet de ne faire qu’un appel de fonction pour déployer un nœud de l’arborescence. Cette fois-ci, c’est coté serveur que les performances ont chuté. Le problème fut résolu en optimisant les fonctions coté serveur en s’appuyant sur la fonction « grep » pour les accès aux fichiers.

A la suite du temps perdu pour trouver ses solutions, nous avons pris du retard par rapport à nos objectifs. Nous avons donc choisi d’abandonner certaines fonctionnalités qui ne nous semblaient pas prioritaire comme la mise en évidence des cycles, des derniers topics créés et de la taille des topics.

Quatrième partie : bilan du projet

Communication :

Pourquoi communiquer

Tout au long de notre projet, nous avons pris soin de nous tenir au courant au sein de l’équipe du TER (étudiants et encadrants) afin que chacun puisse se faire une opinion de l'état d'avancement du projet. Maintenant que celui-ci est fini, on peut se demander si cela n’a pas été une perte de temps. On peut également se demander quelle a été l'importance de cette communication dans l'aboutissement du projet. Nous verrons dans la description de la méthode de travail que pratiquement tout le monde a travaillé en parallèle. Il est donc indispensable de savoir ce que fait son équipe afin de juger si notre travail va bien correspondre à ce qui est attendu et poursuivre notre développement dans la même direction. Pour illustrer cela, imaginez que vous deviez faire une voie ferrée avec un train, une personne s’occupe des rails et l’autre du train. Chacun fait son travail indépendamment, mais il faut faire attention que à ce que la largeur des rails corresponde a celle des roues et inversement, sinon le train ne pourra pas rouler alors que chacun à fait parfaitement ce qui lui était demandé. Il est donc évident que la communication a contribué à l’aboutissement de notre projet.

Méthodes utilisées

Communiquer est une chose, mais la façon de le faire en est une autre. En effet, il ne s’agit pas de déranger tout le monde dès que l'on rencontre un problème ou dès que l’on désire faire une requête sur tel ou tel point. Il est fort probable qu’à ce moment là, les membres de l’équipe soient en plein travail et ne soit pas complètement à votre disposition.

Pour palier à cela, nous avons donc utilisé le système de trace, qui consistait à décrire précisément ce que l’ont voulait faire communiquer. En fonction de l’organisation respective de chacun, on pouvait prendre connaissance des messages des autres, d’y répondre voire même d’organiser des réunions par chat afin de rassembler tout le monde.

De plus, à chaque étape de développement, nous contactions nos encadrants afin de leur montrer notre travail. Ils nous donnaient alors leur avis afin que nous poursuivions dans la bonne direction.

Outils et moyens mis à dispositions

Pour communiquer, nous avons utilisé plusieurs logiciels qui se sont avérés très utiles. Tout d’abord, nous avons utilisé l’outil TWiki pour tout le suivi écrit (travail effectué, suivi de bug,...). Pour communiquer directement, nous utilisions MSN Messenger, et Skype pour les chats vocaux. Nos travaux étaient publiés sur un serveur CVS. Enfin, lorsque c'était nécessaire, nous nous déplacions à Sophia-Antipolis (ILOG) afin de faire une démonstration de notre projet.

Méthodologie :

Organisation du travail

Notre projet comprend deux applications Java indépendantes et une application serveur bâtie autour des services Web pour leur permettre de communiquer avec TWiki. Nous avons décidé de faire développer cette dernière par deux personnes, et chaque applications Java par une seule. Cela peut surprendre car les applications semblent demander beaucoup plus en terme de développement. La raison est simple, d’une part, le développement des services nécessite l’apprentissage de technologies, d'environnement et d'outils auxquels nous ne sommes pas familiers (Perl, spécification WSDL, TWiki etc.). D’autre part, il fallait fournir ces services le plus rapidement possible afin de tester la communication des applications avec le serveur. Enfin, ces services se devaient d’être le plus optimal possible et il était indispensable qu’ils soient opérationnels afin que notre projet aboutisse (à quoi sert de faire un train si on n'a pas les rails ?).

Mise en place du développement

Au début du projet, des conflits engendrèrent quelques tensions du côté de l'équipe des services web. Mais très vite, un consensus su être trouvé pour ne pas mettre en péril la suite du développement. Le reste du temps, le développement se passa très bien, grâce notamment au suivi personnel et aux nombreux échanges d’opinions.

D’autre part, nous pouvons constater que le planning été relativement bien respecté pour les applications clientes, mais il est vrai qu’au niveau Web Service il y a eu un décalage, notamment du à l’apprentissage des technologies. Cependant, ce retard a été rapidement rattrapé une fois les notions acquises.

Aboutissement

Le fait de développer dans ces conditions nous a permis de ne pas bloquer et d’avancer à un rythme régulier. Le résultat s’en fait ressentir, on est arrivé au bout de nos objectifs en respectant le temps qu’il nous était donné. De plus, on peut dire que ce projet est le fruit d’un travail d’équipe dans lequel, la contribution de chacun était indispensable.

Evolution

Etat actuel

Le projet livré marche, et a été montré à nos encadrants. Le résultat les satisfait pleinement. On peut donc dire qu’au niveau développement, c’est une réussite. Il est vrai qu’il reste certaines améliorations à faire, mais nous préférons passer du temps sur l’analyse des différentes méthodes à mettre en œuvre, plutôt que de se plonger dans du code, sans être sûr d’aboutir.

Améliorations

  • Gestions des accents au niveau Web Service
Changer l'encodage par defaut de SOAP::Lite de UTF8 en iso-8859-1
  • Gestion des attachements du côté de l'éditeur et des services
Passage des données binaires entre le Web Serice et l'editeur
  • Généralisation des notifications à TWiki et intégration à l'outil de refactoring
  • Amélioration de la robustesse de l'éditeur
Gérer l'état des boutons d'actions en fonction de la position du curseur
  • Lancement de l'éditeur à partir de l'outil de refactoring
  • Ajout d'une barre de status permettant de visualiser les communications avec les Web Services
  • Amélioration de la fiabilité de l'outil de refactoring

Poursuites

L’analyse faite à la fin va permettre de poursuivre et d’estimer avec plus de facilités les améliorations qui restent à faire. Cette poursuite va être entamée par deux des membres du TER (Damien et Romain) qui vont travailler dessus lors d’un stage chez ILOG. De plus, l’ensemble de notre projet est suivi par la communauté TWiki et les sources sont disponibles librement sur le CVS.

Conclusion

M. Buffa et M. Nahaboo ont été présent tout au long du projet, ils nous ont guidé dans nos choix, nous ont montré comment se déroulait un projet de cette envergure et ont répondu à nos questions. Mais de notre côté, il fallait aussi leur montrer qu’on savait ce que l'on faisait, il fallait les rassurer.

Ce TER nous a donc beaucoup appris, que ce soit au niveau du travail en groupe, dans l’apprentissage de nouvelles technologies, mais aussi par le simple fait d’avoir rencontré et travaillé avec M. Nahaboo qui nous a fait bénéficié de son expérience.

Notre projet est fonctionnel, et facilement intégrable dans un TWiki. On espère qu’il sera massivement utilisé, notamment par notre faculté. Nous sommes assez fière de ce que nous avons réalisé.

Une chose importante, est que notre projet correspond aux attentes formulées au départ. Or, dans le monde de l’entreprise, il est difficile de bien comprendre, cerner ce que souhaite le client et ainsi réaliser la bonne application.

Concernant l'apport de l'enseignement reçu à l'Université, il a été déterminant. Par exemple, dans la réalisation des applications clientes en Java, less nombreux projets que nous avons réalisés au cours des deux dernières années nous ont fourni l'expérience nécessaire à la réussite.

Annexe 0 : Manuel d'installation

Installation des outils d'édition WYSIWYG et de refactoring

Installation des outils d'édition WYSIWYG et de refactoring Pré requis TWiki (version du 01 Février 2003) Perl 5.6+ Librairies Perl SOAP::Lite 0.55+ XML::TreeBuilder 3.08+ (optionnel) Ressources Service Editeur WYSIWYG Outil de refactoring Procédure Service Copie de fichiers Configuration Editeur WYSIWYG Copie de fichiers Configuration du descripteur Java Web Start Modification des templates TWiki Outil de refactoring Copie des fichiers Modification des templates TWiki Pré requis TWiki (version du 01 Février 2003) Nous avons développé nos services sur cette version de TWiki. Nous pouvons difficilement prédire leurs comportements sur de futures versions. Perl 5.6+ Les services Web ont été développés et principalement testés avec la version 5.8 de Perl. Aucune fonctionnalité spécifique à cette version n?a été utilisée et nous n?avons pas constaté de problème avec la version 5.6. Librairies Perl SOAP::Lite 0.55+ SOAP::Lite est requis pour pouvoir utiliser les services Web nécessaires aux applications de refactoring et d?édition WYSWIYG. XML::TreeBuilder 3.08+ (optionnel) Cette librairie n?est requise que si le service de notifications est activé. Ressources Service

Hierarchie de fichiers pour services:

service_tree.jpg

Le répertoire bin contient des scripts Perl :

jnlplauncher : un script qui génère des descripteurs Web Start JNLP à la volée. service : un serveur SOAP de type script CGI. Le répertoire lib contient les modules Perl requis par les services Web ainsi qu?un fichier de configuration :

Service.cfg : le fichier de configuration. Service.pm et le répertoire Service : les implémentations des services.

Editeur WYSIWYG Le répertoire twe contient les ressources de l'éditeur : twe twe.jar : jar exécutable signé et déployable sur un serveur TWiki twe.jnlp : le descripteur Java Web Start (cf. installation de l'éditeur) twe.src.jar : le code source de l'éditeur

Outil de refactoring Le répertoire refactoring contient les ressources de l'outil de refactoring :

refactoring.jar : jar exécutable signé et déployable sur un serveur TWiki Refactor.jnlp : le descripteur Java Web Start (cf. installation de l'éditeur) src : répertoire contenant le code source de l'éditeur doc : la documentation

Procédure Service Copie de fichiers Copier le contenu du répertoire bin dans *TWiki Install Dir*/bin, et le contenu du répertoire lib dans *TWiki Install Dir*/lib. Il ne faut pas oublier de donner les permissions d?exécution aux scripts jnlplauncher et service. Il sera peut être nécessaire de modifier les entêtes des scripts pour être exécutables par l?interpréteur Perl sur votre configuration. Configuration Ouvrir dans un éditeur de texte le fichier Service.cfg. Les valeurs données par défaut peuvent être laissées telles quelles à l?exception de: endpoint et jnlpDir. endpoint doit définir l?url du serveur SOAP, par exemple http://hostname/bin/service. jnlpDir doit définir le répertoire où le script jnlplauncher devra chercher les descripteurs Web Start JNLP, par exemple /usr/home/httpd/twiki/jnlp/. Editeur WYSIWYG Copie de fichiers Copier les fichiers twe.jar et twe.jnlp dans le répertoire spécifié par jnlpDir dans Service.cfg.

Configuration du descripteur Java Web Start Ouvrir dans un éditeur de texte le fichier twe.jnlp. Par défaut le codebase est placé sur la machine de test du projet ( par défaut : http://miageprojet.unice.fr/twikitestnice/) il faut modifier cette valeur par l'URL ou l'ont peu télécharger les fichiers twe.jar et twe.jnlp. Exemple : jnlp spec="1.0+" codebase="http://twikiserveur.fr/jnlp/">

Modification des templates TWiki Pour permettre l'édition en ligne d'un topic TWiki, il faut ajouter un lien dans le template correspondant au topic considéré. Ce lien est le suivant : a href='/cgi-bin/twiki/bin/jnlplauncher/Minfo/TerBn1Installation?jnlp=twe.jnlp> (voir "raw view" pour le lien réel)

Il s'agit d'un appel au script jnlplauncher avec en argument le fichier jnlp et ses arguments.

Outil de refactoring La procédure d'installation de l'outils de refactoring est trés proche de celle de l'éditeur.

Copie des fichiers Il faut copier les fichiers refactoring.jar et Refactor.jnlp dans le répertoire jnlpDir dans Service.cfg, puis modifier le codebase dans le fichier Refactor.jnlp à l'aide d'un éditeur de texte, pour mettre la valeur de l'URL d'accés à ces fichiers depuis internet ou l'intranet (http://nom_serveur/twiki/ par exemple).

Modification des templates TWiki Pour lancer l'application depuis une page web, il faut ajouter le lien suivant dans les templates :

a href="/cgi-bin/twiki/bin/jnlplauncher/Minfo/TerBn1Installation?jnlp=refactoring.jnlp">Refactoring tool

Bref, faudra bien qu'on puisse l'installer un jour ?

Annexe 1 : Services Web et structures de données

Structures de données

ConnectionInfo

Champs Types Commentaire
key int Clef de connexion
timeout int Timeout auquel TWiki est réglé avant de nous déconnecter
subwebs boolean Sous-webs gérés ou non par le service
adminLock boolean Verrou administratif (concurrence entre applications de refactoring) géré par le service ?
locksActualization boolean Actualisation des verrous (administratifs et topics) lors d'un ping ou gestion à faire depuis le client ?
completeRemoveAllowed boolean Suppression complète des topics (et attachements) autorisée ?

User

Champs down Types Commentaire
connection java.util.Calendar Date de connexion de l'utilisateur
login String Login de l'utilisateur
usage String Renseignement sur l'usage du service qu'en fait l'utilisateur

Attachment

Champs Types Commentaire
name String Nom de l'attachement
path String Chemin du fichier avant l'upload
attr string Attachement caché ?
date int Date (en secondes)
user String Utilisateur qui l'a posté
size int Taille
version Float Version de l'attachement
comment String Commentaire associé
content byte[] Contenu binaire

Topic

Champs Types Commentaire
web String Web dans lequel est stoqué le topic
name String Nom du topic
version Float Version du topic (RCS)
author String Auteur du topic
parent String Topic parent
date int Date de création du topic (en secondes)
format String Format TWiki du topic (1.0)
attachments Attachment[] Tableau d'attachements
data String Contenu du topic

Services Web


connect

  • Auteur : Romain RAUGI
  • Version : CVS 1.7
  • Package : Service::Connection

Description

Connexion d'un utilisateur au service (tout service requiert une connexion préalable).

Signature

  • Paramètre(s) :
    • String usage : Usage que veut faire un utilisateur du service
    • String login : Login de l'utilisateur
    • String password : Password
  • Valeur(s) retournée(s) :
    • ConnectionInfo : Connexion établie
    • null : Login/pass incorrect ou service saturé

copyTopic

  • Auteur : Romain RAUGI
  • Version : CVS 1.5
  • Package : Service::Refactoring

Description

Copie de topic avec changement possible de parent et de nom.

Signature

  • Paramètre(s) :
    • int key : Clef de connexion
    • String srcWeb : Web du topic source (syntaxe = Web[/Web]*)
    • String topic : Topic à copier ("WebHome" par exemple)
    • String dstWeb : Web destination
    • String newName : Nouveau nom
    • String parent : Topic parent auquel le rattacher ("" = WebHome)
    • boolean attachments : Copie des attachements ?
  • Valeur(s) retournée(s) :
    • int : Code d'erreur
      • 0 : OK
      • 1 : Non connecté
      • 2 : Pas de verrou adminsitartif déposé
      • 3 : Le topic source n'existe pas
      • 4 : Le nouveau nom correspond à un topic déjà existant
      • 5 : Le topic parent destination n'existe pas
      • 6 : Le nouveau nom n'est pas un WikiWord
      • 7 : Pas les permissions pour copier
      • 8 : Impossible de verrouiller le fichier cible (en cours de création par un autre)
      • 9 : Problème lors de la copie, c.a.d lors de la création du topic cible
      • 10 : Sous-webs pas autorisés

disconnect

  • Auteur : Romain RAUGI
  • Version : CVS 1.7
  • Package : Service::Connection

Description

Déconnexion du service.

Signature

  • Paramètre(s) :
    • int key: Clef de connexion
  • Valeur(s) retournée(s) :
    • true : Déconnexion effectuée
    • false: Déjà déconnecté auparavant probablement

getAttach

  • Auteur : Maxime LAMURE
  • Version : 1.0
  • Package : Service::Editeur

Description

Ce service permet de récupérer un objet de type Attachment correspondant au nom de fichier donné en paramètre.

Signature

  • Paramètre(s) :
    • param1: le chemin du topic
    • param2: le nom du fichier
  • Valeur(s) retournée(s) :
    • objet de type Attachment dont les propriétés correspondent au fichier donne en paramètre.

Exemple

Attachment att=stub.getAttach("Main/WebList.txt",&#8221;toto.avi&#8221;);
System.out.println(att.getDate());
System.out.println(att.getName());

getListAttach

  • Auteur : Maxime LAMURE
  • Version : 1.0
  • Package : Service::Editeur

Description

Ce service renvoie la liste de tous les noms de fichiers en attachement au topic passé en paramètre.

Signature

  • Paramètre(s) :
    • param1 : chemin du topic
  • Valeur(s) retournée(s) :
    • Un tableau de chaîne de caractères contenant les noms des fichiers d’attachement.

Exemple

String [] liste=stub.getListAttach("Main/WebList.txt");
System.out.println("fichier : "+liste[0]);
-> fichier : toto.avi

getTopic

  • Auteur : Maxime LAMURE
  • Version : 1.0
  • Package : Service::Editeur

Description

Récupère un objet de type Topic instancie avec les propriétés du topic dont le nom est donné en paramètre.

Signature

  • Paramètre(s) :
    • param1 : chemin du topic
    • param2 : La clé unique de l’utilisateur
  • Valeur(s) retournée(s) :
    • Une instance d’un objet de type Topic correspondant au topic donné en paramètre.

Exemple

Topic p=stub.getTopic("Main/WebSearch.txt",125);
System.out.println("Autheur: "+p.getAuthor());
-> Auteur: PeterThoeny

getUsers

  • Auteur : Romain RAUGI
  • Version : CVS 1.7
  • Package : Service::Connection

Description

Liste des utilisateurs connectés au service.

Signature

  • Paramètre(s) :
  • Valeur(s) retournée(s) :
    • User[] : Liste des utilisateurs (null si aucun)

getWebs

  • Auteur : Romain RAUGI
  • Version : CVS 1.5
  • Package : Service::Topics

Description

Liste des webs ou des sous-web si un web est passé en paramètre.

Signature

  • Paramètre(s) :
    • String root : "" pour obtenir les webs, un web pour en obtenir les sous-webs.
  • Valeur(s) retournée(s) :
    • String[] : Liste des webs

Exemple

String[] webs = stub.getWebs("");
System.out.println(webs);
-> Main _default TWiki Trash Sandbox

giveHierarchy

  • Auteur : Maxime LAMURE
  • Version : 1.0
  • Package : Service::Arborescence

Description

Ce service ressemble à la commande ls en UNIX.

Signature

  • Paramètre(s) :
    • param1 : Le chemin du Web
    • param2 : La clé unique de l’utilisateur
  • Valeur(s) retournée(s) :
    • Un tableau de chaîne de caractères contenant les noms des Web et des topics présent dans param1. Les fichiers se terminant par .txt sont des topics, les autre des Webs.

Exemple

String [] result=stub.giveHierarchy("../data/Main",125);
for(int i=0;i<result.length ;i++)
    System.out.println(result[i]);

-> ANewPage.txt 
   ImaeWeb.txt
   WebHome.txt
   ...

giveTopicProperties

  • Auteur : Maxime LAMURE
  • Version : 1.0
  • Package : Service::Arborescence

Description

Ce service permet de récupérer les propriétés d’un topic.

Signature

  • Paramètre(s) :
    • param1 : Le chemin du topic
    • param2 : La clé unique de l’utilisateur
Valeur(s) retournée(s)
Un tableau de chaîne de caractères répertoriant les propriétés du topic. Pour les droits, la convention est la suivante :

  1. : aucun droit d’écriture
  2. : droit de change
  3. : droit de renomage
  4. : droit de change et de renomage

Exemple

String[]prop=stub.giveTopicProperties("Main/toto.txt",125);
System.out.println(&#8220; taille: &#8221;+prop[0]);             ->  25685
System.out.println(&#8220; web: &#8221;+prop[1]);              -> Main
System.out.println(&#8220; chemin: &#8221;+prop[2]);         -> /twiki/data/Main
System.out.println(&#8220; topic parent: &#8221;+prop[3]);  -> MainPage
System.out.println(&#8220; auteur: &#8221;+prop[4]);           -> guest
System.out.println(&#8220; date creation: &#8221;+prop[5]); -> lundi 18 avril
System.out.println(&#8220;date modification: &#8221;+prop[6]); -> mardi 1 mai
System.out.println(&#8220; version: &#8221;+prop[7]);          -> 1.1
System.out.println(&#8220; format: &#8221;+prop[8]);           -> 1.0
System.out.println(&#8220; droit: &#8221;+prop[9]);              -> 3

giveWebProperties

  • Auteur : Maxime LAMURE
  • Version : 1.0
  • Package : Service::Arborescence

Description

Permet de récupérer la propriété du Web.

Signature

  • Paramètre(s) :
    • param1 : le chemin du Web.
  • Valeur(s) retournée(s) :
    • Un entier représentant le nombre en octet. Cette taille n’est pas récursive.

Exemple

int taille=stub.giveWebProperties("Main");
System.out.println("La taille est de: "+taille);

lockTopic

  • Auteur : Romain RAUGI
  • Version : CVS 1.5
  • Package : Connection::Topics

Description

Verrouillage ou déverrouillage explicite de topic. Le déverrouillage n'est authorisé qu'au détenteur du verrou (via username si déposé par TWiki lui-même, via clef de connexion si déposé via service).

Signature

  • Paramètre(s) :
    • int key : Clef de connexion
    • String web : Web du topic (syntaxe = Web[/Web]*)
    • String topic : Topic à renommer (syntaxe = WikiWord)
    • boolean doLock: Verrouiller (true) ou déverrouiller (false)?
  • Valeur(s) retournée(s) :
    • boolean : Echec ou succès
A noter : retournera succès lors d'un déverrouillage même s'il n'y a pas de verrou déposé.

mergeTopics

  • Auteur : Romain RAUGI
  • Version : CVS 1.5
  • Package : Service::Refactoring

Description

Fusion de topics.

Signature

  • Paramètre(s) :
    • int key : Clef de connexion
    • String webTarget : Web du topic n°1 (syntaxe = Web[/Web]*)
    • String topicTarget : Topic "destination" participant à la fusion (syntaxe = WikiWord)
    • String webFrom : Web du topic n°2
    • String topicFrom : Topic n°2 participant à la fusion (syntaxe = WikiWord)
    • boolean attachments : Gérer les attachements dans la fusion ?
    • boolean identify : Génération ou non d'un rapport (page en mode verbatim) indiquant de manière détaillée le résultat de la fusion
    • int removeOption : Options concernant le topic n°2
      • -1 : Pas de suppression
      • cf. removeTopic pour les autres codes
    • boolean dontNotify : Notifier ou non du changement
  • Valeur(s) retournée(s) :
    • int : Code d'erreur
      • 0 : OK
      • 1 : Non connecté
      • 2 : Pas de verrou administratif
      • 3 : Le topic n°1 n'existe pas
      • 4 : Le topic n°2 n'existe pas
      • 5 : Les topics 1 et 2 sont les mêmes
      • 6 : Pas les permissions de modifier le topic n°1
      • 7 : Topic n°1 déjà verrouillé
      • 8 : Problème lors de la modification du topic n°1
      • 9 : Problème lors de la suppression du topic n°2 (si demandée)
      • 10 : Sous-webs pas autorisés

moveTopic

  • Auteur : Romain RAUGI
  • Version : CVS 1.5
  • Package : Service::Refactoring

Description

Déplacement de topic avec changement de parent possible.

Signature

  • Paramètre(s) :
    • int key : Clef de connexion
    • String srcWeb : Web du topic (syntaxe = Web[/Web]*)
    • String topic : Topic à renommer (syntaxe = WikiWord)
    • String dstWeb : Web destination
    • String parent : Topic parent auquel le rattacher ("" = WebHome)
    • int update : Mise à jour des liens qu'y s'y réfèrent
      • 0 : Pas de maj
      • 1 : Maj dans tous les webs
      • 2 : Maj dans les webs source et destination
  • Valeur(s) retournée(s) :
    • int : Code d'erreur
      • 0 : OK
      • 1 : Non connecté
      • 2 : Pas de verrou administratif
      • 3 : Le topic source n'existe pas
      • 4 : Le topic parent destination n'existe pas
      • 5 : Pas les permissions pour renommer
      • 6 : Topic déjà verrouillé
      • 7 : Le topic existe déjà dnas le Web destination
      • 8 : Problème lors du déplacement Web source/ Web destination
      • 9 : Problème lors de la modification du lien vers le topic parent
      • 10 : Sous-webs pas autorisés

ping

  • Auteur : Romain RAUGI
  • Version : CVS 1.7
  • Package : Service::Connection

Description

Avertissement au serveur qu'on est toujours présent, actualisation des verrous déposés (si service configuré pour).

Signature

  • Paramètre(s) :
    • int key: Clef de connexion
  • Valeur(s) retournée(s) :
    • true : On est toujours connecté
    • false: On l'est plus

removeSubscription

  • Auteur : Romain RAUGI
  • Version : CVS 1.2
  • Package : Service::Notification

Description

Résialiation d'abonnement aux événements TWiki.

Signature

  • Paramètre(s) :
    • int key : Clef de connexion
  • Valeur(s) retournée(s) :
    • true : On est abonné
    • false: On l'est pas (plus) ou le service ne gère pas les notifications

removeTopic

  • Auteur : Romain RAUGI
  • Version : CVS 1.5
  • Package : Service::Refactoring

Description

Suppression de topic. Attention, ce qui s'applique aux topics s'applique aux attachements ...

Signature

  • Paramètre(s) :
    • int key : Clef de connexion
    • String web : Web du topic (syntaxe = Web[/Web]*)
    • String topic : Topic (syntaxe = WikiWord)
    • int option : Web destination
      • 0 : Déplacement dans le web Trash, génération automatique d'un ID si nom de topic y existe déjà (si service configuré pour)
      • 1 : Déplacement dans le web Trash, suppression de celui qui existerait éventuellement dans Trash (si fonctionnalité autorisée par le service)
      • 2 : Suppression complète (si fonctionnalité autorisée par le service)
      • Autre : Déplacement dans le web Trash, erreur si topic de même nom y existe déjà (pas de génération automatique d'ID)
    • String trashName : Nom à donner au topic dans le web Trash ('' = topic)
  • Valeur(s) retournée(s) :
    • int : Code d'erreur
      • 0 : OK
      • 1 : Non connecté
      • 2 : Pas de verrou administratif
      • 3 : Le topic n'existe pas
      • 4 : Pas les permissions de supprimer le topic
      • 5 : Topic déjà verrouillé
      • 6 : TrashName n'est pas un WikiWord
      • 7 : Impossible de supprimer celui qui se trouve dans le web Trash
      • 8 : Problème lors de l'envoi vers le web Trash
      • 10 : Sous-webs pas autorisés

renameTopic

  • Auteur : Romain RAUGI
  • Version : CVS 1.5
  • Package : Service::Refactoring

Description

Renommage de topic, de la "pile" RCS associée et de la location des attachements.

Signature

  • Paramètre(s) :
    • int key : Clef de connexion
    • String web : Web du topic (syntaxe = Web[/Web]*)
    • String topic : Topic à renommer (syntaxe = WikiWord)
    • String name : Nouveau nom (WikiWord, sinon retour d'un code d'erreur)
    • int update : Mise à jour des liens qu'y s'y réfèrent
      • 0 : Pas de maj
      • 1 : Maj dans tous les webs
      • 2 : Maj au sein du web
  • Valeur(s) retournée(s) :
    • int : Code d'erreur
      • 0 : OK
      • 1 : Non connecté
      • 2 : Pas de verrou administratif
      • 3 : Le topic n'existe pas
      • 4 : Le nouveau nom correspond à un topic existant
      • 5 : Le nouveau nom donné n'est pas un WikiWord
      • 6 : Pas les permissions pour renommer
      • 7 : Topic déjà verrouillé
      • 8 : Problème lors du renommage
      • 10 : Sous-webs pas autorisés

sameTopicParent

  • Auteur : Maxime LAMURE
  • Version : 1.0
  • Package : Service::Arborescence

Description

Ce service retourne une representation de l'arborescence en fonction des parametres donnés:

Signature

  • Paramètre(s) :
    • param1: Le nom du topic parent
    • param2 : Le nom du Web où commence la recherche
    • param3: La clé unique de l’utilisateur
  • Valeur(s) retournée(s) :
    • Un tableau de chaîne de caractères regroupant les chemins des topics ayant le même topic parent. Si le topic retourné est lui-même un topic parent, alors il se termine par #
  • Quelques exemples
    • sameTopicParent("","nomWeb",clé) :
Renvoie la liste des topics parents et la liste des topic qui n'on pas de parent et qui ne sont pas parent. Pour connaitre la liste des topic enfant, il suffit de rappeller cette méthode avec le nom du topic parent en parametre. Si un parent est aussi enfant, il ne sera affiche qu'en appelant la fonction avec le nom de son parent. Les cycles sont gérés.
    • sameTopicParent("Nomtopic","",clé):
Renvoie la liste des topic qui ont Nomtopic comme parent.
    • sameTopicParent("Web.Nomtopic","",clé) :
Renvoie la liste des topic qui ont Nomtopic ou Web.Nomtopic comme parent.

Exemple

String []parent=stub.sameTopicParent("MainPage",&#8221;&#8221;,125);
for(int i=0;i<parent.length ;i++)
System.out.println(parent[i]);

->     /Main/Toto.txt
       /Main/Tata.txt#

setAdminLock

  • Auteur : Romain RAUGI
  • Version : CVS 1.7
  • Package : Service::Connection

Description

Verrou administratif.

Signature

  • Paramètre(s) :
    • int key: Clef de connexion
    • boolean doLock : Verrouiller ou déverrouiller ?
  • Valeur(s) retournée(s) :
    • true : Ok
    • false: Pas (dé)verrouillable

setTopic

  • Auteur : Romain RAUGI
  • Version : CVS 1.5
  • Package : Service::Topics

Description

Sauvegarde d'un topic voire d'attachements

Signature

  • Paramètre(s) :
    • int key : Clef de connexion
    • Topic topic : Objet topic à sauvegarder
    • boolean doKeep : Supprimer les attachements dont on n'a pas renvoyé les infos ?
    • boolean doUnlock : Déverrouiller ?
    • boolean dontNotify : Notifier du changement aux autres ?
  • Valeur(s) retournée(s) :
    • int : Code d'erreur
      • 0 : OK
      • 1 : Non connecté
      • 2 : Le topic n'existe pas
      • 3 : Topic nul passé en paramètre
      • 4 : Pas les permissions
      • 5 : Topic verrouillé par qqun d'autre
      • 6 : Problème lors de la modification
      • 10 : Sous-webs pas autorisés

subscribe

  • Auteur : Romain RAUGI
  • Version : CVS 1.2
  • Package : Service::Notification

Description

Abonnement aux événements TWiki.

Signature

  • Paramètre(s) :
    • int key : Clef de connexion
    • int port : Port sur lequel on veut recevoir les notifications
  • Valeur(s) retournée(s) :
    • true : Ok
    • false: Clef incorrecte ou service de notifications désactivé

Annexe 2 : Documentation utilisateur de l'éditeur

Premier lancement de l'application

Il est normalement réalisé depuis un topic TWiki par l'intermédiaire de Java Web Start. Il suffit de cliquer sur un lien tel que représenté ici :

Après avoir cliquer, le téléchargement commence. Ce téléchargement n'aura lieu qu'en cas de mise à jour de l'éditeur côté serveur.

Ensuite apparaît la fenêtre suivante. Il faut répondre Démarrer, afin d'autoriser l'éditeur à accéder au poste local pour la sauvegarde d'un topic par exemple.

Enfin, la fenêtre de login s'ouvre, il est alors possible de s'identifier pour éditer la page.

Utilisation de l'éditeur

Barre actions diverses

Ceci est la barre de bouton qui commande les actions suivantes (de gauche à droite) :
  • Nouveau document : Propose la sauvegarde du document actif et crée un document vide.
  • Ouvrir document : Propose l'ouverture d'un document au format HTML (.html) ou TWikiML (.twiki). Il est déconseillé d'ouvrir un document HTML avec l'éditeur car il pourrait contenir des balises non reconnues.
  • Enregistrer document : Propose l'enregistrement du document au format .twiki
  • Défaire : Annule la dernière opération de formatage réalisée.
  • Refaire : Le pendant de Défaire.
  • Couper
  • Copier
  • Coller
  • Rechercher
  • Configurer l'éditeur : Permet de choisir si le mot de passe doit être enregistré dans la machine.
  • Validation coté serveur : Une fois l'édition terminée, permet d'enregistrer le topic sur le serveur.

Arbre du document

Il permet de naviguer dans le document. En cliquant sur un élément de l'arbre, le curseur se déplace dans la section correspondante. Il est construit à partir de la hiérarchie de titres du document.

Barre d'onglet

Permet de sélectionner la vue à éditer. Les trois vues sont synchronisées, ainsi on peux éditer n'importe qu'elle vue pour mettre à jour le document.

Barre de formatage supérieure

Barre de bouton pour le formatage du texte. De gauche à droite :
  • T0,T1,...,T2 : Change le texte sélectionné en style : paragraphe, titre de taille 1,2,3,4,5,6. Si le texte sélectionné est du même type que le bouton choisis, le texte est mis au format paragraphe.
  • insert-line : Insère à la position du curseur une ligne horizontale de séparation.
  • insert-table : Insère un tableau. On peux choisir la taille du tableau via la fenêtre suivante :

  • append-row : Ajoute une ligne à la fin du tableau dans lequel se trouve le curseur.
  • append-col : Ajoute une colonne à la fin du tableau dans lequel se trouve le curseur.
  • insert-row : Insère une ligne après la cellule du curseur.
  • insert-col : Insère une colonne après la cellule du curseur.

Barre de formatage inférieure

  • font-bold : Met en gras la sélection.
  • font-italic : Met en italique la sélection.
  • font-code : La sélection est transformée en police à chasse fixe.
  • Couleurs : Colorie la sélection.
  • toggle-ul : Place devant chaque ligne de la sélection un puce.
  • toggle-ol : Place devant chaque colonne de la sélection un numéro croissant.

Comportements spécifiques

  • Dans un tableau la touche TAB permet de passer à la cellule suivante, si le curseur est dans la dernière cellule, l'éditeur crée une nouvelle ligne
  • Si le curseur se trouve dans une liste à puce ou numérotée, la touche ENTREE a pour effet la création d'une nouvelle puce (ou numéro suivant) à la ligne suivante.
  • sinon, la touche ENTREE sert à commencer un nouveau paragraphe.

Annexe 3 : Documentation utilisateur de l'outil de refactoring

Lancement de l’application

L’outil de refactoring se lance à partir d’une page web du TWiki en cliquant sur le lien « Refactoring tool ». Une boîte de dialogue s’affiche permettant à l’utilisateur de se connecter : il doit saisir son nom d’utilisateur, son mot de passe et éventuellement le champ usage décrivant ses intentions.

Une fois que l’utilisateur est connecté, la fenêtre principale de l’application apparaît. On y retrouve deux arbres décrivant l’arborescence de TWiki, séparés par des boutons d’actions et un cadre de description des éléments de l’arborescence.

Pour effectuer une opération sur un topic, il faut le sélectionner dans l’arbre de gauche, et éventuellement choisir une destination dans l’arbre de droite si on veut effectuer un déplacement ou une copie, puis cliquer sur le bouton correspondant à la modification que l’on désire faire. Lorsque l'on clique sur un élément de l'arbre de gauche, ses caractéristiques sont affichées dans le cadre "info".

Description des fonctionnalités

Il est possible d’effectuer cinq actions différentes :

  • le déplacement
  • le renommage
  • la suppression
  • la fusion
  • la copie

A chaque action correspond des options qui permettent d’être plus précis. Elle se situe dans le menu « Options ».

Le déplacement

Pour déplacer un topic ou un groupe de topics, il suffit de les sélectionner dans l’arbre de gauche et choisir une destination dans l’arbre de droite, puis d’appuyer sur le bouton « Move ». Si l’élément de destination sélectionné est un web, les topics seront déplacés dans le topic WebHome de ce web. Le webs ne peuvent pas être déplacés.

Option de déplacement

« No update » : pas de mise à jour des liens qui se réfèrent au topic

« update all webs » : mise à jour des liens dans tous les webs

« update into source and destination webs » : mise à jour dans les webs source et destination seulement

Le renommage

Pour renommer un topic, il faut le sélectionner dans l’arbre de gauche puis cliquer sur le bouton « Rename ». Une boite de dialogue s’affiche alors, permettant de saisir le nouveau WikiName? du topic. Le webs ne peuvent pas être renommés.

Option de renommage

« No update » : pas de mise à jour des liens qui se réfèrent au topic

« update all webs » : mise à jour des liens dans tous les webs

« update into the web of the topic » : mise à jour dans le web contenant le topic seulement

La suppression

Pour supprimer un topic ou un groupe de topics, il suffit de les sélectionner dans l’arbre de gauche et d’appuyer sur le bouton « Delete ». Le webs ne peuvent pas être supprimés.

Options de suppression

« move in trash web with renaming » : déplacement dans le web Trash, génération automatique d'un ID si le nom de topic y existe déjà

« move in trash web with overwritting » : Déplacement dans le web Trash, suppression de celui qui existerait éventuellement dans Trash

« complete removing » : Suppression complète

« move in trash web » : Déplacement dans le web Trash, une erreur est produite si un topic de même nom y existe déjà

La fusion

Pour fusionner des topics, il faut les sélectionner dans l’arbre de gauche puis cliquer sur le bouton « Merge ». Le topic principale de la fusion (celui dans lequel le contenu des autres topics sera ajouté) correspond au premier topic sélectionné. Le webs ne peuvent pas être fusionnés.

Options de fusion

« don’t remove » : Ne supprime pas les topics

« manage attachments » : si elle est cochée, gére les fichiers attachés (les ajoutes au topic final)

« make report » : génère ou non un rapport (page en mode verbatim) indiquant de manière détaillée le résultat de la fusion

« don’t notify » : Notification ou non du changement

Les autres options sont identiques aux options de suppression.

La copie

Pour copier un topic ou un groupe de topics, il suffit de les sélectionner dans l’arbre de gauche et choisir une destination dans l’arbre de droite, puis d’appuyer sur le bouton « Copy ». Si l’élément de destination sélectionné est un web, les topics seront déplacés dans le topic WebHome de ce web. Le webs ne peuvent pas être copiés

Option de copie

« Copy attachments » si cette option est sélectionné, les fichiers attachés sont copier dans le web de destinations

Description de la barre de menu

Le menu « File »

Ce menu contient uniquement un bouton exit pour quitter l’application

Le menu « Edit »

Ce menu contient tous les boutons correspondant aux fonctionnalités décrites ci-dessus, et également le bouton « set administrator lock ». Pour pouvoir faire des modifications, il faut que le verrou administratif soit posé afin que plusieurs utilisateurs ne puissent pas modifier l’arborescence en même temps. Si la case est coché, le verrou est posé sinon il ne l’est pas.

Le menu « Options »

Ce menu contient toutes les options des opérations décrites dans la partie précédante.

Le menu « Help »

Ce menu contient le bouton « Connected users… » permettant d’afficher dans une boîte de dialogue la liste des utilisateurs connectés au système.

Annexe 4 : Documentation de l'application serveur pour développeurs

Annexe 5 : TWiki WYSIWYG Editor - Manuel de maintenance

Introductiont

On dispose :

  • du traducteur TWiki ML <-> HTML de F. Luddeni
  • de l'API Java qui met en oeuvre, au travers de SWING, le modèle MVC (modèle vue contrôleur). Dans notre cas, les classes intervenant sont :
  • JEditorPane pour la vue
  • HTMLEditorKit pour le contrôleur
  • HTMLDocument pour le modèle

Un document TWiki peut être traduit en un document HTML, cependant ce document HTML ne comporte qu'un sous-ensemble limité de balises HTML.

L'idée du programme est de réaliser un éditeur HTML en Java dont le champ d'action correspond au sous-ensemble HTML en bijection avec les éléments de syntaxe TWiki. On trouvera plus de détail sur ce sous-ensemble dans les annexes du cahier des charges. L'éditeur WYSIWYG est complètement dépendant du traducteur aussi bien dans le sens entrant (TWiki ML -> HTML) que sortant (HTML -> TWiki ML). On s'efforcera donc de ne pas y toucher pour garantir l'évolutivité de l'application. Par rapport à un éditeur HTML classique, Un éditeur dédié à TWiki présente les intérêts suivants :

  • Ajout de fonctionnalités dynamiques (Insertion de WikiWord?, de pièces jointes, ...)
  • Gestion spécifique d'élément de syntaxe TWiki : par exemple, réalisé un mapping entre smileys TWiki et image gif correspondante dans l'éditeur HTML
  • Evolution des services dynamiques en relation avec le web service

Architecture de l'application

Packages

  • twe.actions.misc : contient les actions diverses telles que l'ouverture, la sauvegarde de documents locaux, la complétion,... .
  • twe.actions.twiki : contient les actions d'édition de texte (Titres, Gras, Insertion de tableau, ...).
  • twe.gui : contient les élements d'interface utilisateur.
  • twe.translator : contient le traducteur HTML <-> TWiki ML. Il est préférable de ne pas faire de modifications sur ce traducteur pour rendre l'éditeur indépendant d'éventuelles évolutions du traducteur.
  • twe.util contient diverses classes utiles à l'application. Concerne essentiellement HTMLDocument et Element

Fonctionnement

La classe principale est MainFrame. Cette classe est chargée de mettre en place les composants Swing de l'interface et de leur donnée vie au travers d'écouteurs et d'actions. MainFrame dispose d'un ensemble d'actions qui se trouve dans twe.actions. La plupart de ces actions implémentent TWEAction qui est une interface décrivant une action comme possédant un bouton un controleur et une icone. Cela facilite le montage de l'interface graphique.

La plupart des actions se contente d'hériter d'actions déjà existantes dans l'API Java. C'est le cas par exemple des actions pour le copier/coller ou pour le gras et l'italique. D'autres actions comme l'insertion de tableau ou de liste à puces n'existent pas dans l'API et doivent être codée en manipulant le document HTML.

Extensions de l'application

Ajouter une fonctionnalité

C'est très simple, il suffit de :

  • créer une classe héritant de Action et implémentant TWEAction
  • dans MainFrame, modifier la fonction buildMiscBar() ou buildFormatBar() en instantiant l'action nouvellement crée.

NB : Le code effectif de l'action nouvellement crée se trouve dans la fonction héritée actionPerformed. Une action disposant généralement d'un contrôleur (JEditorPane, MainFrame,...) il n'est pas nécessaire d'utiliser l'objet évenement passé en argument de actionPerformed pour récupérer la source de l'action. Il suffit d'utiliser directement la référence au contrôleur.

Modifier le traducteur (externe) TWiki ML <-> HTML

Il suffit de remplacer les classes du traducteur par les nouvelles. Du point de vue de l'éditeur, le traducteur est considéré comme un composant. Le package concerné est twe.translator.

Modifier les stubs d'appel au web service

Tout comme le traducteur, il suffit de remplacer les anciennes classes par les nouvelles. Cependant si la signature des fonctions d'appel au web service change, il faudra également modifier les appels à ces fonctions. Le package concerné est fr.unice.twikiservice.

Documentation - Faire des documents PDF à part des annexes !


to top

I Attachment sort Action Size Date Who Comment
WSImg.GIF manage 39.9 K 07 Jun 2004 - 20:06 LamureMaxime  
twiki.jpg manage 29.8 K 08 Jun 2004 - 13:17 RomainRaugi TWiki Fonctionnement
application.jpg manage 26.9 K 08 Jun 2004 - 13:18 RomainRaugi Application : cycle de vie
click.gif manage 37.5 K 08 Jun 2004 - 16:09 MandrioliDamien Lancement de l'éditeur par Java Web Start
down.gif manage 8.7 K 08 Jun 2004 - 16:18 MandrioliDamien Téléchargement de l'éditeur
security.gif manage 10.0 K 08 Jun 2004 - 16:18 MandrioliDamien Autorisation d'accès par l'éditeur
login.gif manage 5.5 K 08 Jun 2004 - 16:19 MandrioliDamien Invite de login de l'éditeur
all.gif manage 63.9 K 08 Jun 2004 - 16:29 MandrioliDamien Les différentes parties de l'éditeur
table.gif manage 6.7 K 08 Jun 2004 - 16:53 MandrioliDamien Choix de la taille d'un nouveau tableau
editor_seq.gif manage 12.1 K 09 Jun 2004 - 10:00 MandrioliDamien Session Edition WYSIWYG (diagramme de séquence)
refactoring.gif manage 32.2 K 09 Jun 2004 - 14:57 MarioDIMICELI Application de refactoring
seqRefactoring.gif manage 16.0 K 10 Jun 2004 - 01:48 MarioDIMICELI diagramme de séquence (refactoring)
loginRefactoring.gif manage 4.7 K 10 Jun 2004 - 07:46 MarioDIMICELI  
exempleRefactoring.gif manage 55.5 K 10 Jun 2004 - 07:46 MarioDIMICELI  
TWikiWYSIWYGEditor-Manueldemaintenance.pdf manage 69.3 K 10 Jun 2004 - 08:54 MandrioliDamien  
ServicesWebpourTWiki-Manueldemaintenance.pdf manage 279.0 K 10 Jun 2004 - 09:04 MandrioliDamien  
TWikiWYSIWYGEditor-Manueldelutilisateur.pdf manage 152.0 K 10 Jun 2004 - 09:04 MandrioliDamien  
Signaturedesservicesweb.pdf manage 99.2 K 10 Jun 2004 - 09:07 MandrioliDamien  
service_tree.jpg manage 4.0 K 10 Jun 2004 - 09:36 MandrioliDamien  
BN1Rapport.doc manage 1201.5 K 10 Jun 2004 - 15:02 LamureMaxime Rapport final
BN1-Guidedinstallation.pdf manage 60.9 K 10 Jun 2004 - 11:05 MandrioliDamien Guide d'installation
BN1Rapport.pdf manage 764.5 K 10 Jun 2004 - 15:50 MandrioliDamien Rapport final + plannings
twe1.gif manage 40.1 K 15 Jun 2004 - 07:29 MandrioliDamien screenshot vue wysiwyg
twe2.gif manage 31.3 K 15 Jun 2004 - 07:31 MandrioliDamien screenshot vue html
twe3.gif manage 30.3 K 15 Jun 2004 - 07:31 MandrioliDamien screenshot vue syntaxe twiki

You are here: Minfo03 > TerBn1 > DocFinal

to top

Copyright © 1999-2019 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding WIKIDeptinfo? Send feedback