Guide du développeur de la bibliothèque numérique GreenstoneDavid Bainbridge, Dana McKay et Ian H. Witten Département d'informatique, Greenstone est une suite logicielle destinée à la construction et à la distribution de collections de bibliothèques numériques. Cette suite fournit une nouvelle manière d'organiser l'information et de la publier sur l'Internet ou sur un cédérom. Greenstone est produit par le projet de bibliothèque numérique de Nouvelle-Zélande (dépendant de l'université de Waikato), et distribué en coopération avec l'UNESCO et le projet de bibliothèques pour l'humanité. C'est un logiciel Open Source, qu'on peut obtenir à l'URL http://greenstone.org, et qui est diffusé selon les termes de la licence publique générale de GNU. Nous souhaitons nous assurer que ce logiciel fonctionne bien pour vous. Greenstone gsdl-2.50 Mars 2004 À propos de ce manuelCe manuel explique le fonctionnement de Greenstone. Il vise ceux qui souhaitent personnaliser des collections et développer ou maintenir le logiciel. La section 1 expose le processus de construction de collection vu de l'intérieur, comprenant la structure de répertoire, le format de document interne, et le fichier de configuration qui gouverne la structure de chaque collection. La section 2 décrit les parties de Greenstone qui traitent les documents source (et leurs méta-données) et dictent la manière dont on accède à l'information depuis l'interface utilisateur. Elle décrit également des composants logiciels «externes», distribués avec Greenstone. La section 3 explique la structure du système d'exécution de Greenstone, et donne aussi des détails du logiciel pour aider à comprendre son fonctionnement et comment le modifier pour correspondre à des besoins particuliers. La section 4 décrit les fichiers de configuration de Greenstone, et une annexe propose une introduction à la bibliothèque standard de patrons (templates) pour C++. Lors de votre travail avec le logiciel Greenstone, vous trouverez peut-être des références à des fonctionnalités qui ne sont pas décrites dans le présent manuel, car Greenstone est en perpétuel développement. Pour en savoir plus sur les travaux en cours, rejoignez la liste de diffusion de Greenstone (vous trouverez les instructions pour cela sur le site webgreenstone.org). Documents d'accompagnementL'ensemble des documents de Greenstone comprend cinq volumes:
CopyrightCopyright © 2002 2003 2004 2005 2006 2007 by the New Zealand Digital Library Project at the University of Waikato, New Zealand. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Documentation License.” RemerciementsLe logiciel Greenstone a vu le jour grâce à un effort de collaboration entre de nombreuses personnes. Rodger McNab et Stefan Boddie en sont les principaux architectes et développeurs. Des contributions ont été faites par David Bainbridge, George Buchanan, Hong Chen, Michael Dewsnip, Katherine Don, Elke Duncker, Carl Gutwin, Geoff Holmes, Dana McKay, John McPherson, Craig Nevill-Manning, Dynal Patel, Gordon Paynter, Bernhard Pfahringer, Todd Reed, Bill Rogers, John Thompson, et Stuart Yeates. D'autres membres du Projet de bibliothèque numérique de Nouvelle-Zélande ont également donné des conseils et inspiré les concepteurs du système: Mark Apperley, Sally Jo Cunningham, Steve Jones, Te Taka Keegan, Michel Loots, Malika Mahoui, et Lloyd Smith. Nous remercions aussi tous ceux qui ont contribué au développement des modules sous licence GNU GPL qui font partie de cette distribution: MG, GDBM, PDFTOHTML, PERL, WGET, WVWARE, XLHTML. Contents
1 Comprendre le processus de construction d'une collectionLes utilisateurs finals de Greenstone peuvent construire des collections à l'aide du Collector, décrit dans la section du Guide de l'utilisateur de la bibliothèque numérique Greenstone. Il facilite beaucoup la construction de collections sur le modèle de collections existantes, mais avec des contenus nouveaux. Cependant, il n'est pas réellement possible d'utiliser le Collector pour créer des collections avec des structures complètement nouvelles. Le Collector vous invite bien à éditer le fichier de configuration de la collection, qui gouverne cette structure de collection, mais il faut très bien connaître Greenstone pour pouvoir y effectuer des modifications radicales et efficaces. La présente section vous explique ce qu'il faut savoir pour opérer ainsi. Elle décrit également la structure de répertoire de Greenstone et le format interne de stockage des documents. Tout au long de ce manuel nous supposerons que vous avez installé Greenstone sur votre ordinateur, que ce dernier fonctionne sous Windows ou sous Unix. Si tel n'est pas encore le cas vous devriez consulter le Guide d'installation de la bibliothèque numérique Greenstone. Le nom GSDLHOME représentera le répertoire racine de Greenstone, qui s'appelle %GSDLHOME% sur des systèmes Windows et $GSDLHOME sur des systèmes Unix. On détermine ce répertoire pendant la procédure d'installation. 1.1 Construire des collections depuis la ligne de commandeCommençons par décrire pas à pas les opérations nécessaires pour construire une collection depuis la ligne de commande, ce qui facilitera la compréhension du processus. Bien sûr, c'est le Collector qu'il faut plutôt utiliser pour construire des collections de manière plus agréable. La collection que nous prenons en exemple est l'une des collections distribuées sur le cédérom du logiciel Greenstone, et elle contient les pages web personnelles de nombreux contributeurs au projet de bibliothèque numérique de Nouvelle-Zélande et au logiciel Greenstone. Les sections suivantes détaillent la construction sous Windows et sous Unix. En réalité, les deux se ressemblent presque complètement -- ne lisez que celle qui concerne votre système. Lorsque vous suivrez ces étapes, vous penserez peut-être que certaines opérations sont mystérieuses ou des arcanes, mais ne les en suivez pas moins fidèlement -- elles prendront tout leur sens plus tard. Suivra un bref résumé des différences entre les processus de construction sous les deux systèmes. Construire des collections sous WindowsLe premier défi lors de la construction d'une collection à la ligne de commande sous Windows, c'est de parvenir à l'«interpréteur de commandes», qui est l'endroit où l'on tape les commandes. Dans le menu Démarrer ou le sous-menu Programmes, recherchez une ligne Invite MS-DOS, Invite DOS, ou Interpréteur de commandes. Si vous ne trouvez rien de tel, invoquez l'entrée Exécuter et tentez de taper command (ou cmd) dans la boîte de dialogue qui va apparaître. Si rien de tout ceci ne fonctionne, faites-vous assister par une personne qui s'y connaît, telle que votre administrateur système. Rendez-vous dans le répertoire d'installation de Greenstone. En supposant que Greenstone a été installé dans l'emplacement standard, vous vous y rendrez en tapant: cd "C:\Program Files\gsdl "
Les apostrophes doubles sont nécessaires à cause de l'espace dans Program Files. Tapez ensuite à l'invite: setup.bat
Ce fichier de commandes (que vous pouvez lire si vous en avez la curiosité) explique au système où trouver les programmes de Greenstone[1]. Si lors de votre session à l'invite de commandes DOS, vous souhaitez revenir au répertoire racine de Greenstone, vous pourrez toujours ce faire en tapant cd "%GSDLHOME%" (ici encore, les apostrophes doubles sont nécessaires: elles sont dues à la présence d'espaces dans le nom de fichier). Si vous fermez votre fenêtre DOS et en ouvrez une autre, il faudra de nouveau invoquer le fichier setup.bat. Vous avez maintenant la possibilité de compiler, construire, et construire à nouveau des collections. Le premier programme que vous allons examiner est le programme Perl mkcol.pl, dont le nom signifie «make a collection» (compiler une collection). Commencez par exécuter le programme en tapant perl -S mkcol.pl pour obtenir à l'écran une description de la syntaxe et une liste des arguments possibles -- si votre environnement Windows est configuré de manière à associer l'application Perl aux fichiers se terminant en .pl, il vous suffira de taper mkcol.pl pour obtenir ce résultat. Comme vous pourrez le lire dans le message qui apparaît, l'unique argument obligatoire est creator, qui sert à spécifier qui a construit la collection. Utilisons cette commande pour créer les fichiers et sous-répertoires initiaux nécessaires à notre collection des pages personnelles des membres du projet de bibliothèque numérique Greenstone. Pour affecter à la collection le nom dlpeople («gens de la bibliothèque numérique» en anglais et en abrégé), j'ai tapé: perl —S mkcol.pl —creator [email protected] dlpeople
(on peut se contenter de tapermkcol.pl -creator [email protected] dlpeoplesi Perl est associé aux extensions de fichiers en.pl). N'oubliez pas de remplacer mon adresse électronique par la vôtre! Pour visualiser les fichiers nouvellement créés, on se déplace dans le répertoire de la collection en tapant: cd "%GSDLHOME%\collect\dlpeople "
Figure 1
Fichier de configuration de collection créé par mkcol.pl
On peut alors lister le contenu du répertoire en tapant dir. Il devrait s'y trouver sept sous-répertoires: archives, building, etc, images, import, index, et perllib. Il faut maintenant peupler la collection d'échantillons de documents. Les documents source de la collection dlpeople se trouvent sur le cédérom de la distribution Greenstone dans le répertoire collectdlpeople. Insérez d'abord le cédérom dans le lecteur (par exemple, sous D). Copiez ensuite le contenu du répertoire Dcollectdlpeople dans le répertoire import de la collection dlpeople. Vous pouvez procéder comme suit:
sélectionner le contenu du répertoire dlpeople, et le faire glisser dans le répertoire import de la collection dlpeople. Vous pouvez aussi taper la commande: xcopy /s d:\collect\dlpeople\* import
Dans le répertoire etc de la collection, on trouve un fichier appelé collect.cfg. Ouvrez-le dans votre éditeur de texte préféré -- edit est basique mais communément disponible. Il devrait ressembler à ce que présente la figure 1, qui montre le fichier de configuration de collection créé par la commande: Nous sommes désormais disposés à «importer» la collection. Il s'agit du processus qui apporte les documents dans le système Greenstone, en normalisant le format des documents, la manière dont les méta-données sont spécifiées, et la structure de fichiers de stockage des documents. Tapez perl -S import.pl à l'invite pour obtenir une liste de toutes les options du programme d'import. L'option -removeold s'assure que tout document préalablement importé est effacé dans un premier temps. perl —S import.pl -removeold dlpeople
Ne vous inquiétez pas du texte qui défile: il s'agit d'un compte-rendu de la progression de l'import. Sachez que l'import de cette collection prend environ cinq minutes sur une machine à 1 GHz, et d'autant plus longtemps sur des machines plus lentes. Vous remarquerez qu'il n'est pas besoin de se trouver dans les répertoires collect ou dlpeople lors de la saisie de cette commande: la variable GSDLHOME étant déjà positionnée, le logiciel Greenstone peut trouver tous les fichiers nécessaires. Modifions désormais quelque peu le fichier de configuration de la collection pour en personnaliser la représentation. Donnons d'abord un nom à la collection. Il sera utilisé par les navigateurs web en tant que page de titre pour la première page de la collection, et servira d'icone de collection si aucune image n'est fournie. Remplacez la lignecollectionmeta collectionname "dlpeople"par quelque chose commecollectionmeta collectionname "Les membres du projet NZDL"(NZDL est l'acronyme anglais du projet de bibliothèque numérique de Nouvelle-Zélande: New Zealand Digital Library Project). Ajoutez une description de votre collection entre les apostrophes doubles de la ligne collectionmeta collectionextra "". Elle servira de texte pour le paragraphe à propos sur la page d'accueil de la collection. J'ai personnellement ajouté: "Cette collection comprend les pages personnelles de certains membres du projet NZDL.". Il est important de saisir cette description sous la forme d'une seule ligne dans l'éditeur -- ne soyez pas tenté de revenir à la ligne si vous arrivez sur le bord droit de la fenêtre, mais continuez simplement à taper! -- sans quoi le fichier de configuration ne pourra pas être correctement analysé. Si vous souhaitez que votre collection puisse être utilisée avec différentes interfaces de langues, il est possible de faire en sorte que cette description dépende de la langue choisie: ce procédé est décrit dans la section 1.5, plus bas. On peut retenir toute image utilisable dans un navigateur web en tant qu'icone de collection -- l'image que j'ai créée est présentée figure 2. Tapez l'emplacement de l'image entre les apostrophes doubles de la lignecollectionmeta iconcollection ""du fichier de configuration. On peut utiliser le raccourci _httpprefix_ pour remplacer le début d'une URL qui pointe vers une image située dans la zone de fichiers de Greenstone. Cela rend également les configurations plus portables. Vous pouvez par exemple taper:_httpprefix_/collect/dlpeople/images/icon.gifsi vous avez placé une image convenable dans le répertoire images de la collection (collectdlpeopleimages dans l'exemple qui nous intéresse). Sauvegardez le fichier de configuration de la collection et refermez-le -- vous n'en aurez plus besoin au cours de ce didacticiel. La prochain étape consiste à «construire» la collection, ce qui crée tous les index et fichiers qui lui permettront de fonctionner. Tapez perl -S buildcol.pl à l'invite pour obtenir la liste des options de construction de collection. Ces options sont présentées plus en détails dans la section section 1.3. Pour l'instant, nous nous contenterons des valeurs par défaut en tapant: perl —S buildcol.pl dlpeople
à l'invite. Ici non plus, ne vous inquiétez pas en voyant défiler le compte-rendu de progression. «Activez» la collection comme suit: sélectionnez le contenu du répertoire building de la collection dlpeople, et faites-le glisser dans le répertoire index. Vous pouvez aussi effacer le répertoire index (et tout ce qu'il contient) en tapant la commande: rd /s index # on Windows NT/2000
deltree /Y index # on Windows 95/98
et rebaptiser ensuite le répertoire building en index avec: ren building index
Enfin, tapez: mkdir building
en vue de futures reconstructions. Il est important de taper ces commandes dans le bon répertoire (à la différence des commandes mkcol.pl, import.pl et buildcol.pl de Greenstone). Si le répertoire actuel n'est pas dlpeople, tapez:cd "%GSDLHOME%\collect\dlpeople"avant de procéder à la séquence rd, ren, et mkdir donnée ci-dessus. Vous devriez pouvoir accéder à la collection nouvellement construite depuis la page d'accueil de Greenstone. Il vous faudra réactualiser ou recharger cette page si elle était déjà ouverte dans votre navigateur, voire fermer le navigateur et le redémarrer (pour éviter les problèmes de tampon ou cache). Il se peut aussi, dans le cas où vous utilisez la version «Bibliothèque locale» de Greenstone, que vous deviez redémarrer le programme library. Pour visualiser la nouvelle collection, cliquez sur l'image. Le resultat devrait alors ressembler à la figure 3.
Figure 2
Icone de collection
Si nous nous résumons, l'ensemble des commandes tapées pour produire la collection dlpeople sont: cd "C:\Program Files\gsdl " # assuming default location
setup.bat
perl —S mkcol.pl —creator [email protected] dlpeople
cd "%GSDLHOME%\collect\dlpeople "
xcopy /s d:\collect\dlpeople\* import # assuming D drive
perl —S import.pl dlpeople
perl —S buildcol.pl dlpeople
rd /s index # on Windows NT/2000
deltree /Y index # on Windows 95/98
ren building index
mkdir building
Construire des collections sous UnixCommencez par vous rendre dans le répertoire d'installation de Greenstone. Si par exemple Greenstone a été installé dans l'emplacement standard, dans votre répertoire personnel, vous vous y rendrez en tapant: cd ~/gsdl
Tapez ensuite à l'invite: source setup.bash # if you're running the BASH shell
source setup.csh # if you're running the C shell
Ces fichiers de commandes (que vous pouvez lire si vous en avez la curiosité) expliquent au système où trouver les programmes de Greenstone. Si lors de votre session à l'interpréteur de commandes, vous souhaitez revenir au répertoire racine de Greenstone, vous pourrez toujours ce faire en tapant cd $GSDLHOME. Si vous ignorez le type d'interpréteur de commandes que vous utilisez, tapez echo $0 à l'invite -- cela affichera l'information recherchée. Si vous utilisez un autre interpréteur de commandes, demandez conseil à votre administrateur système. Après avoir chargé le bon fichier de réglages, vous avez maintenant la possibilité de compiler, construire, et construire à nouveau des collections. Le premier programme que vous allons examiner est le programme Perl mkcol.pl, dont le nom signifie «make a collection» (compiler une collection). Commencez par exécuter le programme en tapant simplement mkcol.pl pour obtenir à l'écran une description de la syntaxe et une liste des arguments possibles. Comme vous pourrez le lire dans le message qui apparaît, l'unique argument obligatoire est creator, qui sert à spécifier qui a construit la collection.
Figure 3
Page «à propos» de la nouvelle collection
Utilisons cette commande pour créer les fichiers et sous-répertoires initiaux nécessaires à notre collection des pages personnelles des membres du projet de bibliothèque numérique Greenstone. Pour affecter à la collection le nom dlpeople («gens de la bibliothèque numérique» en anglais et en abrégé), j'ai tapé: mkcol.pl —creator [email protected] dlpeople
N'oubliez pas de remplacer mon adresse électronique par la vôtre! Pour visualiser les fichiers nouvellement créés, on se déplace dans le répertoire de la collection en tapant: cd $GSDLHOME/collect/dlpeople
On peut alors lister le contenu du répertoire en tapant ls. Il devrait s'y trouver sept sous-répertoires: archives, building, etc, images, import, index, et perllib. Il faut maintenant peupler la collection d'échantillons de documents. Les documents source de la collection dlpeople se trouvent sur le cédérom de la distribution Greenstone dans le répertoire collect/dlpeople. Pour lire des informations sur un cédérom depuis Linux, insérez le disque dans le lecteur et tapez mount /cdrom
à l'invite (cette commande peut varier d'un système à l'autre). Une fois monté, le cédérom peut s'utiliser comme tout autre répertoire; vous pouvez donc taper ls /cdrom/collect. Voilà qui devrait révéler un répertoire dlpeople sur le cédérom. Copiez ensuite le contenu du répertoire /cdrom/collect/dlpeople dans le répertoire GSDLHOME/collect/dlpeople/import. Pour ce faire, tapez la commande: cp —r /cdrom/collect/dlpeople/* import/
puis tapez umount /cdrom
pour fermer le lecteur de cédérom. Dans le répertoire etc de la collection, on trouve un fichier appelé collect.cfg. Ouvrez-le dans votre éditeur de texte préféré -- emacs est un éditeur populaire sous Linux.Il devrait ressembler à ce que présente la figure 1, qui montre le fichier de configuration de collection créé par la commande:mkcol.pl -creator [email protected] dlpeople Nous sommes désormais disposés à «importer» la collection. Il s'agit du processus qui apporte les documents dans le système Greenstone, en normalisant le format des documents, la manière dont les méta-données sont spécifiées, et la structure de fichiers de stockage des documents. Tapez import.pl à l'invite pour obtenir une liste de toutes les options du programme d'import. L'option -removeold s'assure que tout document préalablement importé est effacé dans un premier temps. import.pl —removeold dlpeople
Ne vous inquiétez pas du texte qui défile: il s'agit d'un compte-rendu de la progression de l'import. Sachez que l'import de cette collection prend environ cinq minutes sur une machine à 1 GHz, et d'autant plus longtemps sur des machines plus lentes. Vous remarquerez qu'il n'est pas besoin de se trouver dans les répertoires collect ou dlpeople lors de la saisie de cette commande: la variable GSDLHOME étant déjà positionnée, le logiciel Greenstone peut trouver tous les fichiers nécessaires. Modifions désormais quelque peu le fichier de configuration de la collection pour en personnaliser la représentation. Donnons d'abord un nom à la collection. Il sera utilisé par les navigateurs web en tant que page de titre pour la première page de la collection, et servira d'icone de collection si aucune image n'est fournie. Remplacez la lignecollectionmeta collectionname "dlpeople"par quelque chose commecollectionmeta collectionname "Les membres du projet NZDL"(NZDL est l'acronyme anglais du projet de bibliothèque numérique de Nouvelle-Zélande: New Zealand Digital Library Project). Ajoutez une description de votre collection entre les apostrophes doubles de la ligne collectionmeta collectionextra "". Elle servira de texte pour le paragraphe «à propos» sur la page d'accueil de la collection. J'ai personnellement ajouté: "Cette collection comprend les pages personnelles de certains contributeurs au projet NZDL.". Il est important de saisir cette description sous la forme d'une seule ligne dans l'éditeur -- ne soyez pas tenté de revenir à la ligne si vous arrivez sur le bord droit de la fenêtre, mais continuez simplement à taper! -- sans quoi le fichier de configuration ne pourra pas être correctement analysé. Si vous souhaitez que votre collection puisse être utilisée avec différentes interfaces de langues, il est possible de faire en sorte que cette description dépende de la langue choisie: ce procédé est décrit dans la section 1.5, ci-dessous. On peut retenir toute image utilisable dans un navigateur web en tant qu'icone de collection -- l'image que j'ai créée est présentée figure 2. Tapez l'emplacement de l'image entre les apostrophes doubles de la lignecollectionmeta iconcollection ""du fichier de configuration. On peut utiliser le raccourci _httpprefix_ pour remplacer le début d'une URL qui pointe vers une image située dans la zone de fichiers de Greenstone. Cela rend également les configurations plus portables. Vous pouvez par exemple taper:_httpprefix_/collect/dlpeople/images/icon.gifsi vous avez placé une image convenable dans le répertoire images de la collection (collect/dlpeople/images dans l'exemple qui nous intéresse). Sauvegardez le fichier de configuration de la collection et refermez-le -- vous n'en aurez plus besoin au cours de ce didacticiel. La prochain étape consiste à «construire» la collection, ce qui crée tous les index et fichiers qui lui permettront de fonctionner. Tapez buildcol.pl à l'invite pour obtenir la liste des options de construction de collection. Ces options sont présentées plus en détails dans la section section 1.3. Pour l'instant, nous nous contenterons des valeurs par défaut en tapant: buildcol.pl dlpeople
à l'invite. Ici non plus, ne vous inquiétez pas en voyant défiler le compte-rendu de progression. «Activez» la collection en déplaçant toutes les données qui viennent d'être placées dans le répertoire building vers le répertoire index. Si vous avez déjà construit cette collection de par le passé, commencez d'abord par enlever l'ancien répertoire index avec la commande: rm —r index/*
(en supposant que vous vous trouvez alors dans le répertoire dlpeople). Puis tapez mv building/* index/
Table 1
Différences entre Windows et Linux pour la construction de collections
Vous devriez pouvoir accéder à la collection nouvellement construite depuis la page d'accueil de Greenstone. Il vous faudra réactualiser ou recharger cette page si elle était déjà ouverte dans votre navigateur, voire fermer le navigateur et le redémarrer (pour éviter les problèmes de tampon ou cache). Pour visualiser la nouvelle collection, cliquez sur l'image. Le resultat devrait alors ressembler à la figure 3. Si nous nous résumons, l'ensemble des commandes tapées pour produire la collection dlpeople sont: cd ~/gsdl # assuming default Greenstone in home directory
source setup.bash # if you're running the BASH shell
source setup.csh # if you're running the C shell
mkcol.pl —creator [email protected] dlpeople
cd $GSDLHOME/collect/dlpeople
mount /cdrom # assuming this is where CD-ROM is mapped to
cp —r /cdrom/collect/dlpeople/* import/
umount /cdrom
import.pl dlpeople
buildcol.pl dlpeople
rm -r index/*
mv building/* index
Différences entre Windows et UnixLes processus de construction de collection sont très similaires sous Unix et sous Windows, mais quelques petites différences demeurent, différences que nous avons résumées dans la table 1. 1.2 Les répertoires de GreenstoneLa figure 4 montre la structure du répertoire GSDLHOME. La table 2 donne une brève description du contenu de chacun des répertoires représentés dans le diagramme. Certains répertoires seront plus détaillés plus loin dans le manuel -- utilisez le guide des sections de la table 2 pour savoir où aller chercher des informations supplémentaires.
Figure 4
Structure du répertoire GSDLHOME
Table 2
Où trouver de l'information à propos des répertoires
1.3 Les processus d'import et de constructionDans le processus de construction de collection décrit à la section 1.1, on utilise une commande pour importer des documents (import.pl) et une autre commande pour construire la collection (buildcol.pl). Nous détaillons dans la présente section ce que ces programmes font et les options qu'ils acceptent. Nous utiliserons la variable nom_col pour nous référer à la collection en cours de construction ou d'import. Les processus d'import et de construction sont très similaires, ce qui explique le nombre d'options communes qu'ils comptent, options décrites dans la table 3 (souvenez-vous que pour obtenir la liste des options acceptées par tout script Greenstone, il suffit de taper son nom seul, sans argument, à l'invite de commandes).
Table 3
Options des processus d'import et de construction
Le processus d'importLe processus d'import a pour but principal de convertir les documents depuis leur format d'origine vers le format d'archivage de Greenstone utilisé de manière interne par Greenstone, et d'écrire un fichier de compte-rendu (archives.inf) qui sera utilisé lors de la construction de la collection. Le programme import.pl a besoin de connaître les greffons (plugins) à utiliser, et de savoir où trouver les fichiers des documents originaux. La table 3 montre les options communes aux processus d'import et de construction; la table 4 montre les options propres au processus d'import. L'option OIDtype mérite quelques explications. Chaque document dispose d'un identifiant d'objet associé, ou OID (Object IDentifier). La meilleure façon de calculer un tel identifiant est de calculer une somme de contrôle («hacher») le contenu du document (c'est la méthode hash). Cependant, cette méthode étant lente, il est possible de choisir une solution plus simple, incrémentale, qui se contente de numéroter les documents séquentiellement dans leur ordre de fourniture (c'est la méthode incremental). Vous pouvez utiliser la méthode incremental pour aller plus vite, mais utilisez la méthode hash si vous avez l'intention d'ajouter des documents à votre collection plus tard, sans recommencer tout le processus d'import.
Table 4
Options propres au processus d'import
Figure 5
Étapes du processus d'import
La figure 5 représente le processus d'import tel qu'implémenté par le programme import.pl. Chaque ovale représente un module utilisé pour mener à bien les tâches relatives à une partie spécifique du système Greenstone. On peut trouver tous ces modules dans le répertoire GSDLHOME/perllib. Pour l'étape 3, remarquez que des variables d'import telles que importdir et archivedir peuvent être positionnées dans le fichier de configuration de la collection ou depuis la ligne de commande. Si elles sont positionnées dans la ligne de commande, toute valeur spécifiée dans le fichier de configuration sera ignorée. L'étape 6 voit la création du fichier d'information d'archives (archives.inf). L'étape 7 crée un objet qui saura où sauvegarder les documents, et qui suivra toute instruction particulière de sauvegarde (telle que sortmeta, qui trie les documents selon une balise de méta-données spécifiée). La plupart du travail effectué par le processus d'import est en fait accompli par les greffons (plugins), qui sont appelés par le module plugin. Ce module met en place un pipe-line des greffons spécifiés dans le fichier de configuration de collection. Il gère aussi l'écriture des documents d'archive de Greenstone (en utilisant un objet document). Le processus de constructionLors du processus de construction le texte est compacté, et les index de corps du texte spécifiés dans le fichier de configuration de collection sont créés. De plus, les informations relatives à la collection qui apparaîtront sur le web sont pré-calculées et incorporées dans la collection -- il s'agit par exemple des informations relatives aux icones et aux titres, ainsi que des informations produites par des classificateurs. Le programme buildcol.pl partage de nombreuses options avec import.pl; elles sont détaillées dans la table 3. La table 5 présente les options qui lui sont propres.
Table 5
Options propres au processus de construction
Figure 6
Étapes du processus de construction
Le diagramme de la figure 6 représente l'exécution du programme buildcol.pl. De nombreuses étapes sont communes avec le processus d'import. La première étape qui diffère est l'étape 4 (à gauche sur la figure). Cette étape n'est effectuée que si l'option create_images a été activée. Les images sont alors créées et consignées dans le fichier de configuration de collection à l'aide d'une fonction du script buildcol.pl. Pour que ceci fonctionne correctement, il faut avoir installé et configuré convenablement GIMP (GNU Image-Manipulation Program, programme de manipulation d'images de GNU) et le module Perl Gimp. Il faut aussi disposer d'un accès en écriture (et en lecture) sur le fichier de configuration de collection. L'étape 5 contrôle d'abord l'existence ou non d'une procédure de construction propre à la collection. Certaines collections impliquent des traitements particuliers au moment de la construction, auquel cas il faut écrire un constructeur propre à la collection et le placer dans son répertoire perllib, sous le nom de la collection auquel on aura concaténé la chaîne «builder» (constructeur). Les constructeurs propres aux collections héritent de mgbuilder. Dans l'étape 5 le constructeur (qu'il s'agisse du constructeur par défaut ou d'un constructeur propre à la collection) est initialisé avec des informations telles que le nombre de documents à inclure, s'il faut ou non garder l'ancienne version de la collection, et où les répertoires building et archive sont localisés. L'étape 6 est l'étape de construction, au cours de laquelle le texte des documents est compacté et indexé, les titres et les icones de collection sont stockés dans la base de données d'informations de la collection, et les structures de données sont construites pour supporter les classificateurs appelés par les greffons (plugins) de la collection. Toutes ces étapes sont menées à bien par mgbuilder (ou un constructeur propre à la collection), qui lui-même utilise MG (Managing Gigabytes (gérer les giga-octets), voir Wittenet al., 1999), logiciel de compression et d'indexation. L'option mode permet de spécifier les portions de collection à construire, mais par défaut tout est construit: texte compacté, index, et base de données d'informations de la collection. Pour publier une collection sur le web après construction, il faut la déplacer du répertoire building vers le répertoire index. Les collections ne sont pas construites directement dans le répertoire index car des collections volumineuses peuvent prendre plusieurs heures ou jours à construire. Il est important que le processus de construction n'affecte pas une copie existante de la collection tant qu'il n'est pas terminé. 1.4 Documents d'archives de GreenstoneTous les documents source sont importés dans le système Greenstone après conversion dans le format d'archivage de Greenstone. C'est un style XML qui divise les documents en sections, et qui peut renfermer des méta-données au niveau du document ou de chaque section. Vous ne devriez pas avoir à créer des fichiers d'archives de Greenstone manuellement -- c'est le travail des greffons (plugins) de traitement de documents décrits dans le chapitre suivant. Il est cependant utile de comprendre le format des fichiers Greenstone, et c'est pourquoi nous le décrivons ici. En XML, les mots-clefs sont entourés de chevrons pour le balisage. Le format d'archivage de Greenstone encode des documents déjà en HTML, et tout caractère <, >, ou " compris dans le texte original est échappé grâce à la convention standard <, >, et ".
Figure 7
(a)
Format d'archivage de Greenstone: (a) définition de type de document (DTD); (b) document d'exemple
Figure 7
(b)
La première partie de la figure 7a donne la définition de type de document (DTD) pour le format d'archivage de Greenstone. Pour simplifier, un document est divisé en éléments Section, et les sections peuvent être imbriquées. Chaque Section renferme une Description qui comprend zéro ou plusieurs éléments Metadata (méta-données), et un élément Content (contenu), qui peut être vide, et qui renferme les données du document à proprement parler. À chaque élément Metadata on associe un attribut de nom (dont le nom est libre), et des données textuelles. En XML, PCDATA signifie «parsed character data» (données de type caractère analysées), c'est-à-dire du texte, tout simplement. La deuxième partie de la figure 7b montre un document simple écrit dans ce format, qui est un petit livre avec deux images associées. Le livre consiste en deux sections appelées respectivement Préface et Premier et unique chapitre, la deuxième section se divisant en deux sous-sections. Remarquez qu'il n'existe aucune notion de «chapitre» en tant que tel: un chapitre est simplement représenté comme une section de premier niveau.
Table 6
Format d'archivage de Greenstone: valeurs pour l'attributnamede la baliseMetadata
La balise <Section> dénote le début de chaque section de document, et la balise fermante correspondante (</Section>) marque la fin de cette section. À la suite de chaque balise <Section> on trouve un élément <Description>. S'y trouve un nombre quelconque d'éléments <Metadata>. On peut ainsi associer différentes méta-données à différentes sections du document. La plupart de ces méta-données sont des types particuliers de méta-données tels que <Title> (titre). Les deux valeurs de l'attribut name (nom) montrées dans la table 6 reçoivent de Greenstone un traitement particulier; toutes les autres sont considérées comme des méta-données attachées à cette section. Dans certaines collections les documents dont divisés en pages. Ces dernières sont alors traitées comme des sections. Un livre peut par exemple disposer de sections de premier niveau qui correspondent à des chapitres, au sein desquels on trouvera un certain nombre de «sections» qui correspondront en réalité aux différentes pages du chapitre. Méta-données de documentLes méta-données sont des informations de description associées à un document telles que l'auteur, le titre, la date, des mots-clefs, etc. Nous avons déjà signalé que les méta-données étaient stockées avec les documents. En observant la figure 7a, on remarque que les balises <Metadata> spécifient le nom du type de méta-données, et lui donnent une valeur. On a par exemple la ligne <Metadata name="Title">Premier et unique chapitre</Metadata> dans la deuxième partie de la figure 7b -- le titre d'un document est une méta-donnée qui lui est associée. On utilise le standard de méta-données Dublin Core pour définir des types de méta-données (Dublin Core, 2001; Weibel, 1999; Thiele, 1997). La table 7 montre les types disponibles dans le standard, les étoiles signalant les entrées disponibles à ce jour sur le site web de la bibliothèque numérique de Nouvelle-Zélande. Si aucun type ne décrit correctement un certain type de méta-données, on peut aussi utiliser des types de méta-données absentes du standard Dublin Core. La collection «Demo» contient par exemple les méta-données how to (comment faire) et Magazine.
Table 7
Standard de méta-données
Au coeur des documents d'archive de GreenstoneLe format d'archivage de Greenstone impose peu de structure aux documents individuels. Les document sont divisés en paragraphes. Ils peuvent être divisés hiérarchiquement en sections et en sous-sections, que l'on peut imbriquer jusqu'à une profondeur arbitraire. À chaque document est associé un identifiant de document ou OID -- ces derniers servant aussi à identifier les sections et les sous-sections par l'ajout de numéros de sections et de sous-sections, séparés par des points, à l'OID du document. On se référera par exemple à la sous-section 3 de la section 2 du document HASHa7 sous la forme HASHa7.2.3. Quand on lit un livre dans une collection de Greenstone, la hiérarchie des sections est reportée dans la table des matières du livre. Les livres de la collection «Demo», par exemple, disposent d'une table des matières hiérarchique qui montre des chapitres, des sections, et des sous-sections, comme l'illustre la figure 8a. Les documents de la collection Computer Science Technical Reports (rapports techniques en informatique) ne disposent pas d'une structure hiérarchique de sections, mais chaque document est divisé en pages et on peut naviguer parmi les pages d'un document rapatrié. Les chapitres, les sections, les sous-sections, et les pages sont tous simplement implémentés en tant que «sections» au sein du document.
Figure 8
(a)
Structure hiérarchique de la collection «Demo»
Figure 8
(b)
Structure hiérarchique de la collection «Demo»
La structure de document sert aussi aux index de recherche. Il existe trois niveaux possibles d'index:document,section, etparagraphe, bien que la plupart des collections ne les utilisent pas tous trois. Un index dedocumentcontient tout le document -- on peut l'utiliser pour trouver tous les documents contenant un ensemble particulier de mots (qui peuvent alors être éparpillés tout au long du document, loin les uns des autres). Lors de la création d'un index desection, toute portion de texte indexée s'étend d'une balise ouvrante <Section> à la prochaine balise <Section> -- un chapitre qui débute immédiatement par une autre section créera donc un document vide dans l'index. Les sections et les sous-sections sont traitées de la même manière: la structure hiérarchique de document est aplatie dans le but de créer des index de recherche. Les index deparagrapheconsidèrent chaque paragraphe comme un document à part entière, et sont utiles pour mener des recherches plus ciblées. Le menu déroulant de la figure 8b montre les index de recherche de la collection «Demo». Les chapitres et les titres des sections sont des index au niveau de la section. alors que les livres entiers représentent des index au niveau des documents. À l'instar des index de texte, on peut créer des index pour tout type de méta-données. Certaines collections proposent par exemple des exemples des titres de sections, comme illustré sur la figure 8b. 1.5 Fichier de configuration de la collectionLe fichier de configuration de la collection gouverne la structure de la collection telle qu'elle est vue par l'utilisateur, ce qui permet d'en personnaliser l'apparence et l'ergonomie, ainsi que la manière dont ses documents sont traités et présentés. Le programme mkcol.pl crée un fichier de configuration de collection simple, en enregistrant votre adresse de courrier électronique en tant que créateur et mainteneur. Nous avons vu lors de l'exploration pas à pas du processus en ligne de commande que le créateur est un argument obligatoire, et il sera également enregistré en tant que mainteneur sauf si on fournit cette information séparément.
Table 8
Éléments du fichier de configuration de la collection
Chaque ligne du fichier de configuration de collection est sur le modèle de la paire «attribut, valeur». Chaque attribut donne une information sur la collection qui affecte la manière dont elle sera représentée ou dont les documents seront traités. La table 8 montre les éléments que l'on peut inclure dans un fichier de configuration de collection, et à quoi sert chaque élément. En plus de ceux-ci, on peut aussi spécifier toutes les options de ligne de commande des programmes import.pl et buildcol.pl dans un fichier de configuration de collection. Par exemple, une ligne disant no_text true (true signifie «vrai» ou «activé» dans ce contexte) positionnera l'option no_text du programme buildcol.pl. Le fichier de configuration de collection créé par le script mkcol.pl et présenté table 9, est très simple et ne contient que le strict minimum d'informations. Les lignes 1 et 2 proviennent de la valeur de creator fournie au programme mkcol.pl, et renferment les adresses de courrier électronique des responsables de la création et de la maintenance de la collection (qui peuvent être distincts).
Table 9
Fichier de configuration de collection créé parmkcd.pl
La ligne 3 indique si la collection sera accessible au public après construction, et peut prendre les valeurs true (valeur par défaut, qui signifie que la collection sera publiquement disponible), ou false (qui signifie que cela ne sera pas le cas). C'est utile lorsque l'on construit des collections pour tester le logiciel, ou pour usage personnel. La ligne 4 indique si la collection est une version bêta ou non (la valeur par défaut ici aussi est true, ce qui signifie que la collection est une version bêta). La ligne 5 détermine les index de collection à créer au moment de la construction: dans cet exemple, seul le texte du document sera indexé. Il existe trois niveaux possibles d'index:document,section, etparagraphe(paragraph en anglais). Ils peuvent contenir les données au format texte (text) ou dans toute méta-donnée -- la plus commune est le titre (Title). On spécifie un index en précisant niveaudonnées. Par exemple, pour inclure également un index des titres de sections, il faudrait remplacer la ligne 5 par indexes documenttext sectionTitle. On inclut plusieurs types de données dans le même index en les séparant par des virgules. Pour créer par exemple un index au niveau de la section de titres, de texte et de dates, il faudrait avoir en ligne 5 indexes sectiontext,Title,Date. Le defaultindex défini en ligne 6 est l'index à utiliser par défaut sur la page de recherche de la collection. Les lignes 7 à 13 spécifient les greffons (plugins) à utiliser lors de la conversion de documents vers le format d'archivage de Greenstone et lors de la construction de collections depuis des fichiers d'archives. La section 2.1 détaille les greffons disponibles. L'ordre dans lequel les greffons sont listés est l'ordre dans lequel ils sont appliqués sur chaque document. Dès qu'un greffon a été capable de traiter un document, les suivants de la liste ne sont pas appelés. La ligne 14 spécifie qu'il faudra créer une liste alphabétique des titres à des fins de navigation. Les structures de navigation sont construites par des «classificateurs». La section 2.2 détaille les classificateurs et leurs possibilités. Les lignes 15 à 18 servent à spécifier les méta-données au niveau de la collection. L'attribut collectionname définit la forme longue du nom de la collection, qui sera utilisée en tant que «titre» pour le navigateur web. L'attribut collectionicon donne l'URL de l'icone de la collection. Si comme ligne 18 on spécifie un index, la chaîne suivante sera affichée comme le nom de cet index sur la page de recherche de la collection. Une méta-donnée au niveau de la collection particulièrement importante est collectionextra, qui fournit un texte, entouré d'apostrophes doubles, décrivant la collection. Il servira de texte pour le paragraphe «à propos». On peut fournir différentes versions de l'attribut collectionextra pour différentes langues d'interface en ajoutant une spécification de langue entre crochets. Par exemple,
collectionmeta collectionextra "collection description"
collectionmeta collectionextra [l=fr] "description en français"
collectionmeta collectionextra [l=mi] "description en maori" Si la langue d'interface est positionnée à «fr» ou «mi», la version appropriée de la description sera affichée. Pour d'autres langues c'est la version par défaut qui apparaîtra. Ce fichier de configuration de collection simple ne fournit aucun exemple de chaîne de formatage, ni des possibilités de sous-collection et de langue proposées par le fichier de configuration. Les chaînes de format seront couvertes plus en détail dans la section 2.3, mais nous traiterons des sous-collections et des langues ici-même. Sous-collectionsGreenstone permet de définir des sous-collections et de construire des index séparés pour chacune d'entre elles. Une collection comprend par exemple un sous-ensemble important de documents appelé Food and Nutrition Bulletin (bulletin de la nourriture et de la nutrition). Nous l'utiliserons en tant qu'exemple. Cette collection compte trois index, tous trois au niveau de la section: le premier pour toute la collection, le deuxième pour le Food and Nutrition Bulletin, et le troisième pour les documents restants. On peut lire ci-après les lignes concernées du fichier de configuration de collection: indexes section:text
subcollection fn "Title/^Food and Nutrition Bulletin/i "
subcollection other "!Title/^Food and Nutrition Bulletin/i "
indexsubcollections fn other fn,other
Les lignes deux et trois définissent des sous-collections appelées fn, qui contiendra les documents du Food and Nutrition Bulletin, et other, qui contiendra les documents restants. Le troisième champ de ces définitions est une expression rationnelle de Perl qui identifie ces sous-ensembles en utilisant la méta-donnée Title: on recherche des titres qui commencent par Food and Nutrition Bulletin dans le premier cas, et les titres qui ne commencent pas ainsi dans le second (remarquez le "!" de négation). L'i final rend la reconnaissance de motif indépendante de la casse: majuscules et minuscules seront confondues. Le champ de méta-données, qui dans le cas présent est Title, peut être n'importe quel champ valide, ou Filename (nom de fichier) pour reconnaître le nom de fichier original du document. La quatrième ligne, indexsubcollections, spécifie trois index: un pour la collection fn, un pour la sous-collection other, et le troisième pour les deux sous-collections (c'est-à-dire pour tous les documents). Remarquez que si deux entrées avaient été spécifiées sur la première ligne, indexes, le nombre total d'index générés aurait été de six et non pas de trois. Si une collection contient des documents dans des langues différentes, on peut construire des index séparés pour chaque langue. La langue est une méta-donnée; les valeurs sont spécifiées à l'aide des codes en deux lettres du standard ISO 639 représentant les noms des langues -- par exemple, en est l'anglais, fr le français, zh le chinois, et mi le maori. Étant donné que l'on peut spécifier des valeurs de méta-données au niveau de la section, on peut avoir certaines portions de documents dans des langues différentes. Si par exemple le fichier de configuration contenait indexes section:text section:Title document:text paragraph:text
languages en zh mi
les index de texte de sections, de titres de sections, de texte de document et de texte de paragraphe seraient créés en anglais, en chinois, et en maori -- pour un total de douze index. Si on ajoute quelques sous-collections, voilà qui augmente d'autant le nombre d'index, et d'une multiplication! Il faut prendre garde à la surenchère des index. (On pourrait obtenir une telle spécification d'index avec subcollection plutôt qu'avec la fonctionnalité languages. Mais la syntaxe excluant la création de sous-collections de sous-collections, il serait alors impossible d'indexer chaque langue séparément dans chaque sous-collection.) Recherche inter-collectionsGreenstone propose une fonctionnalité de recherche transverse aux collections, qui permet d'effectuer une recherche parmi plusieurs collections à la fois, et de combiner les résultats en coulisses de manière à donner à l'utilisateur l'impression qu'il a mené sa recherche dans une unique collection unifiée. On peut rechercher tout sous-ensemble de collections: la page de Préférences laisse choisir quelles collections inclure dans les recherches. On active la recherche inter-collections par une ligne supercollection col _1 col _2 ….
où les collections impliquées sont appelées col_1, col_2, ... La même ligne devrait apparaître dans les fichiers de configuration de toutes les collections impliquées. 2 Exploitez vos documents au maximumOn peut individualiser les collections pour rendre accessibles les informations qu'elles contiennent de diverses manières. Le présent chapitre décrit la manière dont Greenstone extrait l'information des documents et la présente à l'utilisateur: le traitement des documents (section 2.1), les structures de classification (section 2.2), et les outils d'interface utilisateur (sections 2.3 et 2.4). 2.1 Greffons (plugins)Les greffons analysent les documents importés et en extraient les méta-données. Par exemple, le greffon HTML convertit des pages HTML en format d'archivage de Greenstone et extrait les méta-données explicites dans le format de document -- telles que les titres, entourés de balises <title></title>. Les greffons sont écrits en Perl. Ils sont tous inspirés d'un greffon de base appelé BasPlug, qui effectue les opérations partout nécessaires, telles que créer un nouveau document d'archive de Greenstone avec lequel travailler, affecter un identifiant d'objet (OID), et gérer les sections d'un document. Les greffons se trouvent dans le répertoire perllib/plugins. Pour en savoir plus sur un greffon particulier, tapezpluginfo.pl nom-de-greffonà l'invite de commandes (il vous faudra d'abord invoquer le script de réglages approprié si vous ne l'avez pas encore fait, et sous Windows il vous faudra taper perl -S pluginfo.pl plugin-name si votre environnement n'est pas réglé pour associer les fichiers se terminant en .pl à l'interpréteur Perl). Ceci affichera des informations relatives au greffon à l'écran -- les options spécifiques qu'il accepte, et quelles options générales sont autorisées. On peut facilement écrire de nouveaux greffons qui traitent des formats de documents non couverts par les greffons existants, mettent les documents en forme d'une manière particulière, ou extraient un nouveau type de méta-données. Options généralesLa table 10 montre les options acceptées par tout greffon héritant de BasPlug.
Table 10
Options valables pour tous les greffons
Greffons de traitement de documents
Table 11
Greffons (plugins) de Greenstone
Les greffons de traitement de documents sont utilisés par le logiciel de construction de collection pour analyser chaque document source d'une manière qui dépend de son format. Le fichier de configuration d'une collection liste tous les greffons utilisés lors de sa construction. Lors de l'opération d'import, chaque fichier ou chaque répertoire est passé tour à tour à tous les greffons jusqu'à ce qu'un greffon soit trouvé qui puisse traiter l'objet -- c'est pourquoi les premiers greffons listés ont la priorité sur des greffons apparaissant plus tard dans la liste. Si aucun greffon ne peut traiter le fichier, un avertissement est affiché (sur la sortie d'erreur standard) et le traitement passe au fichier suivant (c'est pourquoi l'option block_exp peut être utile -- pour éviter ces messages d'erreur dans le cas de fichiers qui sont peut-être présents mais n'ont pas besoin d'être traités). Lors de la construction, on utilise la même procédure, mais c'est le répertoire archives qui est traité en lieu et place du répertoire import. Les greffons standard de Greenstone sont listés table 11. Il est nécessaire d'utiliser un processus récursif pour traverser des hiérarchies de répertoires. Bien que les programmes d'import et de construction n'effectuent pas de récursion explicite, certains greffons provoquent une récursion indirecte en passant des noms de fichiers ou de répertoires dans le pipe-line des greffons. Par exemple, la manière habituelle d'opérer récursivement à travers une hiérarchie de répertoire est de spécifier RecPlug, qui travaille exactement ainsi. S'il est présent, il devrait être en dernière position dans le pipe-line. Seuls les deux premiers greffons de la table 11 provoquent une récursion indirecte. Certains greffons sont écrits pour des collections spécifiques, avec un format de document que l'on ne trouve nulle part ailleurs, tel que le texte électronique utilisé dans la collection Gutenberg. Ces greffons spécifiques à une collection se trouvent dans le répertoire perllib/plugins de la collection. On peut utiliser des greffons spécifiques à une collection pour remplacer des greffons généraux portant le même nom, qui ne seront alors pas appelés. Certains greffons de traitement de documents utilisent des programmes externes qui analysent des formats de fichiers propriétaires spécifiques -- tel que par exemple Microsoft Word -- et les transforment en texte brut ou en HTML. Un greffon général appelé ConvertToPlug invoque le programme de conversion approprié et en passe le résultat aux greffons TEXTPlug ou HTMLPlug. Nous décrirons cette opération plus en détail sous peu. Certains greffons disposent d'options individuelles, qui les contrôlent de manière plus fine que ce que permettent les options générales. C'est la table 12 qui décrit ces options individuelles.
Table 12
Options propres aux greffons
Greffons d'import de formats propriétairesLes formats propriétaires posent des problèmes difficiles pour tout système de bibliothèque numérique. Bien qu'ils soient parfois documentés, ils sont susceptibles de changer sans préavis, et il est difficile de suivre le rythme des changements. Greenstone a fait le choix d'utiliser des outils de conversion publiés selon les termes de la GPL (licence publique générale de GNU) par des gens focalisés sur telle ou telle tâche de conversion. Les outils pour convertir les formats Word et PDF sont inclus dans le répertoire packages. Tous convertissent des documents au format texte ou au format HTML. Les greffons HTMLPlug et TEXTPlug prennent ensuite la relève et convertissent ce résultat intermédiaire au format d'archivage de Greenstone. C'est ConvertToPlug qui est utilisé pour inclure les outils de conversion. BasPlug n'est jamais appelé directement, mais les greffons traitant des formats particuliers en héritent, comme illustré figure 9. ConvertToPlug utilise le système d'héritage dynamique de Perl pour hériter soit de TEXTPlug soit de HTMLPlug, selon le format dans lequel le document source a été converti.
Figure 9
Hiérarchie d'héritage des greffons (plugins)
Quand ConvertToPlug reçoit un document, il appelle gsConvert.pl (qui se trouve dans le répertoire GSDLHOME/bin/script) pour invoquer l'outil de conversion approprié. Après conversion, le document est renvoyé vers le greffon ConvertToPlug, qui invoque ensuite le greffon texte ou HTML, selon les cas. Tout greffon héritant de ConvertToPlug dispose d'une option convert_to (convertit vers), dont l'argument est soit text (texte) soit html, pour spécifier le format intermédiaire préféré. Le format texte est plus rapide, mais le format HTML rend mieux en général, et comprend des images. Il existe parfois plusieurs outils de conversion pour traiter un format particulier, et le programme gsConvert peut en essayer plusieurs sur un document donné. Par exemple, l'outil habituel de conversion du format Work, wvWare, ne traite pas les formats antérieurs à Word 6, et c'est un programme appelé AnyToHTML, qui se contente d'extraire toutes les chaînes de texte qu'il peut trouver, qui est appelé pour convertir les documents au format Word 5. Voici les étapes nécessaires pour ajouter un nouvel outil externe de conversion de document:
Affecter des méta-données à partir d'un fichierLe greffon standard RecPlug incorpore également une méthode pour positionner des méta-données dans les documents de manière manuelle (ou automatique) à partir de fichiers XML créés manuellement (ou automatiquement). Nous détaillons quelque peu ceci, de manière que vous puissiez créer des fichiers de méta-données dans le format approprié. Si l'option use_metadata_files est précisée, RecPlug utilise un fichier de méta-données auxiliaire, metadata.xml. La première partie de la figure 10a illustre la définition de type de document (DTD) XML pour le format du fichier de méta-données, et la deuxième partie de la figure 10b montre un exemple de fichier metadata.xml.
Figure 10
(a)
Format XML: (a) Définition de type de document (DTD); (b) Fichier de méta-données d'exemple
Figure 10
(b)
Le fichier d'exemple contient deux structures de méta-données. Dans chacune, l'élément filename décrit les fichiers auxquels les méta-données s'appliquent, sous la forme d'une expression rationnelle. <FileName>nugget.*</FileName> indique ainsi que le premier enregistrement de méta-données s'applique à tous les fichiers dont le nom commence par «nugget»[2]. Pour ces fichiers, la méta-donnée Title vaudra «Phare de Nugget Point». Les éléments de méta-données sont traités dans l'ordre dans lequel ils apparaissent. La deuxième structure de la figure 10 positionne la méta-donnée Title pour le fichier nugget-point-1.jpg à la valeur «Phare de Nugget Point, Catlins», en écrasant la spécification précédente. Elle ajoute également un champ Subject dans les méta-données. Parfois, les méta-données sont multi-valuées et les nouvelles valeurs devraient s'accumuler au lieu d'écraser les précédentes. L'attribut mode=accumulate a cet effet. Il est appliqué à la méta-donnée Place (lieu) dans la première spécification de la figure 10, cette méta-donnée sera donc multi-valuée. Pour revenir à une méta-donnée simple, écrivez<Metadata name="Place" mode="override">Nouvelle-Zélande</Metadata>En fait, on peut négliger de préciser cette spécification de mode puisque tout élément écrase le précédent par défaut, sauf indication contraire. Pour accumuler les méta-données dans un champ particulier, il faut préciser mode=accumulate à chaque occurrence. Quand son option use_metadata_files est activée, le greffon RecPlug recherche dans chaque répertoire en entrée un fichier XML appelé metadata.xml et applique son contenu à tous les fichiers et sous-répertoires du répertoire courant. Le mécanisme metadata.xml instancié dans le greffon RecPlug n'est qu'une manière de spécifier des méta-données pour des documents. Il est facile d'écrire des greffons différents qui accepteront des spécifications de méta-données dans des formats complètement différents. Baliser les fichiers de documentsIl faut souvent structurer les documents source en sections et sous-sections, et donc communiquer cette information à Greenstone de manière qu'il puisse reproduire la structure hiérarchique du document. On peut aussi associer à chaque section et sous-section des méta-données, et en particulier un titre. La manière la plus simple de procéder est souvent d'éditer les fichiers source, tout simplement. Le greffon HTML dispose d'un option description_tags qui traite les balises dans le texte comme suit: <!--
<Section>
<Description>
<Metadata name="Title"> Realizing human rights for poor people: Strategies for achieving the international development targets</Metadata>
</Description>
-->
(texte de la section) <!--
</Section>
-->
On utilise les marqueurs<!-- ... -->car ils dénotent des commentaires en HTML; ces balises de section n'auront donc aucun impact sur la mise en forme du document. On peut spécifier d'autres types de méta-données dans la portion Description, mais ce n'est pas le cas du style de collection décrit ici. On peut aussi imbriquer des balises, de telle sorte que la ligne(texte de la section)ci-dessus peut elle-même inclure des sous-sections, telles que (texte de la première partie de la section) <!--
<Section>
<Description>
<Metadata name="Title"> The international development targets</Metadata>
</Description>
-->
(texte de la sous-section) <!--
</Section>
-->
(texte de la dernière partie de la section) Cette fonctionnalité est héritée par tout greffon utilisant HTMLPlug. En particulier, le greffon Word convertit les données qu'il reçoit au format HTML: on peut donc procéder exactement de la même manière pour spécifier des méta-données dans les fichiers Word (et RTF). Ceci implique un peu de travail en coulisses, puisque lors de la conversion de documents Word vers HTML, le programme prend soin, normalement, de neutraliser les caractères significatifs pour HTML, tels que<et>; nous nous sommes arrangés pour contourner cette neutralisation dans le cas des spécifications mentionnées ci-dessus. Il faut alors utiliser exactement le même format, même dans des fichiers Word, et ne pas oublier les<!--et-->qui entourent les méta-données. Le choix des polices et l'espacement n'ont aucune importance. 2.2 ClassificateursLes classificateurs servent à créer les index de navigation d'une collection, comme par exemple l'index titres A-Z de la collection dlpeople, et les index thème, comment faire, organisation et titres A-Z dans la bibliothèque de développement pour l'humanité, dont la collection «Demo» est un sous-ensemble. La barre de navigation située au sommet des copies d'écran dans les figures 3 et 8a inclut la fonction Rechercher, qui est toujours disponible, suivie par autant de boutons que de classificateurs définis. Les informations servant à la navigation sont stockées dans la base de données d'informations de la collection, et y sont placées par des classificateurs lors de la phase finale du programme buildcol.pl.
Figure 11
ClassificateurAZList
Les classificateurs, à l'instar des greffons, sont spécifiés dans le fichier de configuration de la collection. À chacun correspond une ligne débutant par le mot-clef classify et suivie du nom du classificateur et des options qu'il accepte. Le fichier de configuration de collection simple étudié dans la section 1.5 comprend la ligne classify AZList -metadata Title, qui crée une liste alphabétique des titres en prenant tous les documents pourvus d'un champ de méta-données Title, en triant ces derniers et en les ventilant en intervalles alphabétiques. On trouvera un exemple dans la figure 11.
Figure 12
ClassificateurList
Un classificateur plus simple, appelé List, et illustré dans la figure 12, crée une liste triée d'une méta-donnée spécifiée et l'affiche sans créer de tranches alphabétiques. Un exemple est la méta-donnée how to de la collection «Demo», qui est produite par la ligne classify List -metadata Howto dans le fichier de configuration de la collection[3]. Un autre classificateur de liste générique est DateList, illustré dans la figure 13, qui engendre une liste de sélection d'intervalles de dates (le classificateur DateList est également utilisé dans la collection «Archives» de Greenstone).
Figure 13
ClassificateurDateList
D'autres classifications engendrent des structures de navigation qui sont explicitement hiérarchiques. Les classifications hiérarchiques sont utiles pour des classifications et sous-classifications de thèmes, et les hiérarchies organisationnelles. Le fichier de configuration de la collection «Demo» contient la ligne classify Hierarchy -hfile sub.txt -metadata Subject -sort Title, et la figure 14 ontre la hiérarchie de thèmes que cette ligne produit. L'étagère portant un titre en gras et l'étagère actuellement utilisée; la classification de thème à laquelle elle appartient la surplombe. Dans cet exemple la hiérarchie utilisée pour la classification est stockée dans un simple fichier texte, sous le nom sub.txt.
Figure 14
ClassificateurHierarchy
Tous les classificateurs génèrent une structure hiérarchique qui est utilisée pour afficher un index de navigateur. Les niveaux les plus bas de la hiérarchie (les feuilles) sont généralement les documents, mais dans certains classificateurs ce sont les sections. Les noeuds internes de la hiérarchie sont Vlist, Hlist, ou Datelist. Un noeud Vlist est une liste d'objets affichés verticalement et descendant la page, telle que l'index «comment faire» de la collection «Demo» (figure 12). Un noeud Hlist est affiché horizontalement; par exemple l'affichage AZList de la figure 11 est une hiérarchie à deux niveaux de noeuds internes consistant en un noeud Hlist (donnant le sélecteur A-Z) et dont les enfants sont des noeuds Vlist -- parents, à leur tour, de documents. Un noeud Datelist (figure 13) est un cas particulier de noeud Vlist qui permet d'effectuer des sélections par année et par mois. Les lignes spécifiant des classificateurs dans les fichiers de configuration de collection contiennent un argument metadata qui identifie les méta-données selon lesquelles classifier et trier les documents. Tout document de la collection ne disposant pas de cette méta-donnée sera omis par le classificateur (mais il sera quand même indexé, et les recherches le prendront donc en compte). En l'absence de spécification d'argument metadata, tous les documents sont inclus dans le classificateur, dans l'ordre dans lequel le processus de construction les a trouvés. C'est utile si vous souhaitez obtenir une liste de tous les documents de votre collection.
Table 13
Classificateurs de Greenstone
Les classificateurs actuellement disponibles sont listés dans la table 13. De même que l'on peut utiliser le programme pluginfo.pl pour en savoir plus sur un greffon quelconque, on peut utiliser le programme classinfo.pl pour en savoir plus sur un classificateur et sur les options qu'il propose. Tous les classificateurs acceptent l'argument buttonname, qui définit ce qui est écrit sur le bouton de navigation de Greenstone qui invoque le classificateur (sa valeur par défaut est le nom de l'argument metadata). Des boutons sont fournis pour chacun des types de méta-données du système Dublin Core, ainsi que pour quelques autres types de méta-données. Chaque classificateur reçoit un nom implicite en fonction de sa position dans le fichier de configuration. Par exemple, le troisième classificateur spécifié dans le fichier s'appellera CL3. Ces noms sont utilisés dans les champs de la base de données d'informations de la collection, qui définit la hiérarchie des classificateurs. On peut écrire des classificateurs propres à une collection; ils sont alors stockés dans son répertoire perllib/classify. La bibliothèque de développement pour l'humanité dispose d'un classificateur propre de collection qui s'appelle HDLList, et qui est une variante mineure d'AZList. Classificateurs de listesVoici les différentes possibilités de classificateurs de listes:
Le classificateur hierarchyTous les classificateurs sont hiérarchiques. Cependant, les classificateurs de la section 2.1.1 disposent d'un nombre fixé de niveaux, alors que le classificateur hierarchy décrit dans la présente section peut créer un nombre de niveaux arbitraire: il est plus complexe à spécifier que les classificateurs de listes.
Figure 15
Portion du fichier sub.txt
L'argument hfile donne le nom d'un fichier, tel que celui de la figure 15, qui définit la hiérarchie de méta-données. Chaque ligne décrit une classification, et les descriptions comptent trois parties:
La figure 15 est une portion du fichier sub.txt, utilisé pour créer la hiérarchie de thèmes dans la bibliothèque de développement pour l'Humanité (et dans la collection «Demo»). Cet exemple n'est pas très clair puisque le nombre représentant la hiérarchie apparaît deux fois sur chaque ligne. Le type de méta-donnée Hierarchy est représenté dans les documents avec des valeurs sous forme numérique hiérarchique, ce qui correspond à la première occurrence. C'est la deuxième occurrence qui est utilisée pour déterminer la hiérarchie implémentée dans la hiérarchie de navigation. Le classificateur hierarchy dispose d'un argument facultatif, sort, qui détermine la manière dont les documents sont ordonnés au niveau des feuilles. On peut spécifier n'importe quelle méta-donnée comme clef de tri. Le comportement par défaut est de produire la liste dans l'ordre dans lequel le processus de construction rencontre les documents. Au niveau des noeuds internes, l'ordre est déterminé par celui des spécifications dans l'argument hfile. Fonctionnement des classificateursLes classificateurs sont des objets Perl, héritant de BasClas.pm, et stockés dans le répertoire perllib/classify. Ils sont utilisés lors de la construction de la collection. Leur exécution se fait en quatre étapes:
La méthode classify rapatrie l'OID de chaque document, la valeur de méta-donnée selon laquelle classifier le document, et, si nécessaire, la valeur de méta-donnée selon laquelle trier les documents. La méthode get_classify_info s'occupe du tri et de tout traitement propre au classificateur. Dans le cas du classificateur AZList par exemple, elle ventile la liste en intervalles. Le processus de construction initialise les classificateurs dès que l'objet builder est construit. Les classifications sont créées pendant la phase de construction, lors de la création de la base de données d'informations, par classify.pm, qui réside dans le répertoire perllib de Greenstone.
Table 14
Objets apparaissant dans les chaînes de formatage
2.3 Mettre en forme la sortie de GreenstoneLes pages web que vous pouvez voir lorsque vous utilisez Greenstone ne sont stockées nulle part; elles sont générées «à la volée» en fonction des besoins. L'apparence de nombreux aspects de ces pages est contrôlée à l'aide de «chaînes de formatage» (dans le sens de «mise en forme», et pas de «remise à zéro»). Les chaînes de formatage se trouvent dans le fichier de configuration de la collection, introduites par le mot-clef format lui-même suivi du nom de l'élément concerné par la mise en forme. Il existe deux types d'éléments de page contrôlés par des chaînes de formatage. Le premier comprend les éléments de la page qui affichent des documents ou des portions de documents. Le second comprend les listes produites par les classificateurs et les recherches. Toutes les chaînes de formatage sont interprétées au moment de l'affichage des pages. Elles prennent donc effet dès que le fichier collect.cfg est modifié et sauvegardé; il est par conséquent rapide et facile de faire des expériences avec les chaînes de formatage. La table 14 montre les instructions qui affectent la représentation des documents. L'option DocumentButtons contrôle les boutons qui sont affichés sur une page de document. Ici, chaîne est une liste de boutons (séparés par|), dont les valeurs possibles sont Detach (détacher), Highlight (mettre en valeur), Expand Text (développer le texte), et Expand Contents (développer la table des matières). Modifier l'ordre de la liste a le même effet sur les boutons.
Table 15
Les options du mot-clefformat
Formatage des listes de GreenstoneLes chaînes de formatage qui contrôlent l'apparence des listes peuvent s'appliquer à divers niveaux de la structure d'affichage. Elles peuvent altérer toutes les listes d'un certain type au sein d'une collection (comme par exemple DateList), toutes les parties d'une liste (comme par exemple toutes les entrées de la liste Rechercher), ou des portions spécifiques d'une liste particulière (comme par exemple la portion verticale de la liste du classificateur AZList appliqué sur des titres). Le mot-clef format précède un mot-clef en deux parties, dont une seule est obligatoire. La première partie identifie la liste où s'applique le format. La liste générée par une recherche s'appelle Search (rechercher), tandis que les listes générées par des classificateurs sont appelées CL1, CL2, CL3,... pour respectivement le premier, le deuxième, le troisième... classificateur spécifié dans le fichier collect.cfg. La deuxième partie du mot-clef est la portion de la liste à laquelle appliquer la mise en forme -- soit HList (pour une liste horizontale, telle que le sélecteur dans un noeud AZList), VList (pour une liste verticale, telle que la liste des tous les titres sous un noeud de type AZList), ou DateList. Par exemple:
format CL4VList ... s'applique à tous les VList de CL4
format CL2HList ... s'applique à tous les HList de CL2
format CL1DateList ... s'applique à tous les DateList de CL1
format SearchVList ... s'applique à la liste de Résultats de la recherche
format CL3 ... s'applique à tous les noeuds de CL3, sauf indication contraire
format VList ... s'applique à tous les VList de tous les classificateurs, sauf indication contraire Les"..."de ces exemples représentent des spécifications de formatage HTML qui contrôlent l'information et sa représentation, apparaissant sur des pages web représentant le classificateur. Comme pour les spécifications HTML, toute méta-donnée peut apparaître entre crochets: sa valeur est interpolée à l'endroit indiqué. Tout élément de la table 15 peut également apparaître dans des chaînes de formatage. La syntaxe des chaînes prévoit également une instruction conditionnelle, qui est illustrée plus bas. Rappelez-vous que tous les classificateurs produisent des hiérarchies. Chaque niveau de la hiérarchie est affiché de l'une de quatre manières possibles. Nous avons déjà mentionné HList, VList, et DateList. Il existe également Invisible, qui est la manière dont les tous premiers niveaux des hiérarchies sont représentés -- le nom du classificateur apparaît déjà séparément, en effet, sur la barre de navigation de Greenstone. Exemples de classificateurs et de chaînes de formatage
Figure 16
Extrait du fichier collect.cfg de la collection «Demo»
La figure 16 représente une portion du fichier de configuration de la collection «Demo». Nous l'utilisons comme exemple, car il comprend plusieurs classificateurs avec un formatage riche. Remarquez que les instructions des fichiers de configuration ne peuvent pas contenir de retour à la ligne, et que dans la figure, nous avons scindé les lignes les plus longues pour des raisons de lisibilité. La ligne 4 spécifie le classificateur How To (comment faire) de la collection «Demo». C'est le quatrième classificateur du fichier de configuration de la collection; on s'y réfère donc sous le nom CL4. L'instruction de formatage correspondante est la ligne 7 de la figure 16. Cette information d'«indice» est engendrée par le classificateur List, et sa structure est la liste brute des titres affichés figure 12. Les titres sont reliés aux documents eux-mêmes: cliquer sur un titre affiche le document correspondant. Les enfants du premier niveau de la hiérarchie sont affichés sous la forme d'une VList (liste verticale), qui liste les sections verticalement. Comme l'indique l'instruction format associée, chaque élément de la liste apparaît sur une nouvelle ligne ("<br>") et contient le texte de Howto, lui-même relié par lien hypertexte au document lui-même. La ligne 1 spécifie la classification Subject (Thème) de la collection «Demo», à laquelle on se référera sous le nom CL1 (puisqu'elle est la première du fichier de configuration), et la ligne 3 spécifie la classification Organisation CL3. Toutes deux sont générées par le classificateur Hierarchy et comprennent donc une structure hiérarchique d'objets VList. La ligne 2 spécifie la dernière classification de la collection «Demo», titres A-Z (CL2). Remarquez qu'il n'existe pas de chaînes de formatage associées aux classificateurs CL1 à CL3. Greenstone dispose de valeurs par défaut pour chaque type de chaîne de formatage; il n'est donc pas nécessaire de positionner une chaîne de formatage quand on ne souhaite pas obtenir un comportement différent du comportement par défaut.
Figure 17
Mise en forme du document
Voilà pour les quatre lignes classify de la figure 16. On y trouve aussi quatre lignes format. Nous avons déjà expliqué la ligne CL4Vlist. Les trois lignes restantes sont du premier type de chaîne de formatage, documenté dans la table 14. Par exemple, la ligne 8 place l'image de couverture en haut à gauche de chaque page de document. La ligne 9 formate le texte du document à proprement parler, et place le titre du chapitre ou de la section concernée juste avant le texte. Tous ces effets sont illustrés dans la figure 17.
Figure 18
Mise en forme des résultats de la recherche
La ligne 5 de la figure 16 est une spécification quelque peu complexe qui formate la liste de résultats à une requête renvoyée par une recherche, dont les portions sont illustrées à la figure 18. Voici une version simplifiée de la chaîne de formatage: <td valign=top>[link][icon][/link]</td>
<td>[link][Title][/link]</td>
Ceci est conçu pour apparaître comme une ligne dans un tableau, ce qui est la manière dont la liste de résultats à une requête est mise en forme. Comme d'habitude, on obtient une petite icone cliquable qui mène au texte, et le titre du document, ancre d'un lien hypertexte qui mène au document à proprement parler. Dans cette collection, les documents sont hiérarchiques. En fait, l'ancre de lien hypertexte ci-dessus se transforme en le titre de la section renvoyée par le requête. Il serait néanmoins préférable de lui adjoindre également le titre de la section qui la contient, du chapitre qui contient cette dernière, et du livre où ce chapitre apparaît. Il existe un objet de méta-donnée particulier, parent, qui n'est pas stocké dans les documents mais qui est implicite dans tout document hiérarchique, qui produit une telle liste. Elle renvoie soit le document parent ou, si elle est utilisée avec le qualificateur All (tout), la liste de tous les ancêtres au sens hiérarchique, séparés par une chaîne de caractères que l'on peut préciser après le qualificateur All. Ainsi: <td valign=top>[link][icon][/link]</td>
<td>{[parent(All': '):Title]: }[link][Title][/link]</td> a pour effet de produire une liste contenant le titre du livre, le titre du chapitre, etc., qui entourent la section cible; titres séparés par des caractères deux points, et un dernier caractère deux points est suivi d'un lien hypertexte menant au titre de la section cible. Malheureusement, dans le cas où la cible est un livre, elle n'aura aucun parent et on verra donc apparaître une chaîne vide suivie d'un caractère deux points. Pour éviter de tels problèmes, on peut utiliser dans une chaîne de formatage des instructions conditionnelles if and or ... else (si et ou ... sinon): {If}{[metadata], action-if-non-null, action-if-null}
{Or}{action, else another-action, else another-action, etc}
Dans chaque cas les accolades signalent que les instructions doivent être interprétées, et non pas simplement affichées comme du texte. L'instruction If teste si la méta-donnée est vide, et prend la première clause si ce n'est pas le cas, et la deuxième clause si c'est le cas (et si une deuxième clause est fournie). On peut utiliser tout élément de méta-données, y compris la méta-donnée spéciale parent. L'instruction Or évalue chaque action tour à tour jusqu'au moment où elle en rencontre une qui n'est pas vide. Cette action est alors renvoyée en sortie et le reste de la ligne est ignoré. Si l'on revient à la ligne 5 de la figure 16, la chaîne de formatage complète est: <td valign=top>[link][icon][/link]</td>
<td>{If}{[parent(All': '):Title],
[parent(All': '):Title]:}
[link][Title][/link]</td>
Ceci fait précéder la spécification parent d'un test qui examine si le résultat est vide et n'affiche la chaîne du parent que lorsque ce dernier est présent. On peut aussi qualifier parent par Top (sommet) au lieu de All (tout), ce qui donne le nom de document de niveau le plus élevé qui entoure une section -- dans le cas présent, le nom du livre. Nul besoin, avec Top, de chaîne de séparation. Voici quelques derniers exemples pour illustrer d'autres fonctionnalités. Le classificateur DateList, dans la figure 13, est utilisé dans la classification Dates de la collection Computists' Weekly (l'hebdomadaire des informaticiens), et il se trouve qu'il en est le deuxième classificateur, soit CL2. Le classificateur et les spécifications de formatage sont indiqués ci-dessous. Le classificateur DateList diffère d'AZList en ce sens qu'il trie toujours selon la méta-donnée Date, et que les branches situées au pied de la hiérarchie de navigation utilisent DateList au lieu de VList, ce qui ajoute à gauche des listes de documents, l'année et le mois. classify AZSectionList metadata=Creator
format CL2Vlist "<td>[link][icon][/link]</td>
<td>[Creator]</td> <td> [Title]</td> <td>[parent(Top):Date]</td> " La spécification de formatage affiche ces VLists de manière appropriée. Le mécanisme de chaîne de formatage est souple mais difficile à apprendre. La meilleure manière de procéder est d'étudier des fichiers de configuration de collections existantes. Tirer des liens vers différentes versions d'un documentUtiliser le mécanisme[link] ... [/link]dans une chaîne de formatage a pour effet d'insérer un lien hypertexte menant au texte du document, en version HTML. Il est utile dans certaines collections de pouvoir afficher d'autres versions du document. Dans une collection de documents au format Microsoft Word, par exemple, il est bon d'être capable d'afficher la version Word de chaque document plutôt que le HTML qui en fut extrait; de même pour des documents PDF. Pour pouvoir afficher différentes versions d'un document, la clef est d'embarquer les informations nécessaires (c'est-à-dire où se trouvent les autres versions du document) dans le format d'archivage de Greenstone du document. On représente cette information sous la forme de méta-données. Souvenez-vous qu'en plaçant [link][Title][/link]
dans une chaîne de formatage, on crée un lien vers la version HTML du document, lien dont l'ancre est le titre du document. Les greffons Word et PDF générent tous deux la méta-donnée srclink de telle sorte qu'écrire [srclink][Title][/srclink]
dans une chaîne de formatage créera un lien vers la version Word ou PDF du document; lien dont l'ancre sera dans cet exemple aussi, le titre du document. Pour permettre d'afficher l'icone appropriée pour les documents Word et PDF, ces greffons générent aussi la méta-donnée srcicon de telle sorte que [srclink][srcicon][/srclink]
créera un lien étiqueté par l'icone standard pour le format Word ou PDF (selon le cas), et non pas par le titre du document. 2.4 Contrôler l'interface utilisateur de GreenstoneL'interface utilisateur de Greenstone est entièrement contrôlée par des macros placées dans le répertoire GSDLHOME/macros. Elles sont écrites dans un langage conçu spécialement pour Greenstone, et sont utilisées au moment de l'exécution pour engendrer des pages web. La traduction du langage de macros en HTML est la dernière étape de l'affichage d'une page. Ainsi, toute modification à un fichier de macros affecte immédiatement l'affichage, il est donc rapide et facile de faire des expériences avec les macros. Tous les fichiers de macros utilisés par Greenstone sont listés dans le fichier GSDLHOME/etc/main.cfg et sont chargés à chaque démarrage. Signalons l'exception de la version «Bibliothèque locale» sous Windows; dans ce cas il est nécessaire de redémarrer le processus. Les pages web sont générées à la volée pour de nombreuses raisons, et le système de macros est la manière dont Greenstone implémente la souplesse nécessaire. On peut présenter des pages dans de nombreuses langues différentes, et on utilise un fichier de macros différent pour stocker tout le texte de l'interface dans chaque langue. Quand Greenstone affiche une page l'interpréteur de macros consulte une variable de langue et charge la page dans la langue appropriée (ce système ne va pas, malheureusement, jusqu'à traduire le contenu du document). De même, les valeurs de certaines variables d'affichage, telles que le nombre de documents trouvés par une recherche, ne sont pas connues à l'avance: elles sont interpolées dans le texte de la page à l'aide de macros. Le format des fichiers de macrosLes fichiers de macros ont pour extension .dm. Chaque fichier définit un ou plusieurs paquetages, et chaque paquetage définit une série de macros utilisées dans un but précis et unique. À l'instar des classificateurs et des greffons, il existe une base à partir de laquelle construire des macros, appelée base.dm; ce fichier définit le contenu de base d'une page. Les macros portent des noms qui commencent et finissent par un caractère de soulignement, et leur contenu est défini à l'aide d'accolades. Leur contenu peut consister en du texte brut, du HTML (y compris de liens vers des appliquettes (applets) Java ou du JavaScript), des noms de macros, ou toute combinaison de ces éléments. La macro suivante, extraite du fichier base.dm, définit le contenu d'une page en l'absence de toute macro de remplacement: _content_ {<p><h2>Oops</h2>_textdefaultcontent_}
Cette page affichera «Oops» à son sommet, suivi du contenu de la macro d'erreur correspondante, _textdefaultcontent_ qui est en anglais définie comme suit: Global:textdefaultcontentThe requested page could not be found. Please use your browsers 'back' button or the above home button to return to the Greenstone Digital Library.; dans d'autres langues, elle affichera une traduction appropriée de cette phrase. En français, on obtiendra par exemple Global:textdefaultcontentLa page demandée n'a pu être trouvée. Utilisez s'il-vous-plaît le bouton «retour» de votre navigateur, ou le bouton «accueil» pour retourner à la Bibliothèque Numérique Greenstone. Les deux macros _textdefaultcontent_ (contenu textuel par défaut) et _content_ (contenu) se trouvent dans le paquetage global car elles sont requises dans toutes les portions de l'interface utilisateur. Les macros peuvent utiliser des macros d'autres paquetages en tant que contenu, mais il faut alors qu'elles en préfixent les noms par le nom du paquetage. Exemple: _collectionextra_ {This collection contains _about:numdocs_ documents. It was last built _about:builddate_ days ago.)
provient du fichier french.dm (macros pour le français), et elle est utilisée comme description par défaut d'une collection. Elle fait partie du paquetage intitulé global, mais les macros _numdocs_ et _builddate_ se trouvent toutes deux dans le paquetage about (à propos de...) -- d'où le about qui préfixe leurs noms. Les macros renferment souvent des conditionnelles, qui ressemblent aux conditonnelles de chaînes de formatage décrites plus haut, à ceci près que leur apparence est un peu différente. Le format de base est _If_(x,y,z), où x est une condition, y est le contenu de macro à utiliser si cette condition est vérifiée, z le contenu à utiliser dans le cas contraire. Les opérateurs de comparaison sont les mêmes que les opérateurs simples utilisés dans Perl (moins que, plus que, égale, différent de). L'exemple suivant, extrait du fichier base.dm, sert à déterminer comment afficher le sommet de la page À propos de cette collection d'une collection: _imagecollection_ {
_If_( "_iconcollection_ " ne "",
<a href = "_httppageabout_ ">
<img src = "_iconcollection_ " border = 0>
</a>,
_imagecollectionv_)
}
Voilà qui peut sembler abscons. La macro _iconcollection_ vaut la chaîne vide si la collection ne dispose pas d'une icone, ou le nom de l'image dans le cas contraire. Pour paraphraser le code ci-dessus en français: s'il existe une image de collection, afficher l'en-tête de page à propos (à laquelle on se réfère par _httppageabout_) et puis cette image; sinon afficher la solution de secours _imagecollectionv_. Les macros peuvent prendre des arguments. Voici une autre définition de la macro _imagecollection_, suivant immédiatement la définition donnée plus haut, dans le fichier base.dm: _imagecollection_[v=1]{_imagecollectionv_}
L'argument [v=1] spécifie qu'il faut utiliser cette deuxième définition quand Greenstone fonctionne en mode texte seul. Les macros de langue fonctionnent de manière similaire -- à l'exception du fichier english.dm, qui est le fichier utilisé par défaut, toutes les macros de langue spécifient leur langue en argument. Par exemple: _textimagehome_ {Home Page}
apparaît dans le fichier de macros pour la langue anglaise, alors que la version allemande est: _textimagehome_ [l=de] {Hauptaseite}
Les versions anglaise et allemande se trouvent dans le même paquetage, bien qu'elles soient stockées dans des fichiers séparés (les définitions de paquetages peuvent occuper plusieurs fichiers). Greenstone utilise son argument l au moment de l'exécution pour décider quelle langue afficher.
Figure 19
Portion du fichier de macro about.dm
Comme dernier exemple, la figure 19 montre un extrait du fichier de macros about.dm, utilisé pour générer la page à propos de chaque collection. Elle montre la définition de trois macros, _pagetitle_ (titre de page), _content_ (contenu), et _textabout_ (texte «à propos de...»). Utiliser les macrosLes macros sont puissantes, et peuvent sembler un peu obscures. Mais avec une bonne connaissance de HTML et un peu de pratique elles deviennent une manière rapide et facile de personnaliser votre site Greenstone. Supposons par exemple que vous souhaitiez créer une page statique qui ressemble à votre site Greenstone actuel. Vous pouvez créer un nouveau paquetage, que vous appellerez static par exemple, dans un nouveau fichier, et y redéfinir la macro _content_. Ajoutez ce nom de fichier dans GSDLHOME/etc/main.cfg, que Greenstone charge à chaque fois qu'il est invoqué. Vous accéderez à la nouvelle page en utilisant votre URL habituelle pour Greenstone et en lui ajoutant les arguments ?a=p&p=static (on obtiendra par exemple l'URL complète suivante: http://serveur/cgi-bin/library?a=p&p=static). Pour modifier l'apparence et l'ergonomie de Greenstone vous pouvez éditer les paquetages base et style. Pour modifier la page d'accueil de Greenstone, éditez le paquetage home (ceci est décrit dans le Guide d'installation de la bibliothèque numérique Greenstone). Pour modifier la page de requêtes, éditez le fichier query.dm. Expérimentez sans crainte avec les macros. Les modifications apparaissent instantanément, puisque les macros sont interprétées lors de l'affichage des pages. Le langage de macros est un outil puissant que vous pouvez utiliser pour vous approprier vraiment votre site Greenstone. 2.5 Le répertoire packages
Table 16
Le répertoirepackages
Le répertoire packages (paquetages), dont le contenu est représenté dans la table 16, est l'endroit de stockage de tout le code utilisé par Greenstone mais écrit par des tiers ou d'autres équipes de recherche. Tout le logiciel distribué avec Greenstone a été publié sous la licence publique générale de GNU (GPL). Les exécutables produits par ces paquetages sont placés dans le répertoire bin de Greenstone. Chaque paquetage est stocké dans son propre répertoire. Les différents paquetages ont des fonctions très diverses, allant de l'indexation et de la compression à la conversion de documents du format Microsoft Word en HTML. Chaque paquetage dispose d'un fichier README (lisez-moi) qui fournit des informations complémentaires le concernant. 3 Le système d'exécution de GreenstoneLe présent chapitre décrit le système d'exécution de Greenstone pour que vous puissiez comprendre, augmenter et étendre ses fonctionnalités. Le logiciel est écrit en C++ est utilise intensivement l'héritage virtuel. Si vous ne connaissez pas bien ce langage il est préférable que vous l'appreniez avant de continuer la lecture. Deitel et Deitel (1994) proposent un didacticiel complet, mais la référence incontournable est le Stroustrup (1997). Nous commençons par expliquer la philosophie de la conception qui a sous-tendu le système d'exécution car elle a des conséquences importantes sur l'implémentation. Nous fournissons ensuite les détails d'implémentation, qui forment la partie principale de ce chapitre. La version de Greenstone décrite ici est la version CGI (ou version Bibliothèque Web pour les utilisateurs de Windows). La version Bibliothèque locale utilise le même code source mais dispose en frontal d'un serveur web intégré. C'est également un processus persistent. 3.1 Structure des processus
Figure 20
Vue d'ensemble d'un système Greenstone générique
La figure 20 montre plusieurs utilisateurs, représentés par des terminaux informatiques en haut du diagramme, en train d'accéder à trois collections Greenstone. Avant d'être mises en ligne, ces collections subissent les processus d'import et de construction décrits dans les chapitres précédents. Tout d'abord, les documents, représentés en bas de la figure, sont importés dans le format d'archivage de Greenstone, qui est compatible XML. Les fichiers d'archives servent ensuite à la construction de plusieurs index de recherche et d'une base de données d'informations de la collection comprenant les structures hiérarchiques permettant la navigation. La collection est alors prête à être mise en ligne et à répondre à des requêtes d'informations. Deux composants sont centraux dans la conception du système d'exécution: les «réceptionnistes» et les «serveurs de collection». Du point de vue de l'utilisateur, un réceptionniste est le point de contact avec la bibliothèque numérique. Il accepte les données fournies par l'utilisateur, généralement sous la forme de saisies au clavier et de clics de souris; il les analyse; et il émet ensuite une requête au(x) serveur(s) de collection appropriés. Ce dernier localise l'information recherchée et la renvoie au réceptionniste pour que ce dernier la présente à l'utilisateur. Les serveurs de collection se comportent comme un mécanisme abstrait qui gère le contenu de la collection, alors que les réceptionnistes gèrent l'interface utilisateur.
Figure 21
Système Greenstone utilisant le «protocole vide»
Comme illustré dans la figure 20, les réceptionnistes communiquent avec les serveurs de collection en utilisant un protocole défini. L'implémentation de ce protocole dépend de l'ordinateur et de la configuration du système de bibliothèque numérique. Le cas le plus fréquent et le plus simple est celui d'un réceptionniste et d'un serveur de collection, fonctionnant tous deux sur le même ordinateur. C'est ce qui est produit par l'installation par défaut de Greenstone. Les deux processus sont alors combinés dans un unique exécutable (appelé library), et le protocole se réduit par conséquent à des appels de fonctions. C'est ce que nous appelons leprotocole vide(null protocol). C'est la base des systèmes de bibliothèque numérique Greenstone clef en main. Cette configuration simplifiée est illustrée figure 21, où le réceptionniste, le protocole et le serveur de collection sont regroupés sous la forme d'une unique entité, le programme library. Le présent chapitre a pour but d'expliquer son fonctionnement. Un «serveur» est habituellement un processus persistent qui, une fois démarré, fonctionne indéfiniment, en répondant aux requêtes entrantes. Malgré son nom, cependant, le serveur de collection dans la configuration du protocole vide n'est pas un serveur au sens habituel. En fait, à chaque requête d'une page web de Greenstone, le programme library est démarré (par le mécanisme CGI), répond à la requête, et quitte. Nous n'appelons le serveur de collection «serveur» que parce qu'il est également conçu pour fonctionner dans la configuration plus générale de la figure 20. De manière surprenante, ce cycle de démarrage, traitement, et fin d'exécution n'est pas aussi lent qu'on pourrait le craindre, et le service fourni est parfaitement utilisable. Il est clair cependant que ce système est inefficace. Un mécanisme appelé Fast-CGI (www.fastcgi.com) fournit un compromis. Si on l'utilise, le programme library demeure en mémoire après la première exécution, et les lots suivants d'arguments CGI lui sont communiqués, ce qui évite les surcharges d'initialisation, et ressemble beaucoup à un serveur au sens classique. Fast-CGI est une option dans Greenstone, que l'on active en recompilant le code source de Greenstone avec les bibliothèques appropriées. Pour fournir un autre choix que le protocole vide, nous avons également développé le protocole Greenstone en utilisant le célèbre système CORBA (Slamaet al., 1999). Il utilise un paradigme orienté objet unifié pour activer différents processus, fonctionnant sur différentes plates-formes, et implémentés en différents langages de programmation, pour accéder au même ensemble d'objets distribués sur l'Internet (ou tout autre réseau). Des scénarios comme celui de la figure 20 peuvent ensuite être entièrement implémentés, avec des réceptionnistes et des serveurs de collection fonctionnant sur des ordinateurs différents.
Figure 22
Interface graphique de requêtes de Greenstone
Ceci permet la mise en place d'interfaces bien plus sophistiquées pour mettre en place exactement les mêmes collections de bibliothèques numériques. Un exemple parmi tant d'autres, la figure 22 représente une interface graphique de requêtes, fondée sur des diagrammes de Venn, qui permet aux utilisateurs de manipuler directement des requêtes booléennes. Écrite en Java, cette interface fonctionne localement, sur l'ordinateur de l'utilisateur. Utilisant CORBA, elle accède à un serveur de collection Greenstone distant, écrit en C++. Ce protocole distribué faisant toujours l'objet de recherches en raffinement et utilisabilité, le présent manuel ne le détaillera pas davantage (voir Bainbridgeet al., 2001, pour des informations complémentaires à ce sujet). 3.2 Cadre conceptuel
Figure 23
Génération de la page «à propos»
La figure 23 représente la page «à propos» d'une collection Greenstone particulière (la collection du projet Gutenberg). Examinez l'URL au sommet de la figure: cette page est générée par l'exécution du programme CGI library, qui est l'exécutable mentionné plus haut, comprenant à la fois le réceptionniste et le serveur de collection, reliés entre eux par le protocole vide. Les arguments passés au programme library sont c=gberg, a=p, et p=about. On peut les interpréter comme suit:
Pour la collection du projet Gutenberg (c=gberg), l'action est de générer une page (a=p), et la page à générer s'appelle about -- à propos de ... -- (p=about).
Figure 24
Système d'exécution de Greenstone
La figure 24 illustre les portions principales du système d'exécution de Greenstone. Au sommet, le réceptionniste initialise d'abord ses composants, puis analyse les arguments CGI pour savoir quelle action appeler. Lors de l'exécution de l'action (ce qui comprend d'autres traitements des arguments CGI), le logiciel utilise le protocole pour accéder au contenu de la collection. La réponse est utilisée pour générer une page web, avec l'aide du composant de mise en forme et du langage de macros. Le langage de macros, que nous avons rencontré section 2.4, fournit un système de bibliothèque numérique Greenstone d'un style consistant, et permet de créer des interfaces dans différentes langues. L'interaction avec la bibliothèque fournit les squelettes des pages web; les macros du répertoire GSDLHOME/macros leur donnent chair. L'objet de langage de macros représenté figure 24 a pour rôle de lire ces fichiers et de stocker le résultat de l'analyse en mémoire. Toute action peut utiliser cet objet pour développer une macro. On peut même créer de nouvelles définitions de macros pour en écraser d'anciennes, ce qui ajoute une dimension dynamique à l'utilisation des macros. La représentation de la page «à propos» (figure 23) est connue avant l'exécution, et consignée dans le fichier de macros about.dm. Les en-têtes, les pieds, et l'image de fond n'y sont même pas mentionnés car ils se trouvent dans le paquetage de macros global. Cependant, le texte spécifique d'«à propos» d'une collection particulière n'est pas connu d'avance; il est stocké dans la base de données d'informations de la collection lors du processus de construction. Cette information, rapatriée à l'aide du protocole, est stockée sous _collectionextra_ dans le paquetage de macros global. Vous remarquerez que ce nom de macro ressemble presque exactement au nom utilisé pour exprimer cette information dans le fichier de configuration de collection décrit section 1.5. Pour générer le contenu de la page, la macro _content_ (contenu) du paquetage about (présenté figure 19) est développée, ce qui à son tour développe _textabout_ (texte d'à propos), qui accède à la macro _collectionextra_, qui venait d'être placée là de façon dynamique. Un autre ingrédient important est l'objet de mise en forme, ou formatage. Les instructions de mise en forme du fichier de configuration de collection affectent la présentation de portions particulières de la collection, comme nous l'avons expliqué section 2.3. Elles sont gérées par l'objet de mise en forme représenté figure 24. La tâche principale de cet objet est d'analyser et d'évaluer des instructions telles que les chaînes de formatage de la figure 16. Comme nous l'avons vu en section 2.3, de telles chaînes peuvent comprendre des références à des méta-données entre crochets (comme par exemple [Title] pour le titre), qu'il faut ensuite rapatrier du serveur de collection. Les objets de mise en forme et de langage de macros interagissent, car les instructions de formatage peuvent comprendre des macros qui, une fois développées, incluent des méta-données, qui une fois développées incluent des macros, etc. Le serveur de collection, au bas de la figure 24, connaît lui aussi une phase d'initialisation, préparant les objets filtre et source pour répondre à des requêtes entrantes fournies selon le protocole, et un objet de recherche pour les assister dans cette tâche. Les objets de recherche accèdent en fin de chaîne aux index et à la base de données d'informations de la collection, tous créés lors de la construction de la collection. Si on ne compte pas les lignes vides, le réceptionniste contient 15 000 lignes de code. Le serveur de collection en compte 5 000, dont les trois quarts correspondent à des fichiers d'en-têtes. Le serveur de collection est plus compact car le rapatriement de données se fait à travers deux programmes pré-compilés. MG, un système de rapatriement dans le corps du texte, sert à la recherche, et GDBM, un système de gestion de bases de données, renferme la base de données d'informations de la collection. Pour encourager extensibilité et souplesse, Greenstone utilise largement l'héritage -- en particulier dans les objets d'action, de filtre, de source, et de recherche. Pour une simple bibliothèque numérique ne contenant que des collections textuelles, ceci signifie qu'il vous faudra en apprendre un peu plus pour programmer le système. Mais cela signifie aussi qu'on pourrait facilement remplacer MG et GDBM si le besoin devait un jour s'en faire sentir. De plus, l'architecture du logiciel est assez riche pour accepter toutes les fonctionnalités multimédia, telles que le contrôle de l'interface par des systèmes de reconnaissance vocale, ou la soumission de requêtes sous la forme d'images dessinées. 3.3 Agencement du cadre conceptuelLes sections 3.6 et 3.8 détaillent le fonctionnement du serveur de collection et du réceptionniste, en passant plus de temps sur chacun des modules de la figure 24 et en décrivant leur implémentation. Il est utile de commencer par travailler sur des exemples d'interaction utilisateur avec Greenstone et de décrire ce qui se passe en coulisses. Nous supposerons pour le moment que tous les objects sont correctement initialisés. L'initialisation est une procédure assez compliquée, que nous revisiterons dans la section 3.9. Effectuer une recherche
Figure 25
Recherche de «Darcy» dans le projet Gutenberg
Quand un utilisateur effectue une requête en pressant le boutton Démarrer la recherche sur la page de recherche, une nouvelle action de Greenstone est invoquée, qui aboutit à la génération d'une nouvelle page HTML à l'aide du langage de macros. La figure 25 montre le résultat de la recherche dans la collection du projet Gutenberg du nom Darcy. La page de recherche comprenait originellement l'instruction a=q cachée dans le HTML. Cette instruction est activée lorsque le bouton de recherche est enfoncé, et appelle l'action queryaction. L'exécution de queryaction effectue un appel à l'objet de filtre de la collection (c=gberg) à travers le protocole. Les filtres sont une fonction de base importante des serveurs de collection. Adaptés aux activités de recherche et de navigation, ils fournissent une manière de sélectionner un sous-ensemble d'informations dans la collection. Dans le cas présent, queryaction met en place une requête de filtre en:
Les appels du protocole sont synchrones: le réceptionniste est effectivement bloqué tant que la requête de filtre n'a pas été traitée par le serveur de collection et que les données générées n'ont pas été renvoyées. Lors d'un appel de protocole de type QueryFilter, l'objet de filtre (de la figure 24) décode les options et effectue un appel à l'objet de recherche, qui utilise MG pour la recherche proprement dite. L'objet de recherche a pour rôle de fournir une interface abstraite de programme qui permet la recherche, indépendamment de l'outil de recherche utilisé de façon sous-jacente. Le format utilisé pour le renvoi des résultats utilise lui aussi l'abstraction, ce qui oblige l'objet de recherche à traduire les données générées par l'outil de recherche sous une forme standard. Lorsque les résultats de la recherche ont été renvoyés au réceptionniste, la suite des événements consiste à mettre en forme les résultats pour les afficher, en utilisant les objets de mise en forme et de langage de macros. Comme le montre la figure 25, ceci suppose de générer l'en-tête, le pied de page, la barre de navigation et le fond de page standard de Greenstone; de répéter la partie principale de la page de requêtes juste en dessous de la barre de navigation; et d'afficher une icone de livre ainsi que le titre et l'auteur pour chacun des résultats de la recherche. La mise en forme de cette dernière partie est dictée par l'instruction format SearchVList du fichier de configuration de collection. Avant qu'on puisse afficher les méta-données de titre et d'auteur, il faut les rapatrier depuis le serveur de collection, ce qui suppose des appels supplémentaires à travers le protocole, en utilisant cette fois BrowseFilter (filtre de navigation). Rapatrier un documentÀ la suite de la requête précédente pour Darcy, voyons ce qui se passe lors de l'affichage d'un document. La figure 26 montre ce qui se passe quand on clique sur l'icone jouxtant le titre The Golf Course Mystery (le mystère du parcours de golf) dans la figure 25.
Figure 26
The Golf Course Mystery (le mystère du parcours de golf)
Le texte source de la collection Gutenberg consiste en un long fichier par livre. Au moment de la construction, ces fichiers sont ventilés sous forme de pages différentes environ toutes les 200 lignes, et les informations relatives à chaque page sont stockées dans les index et la base de données d'informations de la collection. Au sommet de la figure 26 on constate que ce livre comprend 104 pages engendrées automatiquement, et on remarque juste en dessous le début de la première page: le copiste, le titre, l'auteur, et le début d'une table des matières (qui fait partie du texte source de Gutenberg; elle n'a pas été engendrée par Greenstone). En haut à gauche on trouve des boutons qui contrôlent la mise en forme du document: une seule page ou tout le document; s'il faut mettre en valeur le terme de la requête ou non; et s'il faut que le livre soit ou non affiché dans sa propre fenêtre, détachée des activités principales de recherche et de navigation. En haut à droite on trouve une aide à la navigation qui propose un accès direct à n'importe quelle page du livre: il suffit de taper le numéro de la page et d'enfoncer le bouton «aller à la page». On peut aussi se rendre aux pages précédente ou suivante en cliquant sur les icones de flèches aux côtés de l'outil de sélection de page. L'action de rapatriement des documents, documentaction, est spécifiée par a=d et elle accepte quelques arguments supplémentaires. Le plus important est le document à rapatrier: il est spécifié par la variable d. Dans la figure 26, il a la valeurd=HASH51e598821ed6cbbdf0942b.1pour rapatrier la première page du document d'identifiantHASH51e598821ed6cbbdf0942bqui s'appelle aussi, de manière plus agréable, The Golf Course Mystery (le mystère du parcours de golf). Il existe d'autres variables, spécifiant s'il faut ou non mettre en valeur le terme de la requête (hl, pour highlighting) et quelle page du livre afficher (gt). Ces variables permettent de proposer les fonctionnalités offertes par les boutons présentés sur la page web de la figure 26, et décrits ci-dessus. Si l'une de ces variables manque à l'appel, c'est le comportement par défaut correspondant qui sera utilisé. Cette action suit une procédure similaire à celle de queryaction: évaluation des arguments CGI, accès au serveur de collection en utilisant le protocole, et utilisation du résultat pour engendrer une page web. Les options relatives au document sont décodées à partir des arguments CGI et stockées dans l'objet pour plus tard. Pour rapatrier le document depuis le serveur de collection, on n'a besoin que de l'identifiant de document pour effectuer l'appel de protocole à get_document() (obtenir le document). Après l'envoi du texte, un travail considérable de remise en forme est nécessaire. Pour ce faire, le code de documentaction accède aux arguments stockés dans l'objet et utilise les objets de mise en forme et de langage de macros. Navigation dans un classificateur hiérarchiqueLa figure 27 montre un exemple de navigation, où l'utilisateur a choisi titres A-Z et choisi le lien hypertexte de la lettre K. C'est également documentaction qui gère cela, ce qu'on constate en observant l'argument CGI a=d, comme précédemment. Cependant, alors qu'auparavant la requête CGI comprenait une variable d, il n'y en a aucune cette fois-ci. À la place, le noeud à afficher pour navigation dans la hiérarchie de classification est spécifié dans la variable cl. Dans notre cas, ceci représente les titres groupés sous la lettre K. Cette liste a été formée au moment de la construction et fut stockée dans la base de données d'informations de la collection.
Figure 27
Navigation dans les titres de la collection Gutenberg
Les enregistrements représentant des noeuds de classificateur dans la base de données utilisent le préfixe CL, suivi de nombres séparés par des points (.) pour désigner où ils résident au sein de la structure récursive. Si on ignore le bouton de recherche, situé tout à gauche de la barre de navigation, les classificateurs sont numérotés séquentiellement et par ordre croissant, de gauche à droite, en commençant à 1. Ainsi, le noeud de classificateur de premier niveau pour les titres dans notre exemple est CL1 et la page recherchée est engendrée en positionnant cl=CL1.11. On peut observer cela dans l'URL au sommet de la figure 27. Lors du traitement d'une requête de document de type cl, l'objet de filtre est utilisé pour rapatrier le noeud à travers le protocole. Selon les données renvoyées, d'autres appels de protocole sont effectués pour rapatrier les méta-données des documents. Dans le cas présent, ce sont les titres des livres qui sont rapatriés. Mais si le noeud avait été un noeud interne dont les fils avaient eux-mêmes été des noeuds, les titres des noeuds fils auraient eux aussi été rapatriés. Du point de vue du code cela revient à la même chose, et c'est géré par le même mécanisme. Enfin, toutes les informations rapatriées sont reliées les unes aux autres à l'aide du langage de macros, pour produire la page web représentée figure 27. Génération de la page d'accueil
Figure 28
Page d'accueil de Greenstone
Comme dernier exemple, examinons le cas de la génération de la page d'accueil de Greenstone. La figure 28 montre -- dans le cas de l'installation par défaut de Greenstone -- la page d'accueil après l'installation de certaines collections de test. Son URL, qu'on peut voir au sommet de la capture d'écran, comprend les arguments a=p et p=home. Ainsi, à l'instar de la page «à propos», elle a été engendrée par pageaction (a=p), mais dans le cas présent la page à produire est la page home -- accueil -- (p=home). Le langage de macros accède par conséquent au fichier home.dm. Nul besoin de spécifier une collection (à l'aide de la variable c) dans le cas présent. La page d'accueil a pour but de présenter les collections disponibles. Cliquer sur une icone emmène l'utilisateur sur la page à propos de la collection choisie. Le menu des collections est généré automatiquement à chaque chargement de la page, en se fondant sur les collections présentes dans le système de fichiers à ce moment-là. Quand une nouvelle collection est mise en ligne, elle apparaît automatiquement sur la page d'accueil lorsque cette page est rechargée ou réactualisée, pour peu que cette collection ait été spécifiée comme «publique». Pour ce faire, le réceptionniste utilise, évidemment, le protocole. Dans le cadre de l'évaluation des arguments CGI, pageaction est programmé pour détecter le cas particulier p=home. L'action utilise alors get_collection_list() (obtenir la liste des collections), appel de protocole servant à établir l'ensemble actuel de collections mises en ligne. Pour chacune de ces collections il appelle get_collectinfo() (obtenir les informations de collection) pour recevoir les informations la concernant. Ces informations précisent si la collection est publiquement disponible, quelle est l'URL menant à l'icone de la collection (si une telle icone existe), et le nom complet de la collection, et elles sont utilisées pour générer l'entrée appropriée sur la page d'accueil de la collection. 3.4 Code source
Table 17
Programmes indépendants inclus dans Greenstone
Le code source du système d'exécution se trouve dans GSDLHOME/src. Il occupe deux sous-répertoires, recpt pour le code du réceptionniste, et colservr pour celui du serveur de collection. Greenstone fonctionne sur les systèmes Windows à partir de la version 3.1, qui impose malheureusement une limite de huit caractères sur les noms de fichiers et de répertoires; c'est ce qui explique l'utilisation d'abréviations cryptiques telles que recpt et colservr. Les sous-répertoires restants comprennent des outils indépendants, principalement utilisés en renfort du processus de construction. Ils sont listés dans la table 17. Un autre répertoire, GSDLHOME/lib, inclut des objets de bas niveau utilisés à la fois par le réceptionniste et par le serveur de collection. Ce code est décrit dans la section 3.5. Greenstone utilise énormément la bibliothèque standard de patrons (STL), une bibliothèque bibliothèque très répandue de code C++, développée par Silicon Graphics (www.sgi.com), et qui est l'aboutissement de nombreuses années de conception et de développement. À l'instar de toutes les bibliothèques de programmation, il faut un certain temps pour l'apprendre. L'annexe AppendixA donne un bref aperçu de ses principales portions utilisées tout au long du code de Greenstone. Pour une description plus détaillée, consultez le manuel de référence officiel de STL, disponible en ligne sur le site webwww.sgi.com, ou l'un des nombreux manuels traitant de STL, tel que celui de Josuttis (1999). 3.5 Types de base de GreenstoneLes objets définis dans le répertoire GSDLHOME/lib sont des objets de bas niveau de Greenstone, construits par-dessus STL, et qui sont utilisés tout au long du code source. Nous détaillons tout d'abord text_t, un objet utilisé pour représenter du texte Unicode. Nous résumerons ensuite le but de chacun des fichiers de bibliothèque. L'objet text_tGreenstone fonctionne avec de nombreuses langues, tant pour le contenu d'une collection que pour l'interface utilisateur. Pour gérer cela, nous avons utilisé Unicode tout au long du code source, et l'objet sous-jacent qui réalise une chaîne Unicode s'appelle text_t.
Figure 29
API de text_t (abrégée)
Unicode stocke chaque caractère sur deux octets. La figure 29 montre les fonctionnalités principales de l'interface de programmation (API, pour Application Program Interface) de text_t. Les deux octets sont assurés par l'utilisation du type standard C++ short, défini comme étant un entier sur deux octets. Le type de données central de l'objet text_t est un tableau dynamique de short non signés, construit par la déclaration STL vector<unsigned short>, et baptisé usvector (pour unsigned short vector). Les fonctions de construction (lignes 10-12) gèrent explicitement trois formes d'initialisation: construction sans paramètres, qui engendre une chaîne Unicode vide; construction avec un paramètre entier, qui engendre une version texte Unicode de la valeur numérique fournie; et construction avec un paramètre char*, qui traite l'argument comme une chaîne C++ terminée par un caractère nul et en génère une version Unicode. Ensuite, la plus grande partie du code (lignes 17-28) s'occupe de maintenir un conteneur de type vecteur STL: begin() (début), end() (fin), push_back() (remettre), empty() (vide), etc. On peut aussi effacer des chaînes, concaténer des chaînes, ainsi que convertir une valeur entière dans une chaîne de texte Unicode et renvoyer la valeur entière correspondant à un texte qui représente un nombre.
Figure 30
Opérateurs surchargés pour text_t
De nombreux opérateurs surchargés n'apparaissent pas dans la figure 29. Ils sont montrés dans la figure 30 pour donner un avant-goût des opérations possibles. La ligne 4 permet l'affectation d'un objet text_t à un autre, et la ligne 5 surcharge l'opérateur +=, pour fournir une manière plus naturelle de concaténer un objet text_t à la fin d'un autre. Il est également possible, à travers la ligne 6, d'accéder à un caractère Unicode particulier (représenté sous la forme d'un short) en utilisant des indices de tableaux [ ]. On fournit aussi des opérateurs d'affectation et de concaténation pour les entiers et les chaînes C++. Les lignes 12-18 fournissent des opérateurs booléens de comparaison de deux objets text_t: égale, différent de, précède alphanumériquement, etc. Il existe aussi des fonctions membre qui prennent des arguments de type const au lieu d'arguments de type non-const, mais elles ne sont pas représentées ici. Une telle répétition est habituelle dans des objets C++, ce qui augmente le code de l'API mais ne la rend pas plus grosse conceptuellement. En fait, de nombreuses fonctions sont implémentées sous la forme d'instructions tenant sur une ligne. Pour plus de détails, reportez-vous au fichier source GSDLHOME/lib/text_t.h. Le code des bibliothèques GreenstoneLes fichiers d'en-têtes du répertoire GSDLHOME/lib comprennent un mélange de fonctions et d'objets qui fournissent un support utile au système d'exécution de Greenstone. Là où l'efficacité prime, les fonctions et les fonctions membre sont déclarées inline. Dans la majorité des cas, les détails d'implémentation sont contenus dans le fichier .cpp correspondant au fichier d'en-têtes.
3.6 Serveur de collectionNous allons maintenant expliquer systématiquement tous les objets apparaissant dans le cadre conceptuel de la figure 24. Nous commençons au bas du diagramme -- c'est-à-dire aux fondations du système -- avec les objets de recherche, source, et de filtre, et remonterons les couches du protocole vers les composants centraux du réceptionniste: actions, mise en forme, et langage de macros. Nous nous concentrerons ensuite sur l'initialisation des objets, puisque cette dernière est plus facile à comprendre quand on connaît le rôle des différents objets. La plupart des classes centrales du cadre conceptuel sont exprimées à l'aide d'héritage virtuel pour favoriser l'extensibilité. Avec l'héritage virtuel, les objets hérités peuvent être passés en tant que leur classe de base, mais tout appel de fonction invoque la version définie dans l'objet hérité. En assurant que le code source de Greenstone utilise partout la classe de base, sauf aux endroits où s'effectue la construction des objets à proprement parler, nous garantissons donc que différentes implémentations -- utilisant peut-être des technologies sous-jacentes radicalement différentes -- peuvent facilement être mises en place. Supposons par exemple qu'une classe de base nommée BaseCalc (calculs de base) fournisse l'arithmétique classique: additions, soustractions, multiplications et divisions. Si toutes ses fonctions sont déclarées virtuelles, et que tous les arguments et types renvoyés sont déclarés comme des chaînes, on peut facilement implémenter des versions héritées de l'objet. L'une, FixedPrecisionCalc (calcul en précision finie), pourrait utiliser les fonctions de la bibliothèque C pour faire les conversions entre chaînes et entiers, et implémenter les calculs en utilisant les opérateurs arithmétiques standard: +, -, *, et /. Une autre, appelée InfinitePrecisionCalc (calcul en précision infinie), pourrait accéder aux arguments des chaînes caractère par caractère, en implémentant les opérations arithmétiques qui sont en principe d'une précision infinie. En écrivant un programme qui utilise partout BaseCalc, l'implémentation peut passer de la précision finie à la précision infinie ou inversement en modifiant une seule ligne: l'endroit où l'objet de calcul est construit. L'objet de recherche
Figure 31
API de la classe de base de recherche Search
La figure 31 montre l'API de la classe de base de l'objet de recherche présenté dans la figure 24. Elle définit deux fonctions membre virtuelles: search() (recherche) et docTargetDocument() (doc document-cible). Comme le signifie le =0 qui suit la déclaration des arguments, il s'agit de fonctions pures -- ce qui signifie qu'une classe qui hérite de cet objet devra implémenter ces deux fonctions, faute de quoi le compilateur se plaindra. La classe comprend également deux champs de données protégés: collectdir (répertoire de collection) et cache (tampon). Un objet de recherche est instancié pour une collection particulière, et le champ collectdir sert à stocker l'endroit du système de fichiers où la collection (et en particulier ses fichiers d'index) se trouve. Le champ cache retient les résultats d'une requête. Il sert à accélérer des requêtes ultérieures qui répéteraient la même requête (et ses paramètres). Il peut sembler improbable qu'on effectue des requêtes identiques, mais dans la pratique c'est un phénomène fréquent. Le protocole de Greenstone est sans état. Pour générer une page de résultats semblable à la figure 25 mais en présentant les résultats 11-20 de la même requête, la recherche est à nouveau transmise, en spécifiant cette fois-ci qu'il faut renvoyer les documents 11-20. L'utilisation de tampon rend ceci efficace, car le fait que cette recherche a déjà eu lieu est détecté et les résultats sont obtenus directement depuis le tampon. Ces deux champs de données s'appliquent à tout objet hérité qui implémente un mécanisme de recherche. C'est pourquoi ils apparaissent dans la classe de base, et ils sont déclarés dans une section protégée de la classe de manière que les classes héritées puissent y accéder directement. Recherche et rapatriement avec MGGreenstone utilise MG (abréviation de «Managing Gigabytes» -- gérer les giga-octets; voir Wittenet al., 1999) pour indexer et rapatrier les documents, et son code source est inclus dans le répertoire GSDLHOME/packages. MG utilise des techniques de compression pour optimiser l'utilisation de l'espace disque sans impacter la vitesse d'exécution. Pour une collection de documents écrits en anglais, le texte compacté et les index de corps du texte occupent en tout, en moyenne, un tiers de l'espace disque requis par le texte original, non compacté. La recherche et le rapatriement sont souvent plus rapides que les opérations équivalentes sur la version non compactée car elles impliquent moins d'opérations sur le disque dur.
Figure 32
API pour accéder directement à MG (abrégée)
L'utilisation normale de MG se fait interactivement, en tapant des commandes à l'invite, et une manière d'implémenter la classe mgsearchclass serait d'utiliser l'appel system() de la bibliothèque C au sein de l'objet pour exécuter les commandes MG appropriées. Mais une approche plus efficace consiste à taper directement dans le code de MG avec des appels de fonctions. Bien que ceci nécessite une meilleure compréhension du code de MG, on peut masquer une grande partie de la complexité derrière une nouvelle API qui deviendra le point de contact pour l'objet mgsearchclass. C'est le rôle du fichier colserver/mgq.c, dont l'API est présentée figure 32. On fournit des paramètres à MG à travers la fonction mgq_ask() (demande mgq), qui prend des options de texte dans un format identique à celui utilisé à la ligne de commande, tel que: mgq_ask( ".set casefold off ");
Il sert aussi à invoquer une requête. On accède à ses résultats à travers la fonction mgq_results (résultats de mgq), qui prend un pointeur vers une fonction comme quatrième paramètre. Ceci fournit une manière souple de convertir l'information renvoyée dans les structures de données de MG en le format requis par mgsearchclass. Des appels tels que mgq_numdocs() (mgq-numéros de documents), mgq_numterms() et mgq_docsretrieved() (respectivement, mgq-numéros de termes et mgq-documents rapatriés) renvoient également des informations, qui sont cette fois plus précisément prescrites. Les deux dernières fonctions gèrent la troncature. L'objet source
Figure 33
API de la classe de base source
Le rôle de l'objet source dans la figure 24 est d'accéder aux méta-données et au texte du document, et l'API de sa classe de base est présentée figure 33. Une fonction membre associe à chaque tâche les fonctions get_metadata() (obtient les méta-données) et get_document() (obtient le document) , respectivement. Toutes deux sont déclarées virtual, la version fournie par une implémentation particulière de la classe de base n'est donc appelée qu'au moment de l'exécution. Une version héritée de cet objet utilise GDBM pour implémenter get_metadata() et MG pour implémenter get_document(): nous détaillons cette version ci-dessous. On trouve d'autres fonctions membre dans la figure 33, telles que configure(), init(), et translate_OID() (traduire l'identifiant d'objet). Les deux premières sont liées au processus d'initialisation décrit section 3.9. La dernière, translate_OID(), gère la syntaxe pour exprimer les identifiants de documents. Nous avons vu figure 26 comment on pouvait ajouter un numéro de page à un identifiant de document pour ne rapatrier que la page correspondante. Ceci est possible car les pages ont été stockées en tant que «sections» lors de la construction de la collection. Ajouter «.1» à un OID rapatrie la première section du document correspondant. Les sections peuvent être imbriquées; on y accède alors on concaténant les numéros de sections et en séparant les numéros par des points. En plus des numéros hiérarchiques de sections, la syntaxe de l'identifiant de document permet des accès relatifs. Par rapport à la section actuelle du document il est possible d'accéder aupremier fils(first child) en ajoutant .fc, audernier fils(last child) en ajoutant .lc, auparenten ajoutant .pr, aufrère suivant(next sibling) en ajoutant .ns, et aufrère précédent(previous sibling) en ajoutant .ps. La fonction translate_OID() utilise les paramètres OIDin (OID en entrée) et OIDout (OID en sortie) pour renfermer la source et le résultat de la conversion. Elle prend aussi deux autres paramètres, err (erreur) et logout (journal en sortie). Ils communiquent tout état d'erreur qui peut se produire lors de l'opération de traduction, et déterminent où envoyer les informations de journalisation. Ces paramètres dépendent étroitement du protocole, comme nous le verrons dans la section 3.7. Rapatriement de base de données avec gdbm GDBM est le gestionnaire de bases de données de GNU (www.gnu.org). Il implémente une structure d'enregistrements plats de couples clef/données, et il est compatible en arrière avec DBM et NDBM. Les opérations fournies comprennent le stockage, le rapatriement, et la destruction d'enregistrements par clef, et un parcours non ordonné de toutes les clefs.
Figure 34
Base de données GDBM pour la collection (extrait)
La figure 34 montre un extrait de la base de données d'informations de la collection créée lors de la construction de la collection Gutenberg. Cet extrait fut produit à l'aide de l'outil Greenstone db2txt, qui convertit le format binaire de base de données GDBM sous forme textuelle. La figure 34 contient trois enregistrements, séparés par des lignes horizontales. Le premier est une entrée de document, les deux autres sont des portions de la hiérarchie créées par le classificateur AZList pour les titres de la collection. La première ligne de chaque enregistrement est sa clef. L'enregistrement de document stocke le titre du livre, son auteur, et toute autre méta-donnée fournie (ou extraite) lors de la construction de la collection. Il contient aussi des valeurs pour usage interne: où les fichiers associés à ce document se trouvent (<archivedir>) et le numéro de document utilisé de manière interne par MG (<docnum>). Le champ <contains> (contient) stocke une liste d'éléments, séparés par des points-virgules, qui pointent vers des enregistrement relatifs dans la base de données. Pour un enregistrement de document, <contains> sert à pointer vers les sections imbriquées. On formera des clefs d'enregistrement en concaténant la clef courante à l'un des éléments fils (le séparateur étant un point). Le deuxième enregistrement de la figure 34 est le noeud principal de la hiérarchie de classification de titres A-Z. Ses enfants, auxquels on accède à travers le champ <contains>, comprennent CL1.1, CL1.2, CL1.3 etc., et correspondent aux pages individuelles pour les lettres A, B, C, etc. Il n'en existe que 24: le classificateur AZList a rassemblé les lettres Q-R et Y-Z car elles ne concernaient que peu de titres. Les enfants du champ <contains> du troisième enregistrement, CL1.1, sont les documents proprement dits. On peut trouver des structures plus compliquées -- le champ <contains> peut inclure un mélange de documents et d'autres noeuds CL. Les clefs exprimées relativement à la clef courante se reconnaissent des clefs absolues car elles commencent par une apostrophe double. ("). Utiliser MG et GDBM pour implémenter un objet source
Figure 35
API de la version de sourceclass basée sur MG et GDBM (abrégée)
L'objet qui rassemble MG et GDBM pour réaliser une implémentation de sourceclass s'appelle mggdbmsourceclass. La figure 35 présente son API. Les deux fonctions membre set_gdbmptr() et set_mgsearchptr() (respectivement, positionne le pointeur gdbm et recherche le pointeur mg) stockent des pointeurs vers leurs objets respectifs, de sorte que les implémentations de get_metadata() (obtient les méta-données) et get_document() (obtient le document) puissent accéder aux outils appropriés pour mener leur tâche à bien. L'objet de filtre
Figure 36
API de la classe de base de filtre
L'API de la classe de base de l'objet de filtre de la figure 24 est présentée dans la figure 36. Elle commence par les champs de données protégés gsdlhome, collection, et collectdir, fréquents dans les classes qui ont besoin d'accéder à des fichiers propres à des collections.
mggdbsourceclass est une autre classe qui inclut ces trois champs de données. Les fonctions membre configure() et init() (d'abord vues dans la fonction sourceclass) sont utilisées par le processus d'initialisation. L'objet lui-même est intimement aligné avec la portion de filtre lui correspondant dans le protocole; en particulier les fonctions get_filteroptions() et filter() correspondent exactement.
Figure 37
Manière de stocker une option de filtre
Les deux classes présentées dans la figure 37 sont centrales pour les options de filtre. FilterOption_t (filtre d'option) stocke le nom de l'option, son type, et si elle peut ou non être répétée (repeatable). validValues est interprété selon le type de l'option. Pour un type booléen, la première valeur est la valeur fausse false, la deuxième valeur est la valeur vraie true. Pour un type entier, la première valeur est la valeur minimale, la deuxième valeur est la valeur maximale. Pour un type énuméré toutes les valeurs sont listées. Pour un type de chaîne la valeur est ignorée. Pour des situations plus simples, on utilise OptionValue_t (valeur d'option), qui enregistre sous forme de text_t le nom de l'option et sa valeur. Les objets de requête et de réponse passés en paramètres à filterclass sont construits à partir de ces deux classes, en utilisant des tableaux associatifs pour stocker un ensemble d'options telles que les options nécessaires à la fonction InfoFilterOptionsResponse_t. On peut trouver des détails complémentaires dans le fichier GSDLHOME/src/recpt/comtypes.h. Objets de filtre hérités
Figure 38
Hiérarchie d'héritage pour l'objet de filtre
Les filtres utilisent deux niveaux d'héritage, comme illustré dans la figure 38. Tout d'abord on distingue les filtres de requête et de navigation, et il existe pour les premiers une implémentation spécifique, fondée sur MG. Pour fonctionner correctement, mgqueryfilterclass doit accéder à MG à travers mgsearchclass et à GDBM à travers gdbmclass. browsefilterclass n'a besoin que d'accéder à GDBM. Les pointeurs vers ces objets sont stockés sous la forme de champs de données protégés au sein des classes respectives. Code du serveur de collectionVoici les fichiers d'en-têtes du répertoire GSDLHOME/src/colservr, suivis de leur description. Le nom de fichier correspond généralement au nom de l'objet qu'il renferme.
3.7 Le protocole
Table 18
Liste des appels de protocole
La table 18 liste les appels de fonction au protocole, en résumant chaque entrée. Les exemples donnés section 3.3 ont couvert la plupart de ces appels. Les fonctions non mentionnées précédemment sont les fonctions has_collection(), ping(), get_protocol_name() et get_filteroptions(). Les deux premières répondent par oui ou par non aux questions «la collection existe-t-elle sur ce serveur?» et «est-elle en cours de fonctionnement?», respectivement. Le but des deux autres est de supporter des protocoles multiples au sein d'une architecture distribuée sur des ordinateurs différents, et non pas le simple exécutable fondé sur le protocole vide et décrit ici. L'une d'entre elles fait une distinction selon le protocole en cours d'utilisation. L'autre permet à un réceptionniste d'interroger un serveur de collection pour trouver les options supportées, afin de s'auto-configurer dynamiquement pour profiter des services offerts par un serveur particulier.
Figure 39
API du protocole vide (abrégée)
La figure 39 montre l'API pour le protocole vide. Les commentaires, ainsi que certains détails de bas niveau, ont été omis (consultez le fichier source, c'est-à-dire recpt/nullproto.h, pour avoir tous les détails). Ce protocole hérite de la classe de base recptproto. On utilise l'héritage virtuel de telle sorte que plus d'un type de protocole -- y compris des protocoles pas encore conçus -- puisse être facilement supporté dans le reste du code source. Ceci est possible car l'objet de classe de base recptproto est utilisé tout au long du code source, à l'exception de l'endroit de la construction. Nous spécifions ici la véritable variété de protocole que nous souhaitons utiliser -- dans ce cas-ci, le protocole vide. À l'exception de get_protocol_name(), qui ne prend aucun paramètre et renvoie le nom du protocole sous la forme d'une chaîne au format Unicode, toutes les fonctions du protocole incluent un paramètre d'erreur et un flux de sortie en tant que leurs deux derniers arguments. Le paramètre d'erreur enregistre toute erreur qui se produit pendant l'exécution de l'appel de protocole, et le flux de sortie est utilisé à des fins de journalisation. Les fonctions sont de type void--elles ne renvoient pas explicitement des informations dans leur dernière instruction, mais renvoient plutôt des données à travers des paramètres désignés tels que le paramètre d'erreur (dont on vient de parler). Dans certains langages de programmation, de tels sous-programmes s'appelleraient «procédures» et non «fonctions», mais le C++ n'opère pas de telle distinction syntaxique. La plupart des fonctions prennent le nom de la collection en argument. Trois des fonctions membre (les fonctions get_filteroptions(), filter(), et get_document()) suivent le schéma de fournir un paramètre de requête et de recevoir les résultats dans un paramètre de réponse. 3.8 Le réceptionnisteC'est la dernière couche du modèle conceptuel. Après analyse des arguments du CGI, l'activité principale est l'exécution d'une action, assistée par les objets de mise en forme et de langage de macros. Ces derniers sont décrits plus bas. Bien qu'ils soient représentés comme des objets dans le cadre conceptuel, les objets de mise en forme et de langage de macros ne sont pas strictement des objets au sens du C++. En fait, l'objet de mise en forme est une collection de structures de données et un ensemble de fonction qui opère sur ces dernières, et l'objet de langage de macros est construit autour de displayclass, définie dans lib/display.h, avec un support de conversion de flux provenant de lib/gsdlunicode.h. Les actions
Table 19
Les actions dans Greenstone
Greenstone supporte les onze actions résumées dans la table 19.
Figure 40
Utilisation de cgiargsinfoclass depuis pageaction.cpp
Les arguments CGI nécessaires à une action sont formellement déclarés dans sa fonction constructeur avec cgiarginfo (définie dans recpt/cgiargs.h). La figure 40 montre un extrait de la fonction constructeur pageaction, qui définit la taille et les propriétés des arguments CGI a et p. Pour chaque argument CGI, le constructeur doit spécifier son nom court (lignes 2 et 10), qui est le nom de la variable CGI à proprement parler; un nom long (lignes 3 et 11) qui est utilisé pour fournir une description plus parlante de l'action; s'il représente une valeur de caractère simple ou multiple (lignes 4 et 12); possiblement, une valeur par défaut (lignes 5 et 13); ce qui se produit quand plusieurs valeurs par défaut sont fournies (lignes 6 et 14, étant donné qu'on peut positionner des valeurs par défaut dans les fichiers de configuration); et s'il faut ou non que la valeur soit conservée à la fin de cette action (lignes 7 et 15). Étant donné qu'elle est embarquée dans le code, on peut générer automatiquement des pages web qui détaillent cette information. L'action statusaction produit cette information, et on peut la visualiser en saisissant l'URL de la page d'administration de Greenstone. Les douze actions héritées sont construites dans main(), la fonction de premier niveau de l'exécutable library, dont la définition est donnée dans le fichier recpt/librarymain.cpp. C'est aussi là que l'objet receptionist (défini dans recpt/receptionist.cpp) est construit. La responsabilité de toutes les actions est passée à l'objet receptionist, qui les traite en maintenant, sous la forme d'un champ de données, un tableau associatif de la classe de base d'action, indexé par les noms d'actions.
Figure 41
API de la classe de base d'action
La figure 41 montre l'API de la classe de base d'action. Lors de l'exécution d'une action, l'objet receptionist appelle plusieurs fonctions, en commençant par check_cgiargs(). La plupart l'aident à vérifier, positionner, et définir des valeurs et des macros, alors que la fonction do_action() engendre pour de bon la page produite. Si un objet hérité particulier ne dispose d'aucune définition pour une fonction membre donnée, il passe à la définition de la classe de base qui implémente un comportement par défaut approprié. Voici des explications des fonctions membre:
Au début de la définition de classe, argsinfo est le champ de données protégé (utilisé dans l'extrait de code représenté dans la figure 40) qui stoke les informations d'argument CGI spécifiées dans une fonction constructeur d'action héritée. L'autre champ de données, gsdlhome, enregistre GSDLHOME pour pouvoir y accéder plus facilement[4]. L'objet inclut également les fonctions configure() et init() à des fins d'initialisation. Mise en forme
Figure 42
Structures de données centrales de la classe de mise en forme
Bien que la mise en forme soit représentée comme une seule entité dans la figure 24, elle constitue en réalité une collection de structures de données et de fonctions, rassemblées dans le fichier d'en-têtes recpt/formattools.h. Les structures de données centrales de la classe sont représentées figure 42.
Figure 43
Structures de données construites pour l'exemple d'instruction de mise en forme
L'implémentation est plus facile à expliquer avec un exemple. Quand l'instruction de mise en forme format CL1Vlist
"[link][Title]{If}{[Creator], par [Creator]}[/link]" est lue dans un fichier de configuration de collection, elle est analysée par les fonctions de formattools.cpp et la structure de données interconnectée montrée figure 43 est construite. Quand il faut faire évaluer l'instruction de mise en forme par une action, la structure de données est traversée. Le chemin pris au niveau des noeuds comIf et comOr dépend des méta-données renvoyées par un appel au protocole. Il se peut que lors du rapatriement de méta-données, le résultat contienne d'autres macros et syntaxes de mise en forme. Ceci est géré par des allers-retours entre l'analyse et l'évaluation, en fonction des besoins. Le langage de macrosL'entité de langage de macros de la figure 24, tout comme celle de mise en forme, ne correspond pas à une unique classe C++. Dans ce cas-ci il existe une classe centrale, mais l'implémentation du langage de macros dépend aussi de fonctions et de classes de support. Ici encore, on expliquera mieux l'implémentation en utilisant un exemple. Donnons d'abord quelques définitions d'échantillons de macros qui illustrent les priorités entre macros, puis -- à l'aide d'un diagramme -- nous décrirons les structures de données de base construites pour supporter cette activité. Enfin, nous présenterons et décrirons les fonctions membre publiques de displayclass, l'objet de macro de premier niveau.
Figure 44
Illustration de la priorité entre les macros
Dans une collection Greenstone habituelle, la priorité entre les macros est normalement: c (pour la collection) passe avant v (pour une interface graphique ou textuelle), qui passe avant l (pour la langue). Ceci est mis en place par la ligne macroprecedence c,v,l
dans le fichier de configuration principal main.cfg. Les instructions de macros de la figure 44 définissent des exemples de macros pour l'en-tête _header_ du paquetage de requête pour diverses valeurs de c, v, et l. Si les arguments CGI donnés lors de l'invocation d'une action comprennent c=hdl, v=1, et l=en, la macro _header_[v=1] serait alors sélectionnée pour l'affichage. Elle serait sélectionnée avant _content_[l=en] car v a la priorité sur l. La macro _content_[l=fr,v=1,c=hdl] ne serait pas sélectionnée parce que le paramètre de page pour l est différent.
Figure 45
Structures de données représentant les macros par défaut
La figure 45 montre la structure de données principale construite lors de la lecture des fichiers de macros spécifiés dans etc/main.cfg. Il s'agit essentiellement d'un tableau associatif de tableaux associatifs de tableaux associatifs. Le niveau le plus élevé (à gauche) indexe le paquetage dont provient la macro, et le deuxième niveau indexe le nom de la macro. Le dernier niveau indexe tous les paramètres spécifiés, en stockant chacun sous le type mvalue qui enregistre, en plus de la valeur de la macro, le fichier dont elle provient. Par exemple, on peut trouver le texte défini pour _header_[l=en] dans la figure 44 stocké dans le plus bas des deux enregistrements mvalue dans la figure 45.
Figure 46
API de la classe d'affichage displayclass
L'objet central de support du langage de macros est displayclass, défini dans lib/display.h. Ses fonctions membre publiques sont représentées figure 46. La classe lit les fichiers de macros spécifiés à l'aide de loaddefaultmacros(), en stockant dans une section protégée de la classe (non représentée), le type de la structure de données montrée figure 45. Il est également permis au système d'exécution de positionner des macros à l'aide de setmacro() (dans le dernier exemple de la section 3.3, pageaction positionne _homeextra_ comme étant la table des collections dynamiquement générée en utilisant cette fonction). Ceci est supporté par un ensemble de tableaux associatifs similaires à ceux utilisés pour représenter les fichiers de macros (ce n'est pas identique, car le premier n'a pas besoin d'une couche de «paramètres»). Dans displayclass, Les macros lues dans le fichier s'appellent lesmacros par défaut. Les macros locales spécifiées à travers setmacro() s'appellentmacros courantes, et sont effacées de la mémoire après la génération de la page. Quand il faut produire une page, openpage() est d'abord appelée pour communiquer les réglages courants des paramètres de page (l=en etc.). Ensuite, le texte et les macros passent dans un flux à travers la classe -- typiquement depuis une actionclass -- en utilisant du code tel que: cout << text_t2ascii << display << "_amacro_ "
<< "_anothermacro_ ";
Le résultat est que les macros sont développées selon les réglages des paramètres de page. Si nécessaire, ces réglages peuvent être modifiés en cours de procédure à l'aide d'une action en utilisant setpageparams(). Les fonctions membre publiques restantes fournissent le support de bas niveau. Le code du réceptionnisteNous avons maintenant décrit les objets principaux du réceptionniste. Nous détaillons ci-dessous les classes de support, situées dans GSDLHOME/src/recpt. À l'exception des cas où l'efficacité prime -- les définitions sont alors inline -- les détails d'implémentation sont contenus dans le fichier .cpp correspondant au fichier d'en-têtes. Les fichiers de support comportent souvent le mot tool (outil) dans leur nom, comme par exemple OIDtools.h et formattools.h. Un autre ensemble de fichiers de portée lexicale comprend le préfixe z3950. Ces fichiers fournissent un accès distant aux bases de données et aux catalogues en ligne publiquement accessibles à travers le protocole Z39.50. Le terme browserclass est inclus dans un autre groupe important de fichiers de support. Ces fichiers sont liés à travers une hiérarchie d'héritage virtuel. En tant que groupe, ils supportent une notion abstraite de navigation: génération de pages en série comportant des contenus de documents compartimentés ou des méta-données. Les possibilités des navigation comportent la lecture de documents triés par ordre alphabétique des titres ou par ordre chronologique des dates; l'exploration des résultats d'une requête par lot de dix entrées; et l'accès aux pages individuelles d'un livre en utilisant le mécanisme aller à la page.... Chaque possibilité de navigation hérite de la classe de base, browserclass:
Les actions accèdent aux objets browserclass à travers browsetools.h.
3.9 InitialisationDans Greenstone, l'initialisation est une opération compliquée qui traite les fichiers de configuration et affecte des valeurs par défaut aux champs de données. En plus des fonctions d'héritage et constructeur, les objets centraux définissent les fonctions init() et configure() pour faciliter la normalisation de la tâche. Même ainsi, l'ordre d'exécution peut être difficile à suivre. La présente section décrit ce qui se passe. Greenstone utilise plusieurs fichiers de configuration pour des raisons différentes, mais tous suivent la même syntaxe. À moins qu'une ligne ne contienne que des blancs ou commence par un caractère dièse (#), le premier mot définit un mot-clef et les mots suivants représentent une configuration particulière pour ce mot-clef. Les lignes des fichiers de configuration sont passées une à une à la fonction configure() sous la forme de deux arguments: le mot-clef et un tableau des mots restants. En se fondant sur le mot-clef, un version particulière de la fonction configure() décide si l'information l'intéresse, et dans l'affirmative, la stocke. Par exemple, collectserver (qui correspond à l'objet de collection de la figure 24) traite les instructions de mise en forme du fichier de configuration de collection. Quand la fonction configure() reçoit le mot-clef format, elle déclenche une instruction if qui stocke dans l'objet une copie du deuxième argument de la fonction. Après le traitement du mot-clef et avant de rendre la main, certaines versions de configure() passent les données aux fonctions configure() d'autres objets. L'objet réceptionniste appelle les fonctions configure() des objets d'actions, de protocoles, et de navigation. L'objet de protocole vide appelle la fonction configure() de chaque objet de collection; l'objet de collection appelle les objets de filtre et source. En C++, les champs de données sont normalement initialisés par la fonction qui construit l'objet. Cependant, dans Greenstone, certaines initialisations dépendent de valeurs lues dans des fichiers de configuration, il faut donc procéder à un deuxième tour d'initialisations. C'est le but des fonctions membre init(), et dans certains cas cela mène à d'autres appels de fonctions configure().
Figure 47
Initialisation de Greenstone avec le protocole vide
Les lignes 47 présentent les messages de diagnostics générés par une version de Greenstone configurée pour mettre en valeur le processus d'initialisation. Le programme démarre à la fonction main() du fichier recpt/librarymain.cpp. Il construit un objet de réceptionniste et un objet de protocole vide, puis parcourt le fichier gsdlsite.cfg (situé dans le même répertoire que l'exécutable library) à la recherche de gsdlhome et stocke son résultat dans une variable. Pour chaque collection en ligne -- liste établie en lisant les répertoires présents dans GSDLHOME/collect -- le programme construit un objet de collection, à travers l'objet de protocole vide, qui contient des objets de filtre, de recherche et source, ainsi que quelques appels câblés à la fonction configure(). La fonction main() ajoute ensuite l'objet de protocole vide au réceptionniste, qui conserve un tableau de classe de base de protocoles dans un champ de données protégé, et positionne ensuite plusieurs convertisseurs. La fonction main() construit tous les objets d'action et de navigation utilisés dans l'exécutable et les ajoute à l'objet réceptionniste. La fonction conclut en appelant la fonction cgiwrapper() de cgiwrapper.cpp, qui comporte elle-même une certaine quantité d'initialisation d'objets. La fonction cgiwrapper() comprend trois parties: configuration, initialisation, et génération de page. Tout d'abord, quelques appels câblés à la fonction configure() sont effectués. Le fichier gsdlsite.cfg est ensuite lu et la fonction configure() est appelée pour chacune de ses lignes. Même chose pour le fichier etc/main.cfg. La deuxième phase de la fonction cgiwrapper() effectue des appels à init(). L'objet réceptionniste ne fait qu'un appel à sa fonction, mais cette invocation appelle les fonctions init() des différents objets qu'il contient. Un appel câblé à configure() est d'abord effectué pour positionner collectdir, puis les fichiers de macros sont lus. La fonction init() de chaque action est appelée. Même chose pour chaque protocole utilisé dans le réceptionniste -- mais dans le cas du système décrit ici, seul le protocole vide y est stocké. L'appel de la fonction init() de cet objet provoque d'autres configurations: pour chaque collection du protocole vide, les fichiers propres à la collection build.cfg et collect.cfg sont lus et traités, chaque ligne provoquant un appel à la fonction configure(). La phase finale de cgiwrapper() consiste à analyser les arguments CGI, et appeler ensuite l'action appropriée. Tous ces appels sont effectués avec le support de l'objet réceptionniste. Les codes de configuration, initialisation, et de génération de page sont séparés car Greenstone est optimisé pour fonctionner en tant que serveur (avec Fast-CGI, ou le protocole CORBA, ou la version «Bibliothèque locale» sous Windows). Dans ce mode de fonctionnement, le code de configuration et d'initialisation n'est effectué qu'une fois, et le programme demeure ensuite en mémoire et génère de nombreuses pages web en réponse aux requêtes des clients, sans nécessiter de réinitialisation. 4 Configurer son site GreenstoneDans Greenstone, deux fichiers de configuration sont utilisés pour configurer divers aspects du site Greenstone. Il s'agit du fichier de configuration «principal» main.cfg, qui se trouve dans GSDLHOME/etc, et du fichier de configuration «de site» gsdlsite.cfg, qui se trouve dans GSDLHOME/cgi-bin. Ces fichiers contrôlent tous deux des aspects spécifiques de la configuration du site, et tous deux peuvent être visualisés depuis la page d'administration de Greenstone. 4.1 Fichier de configuration principalLe fichier de configuration principal main.cfg sert à configurer le réceptionniste -- la partie de Greenstone qui présente les requêtes et affiche les pages. Vous pouvez tout contrôler, des langues que l'interface peut utiliser aux journaux qui seront conservés. Maintenance du site et journalisationLes lignes du fichier de configuration dictent la manière dont votre site Greenstone sera maintenu, quelles fonctionnalités il offrira, quels événements seront journalisés, et quelles notifications seront faites au mainteneur. La table 20 détaille certaines des options disponibles; les options restantes sont décrites dans les sections suivantes.
Table 20
Options de configuration pour la maintenance et la journalisation
Support des languesLe fichier de configuration main.cfg contient deux types d'entrées qui affectent la gestion des différentes langues. Elles déterminent quelles langues et quels encodages seront disponibles dans la page de Préférences. Les lignes encoding (encodage) spécifient les différents types d'encodage de caractères qui peuvent être sélectionnés. Les lignes language (langue) spécifient quelles langues on pourra sélectionner pour l'interface utilisateur (il doit bien sûr exister une macro de langue pour chaque langue possible). La ligne encoding peut contenir quatre valeurs possibles: shortname (nom court), longname (nom long), map (correspondance), et multibyte (multi-octets). La valeur shortname est l'étiquette du jeu de caractères standard, et doit être spécifiée pour tous les encodages. La valeur longname donne le nom d'encodage spécifié sur la page de Préférences. En son absence la valeur par défaut est celle de shortname. La valeur map est obligatoire pour tous les encodages à l'exception de l'UTF-8, qui est géré de manière interne (et qui devrait toujours être activé). La valeur multibyte devrait être positionnée pour tous les jeux de caractères qui nécessitent plus d'un octet par caractère. Le fichier main.cfg spécifie de nombreux encodages, dont la plupart sont désactivés car commentés. Pour activer un encodage, ôtez le caractère de commentaire «#». Chaque ligne language peut contenir trois valeurs possibles: shortname (nom court), longname (nom long), et default_encoding (encodage par défaut). La valeur shortname est le symbole de langue en deux lettres ISO 639, et elle est obligatoire. La valeur longname donne le nom de la langue spécifié sur la page de Préférences. En son absence la valeur par défaut est celle de shortname. L'option default_encoding sert à spécifier l'encodage préféré pour cette langue. Paramètres de page et arguments CGIOn peut définir des paramètres de page et des arguments CGI dans le fichier de configuration main.cfg. Rappelez-vous qu'à la figure 40 la plupart des arguments CGI sont définis au sein même du code C++ de la bibliothèque. Cependant, il est parfois utile de définir de nouveaux arguments ou d'éditer les arguments existants dans les fichiers de configuration, ce qui évite de recompiler la bibliothèque. Pour ce faire, vous utiliserez l'option de configuration cgiarg. Elle peut prendre jusqu'à six arguments, qui sont les suivants: shortname (nom court), longname (nom long), multiplechar (caractères multiples), argdefault (argument par défaut), defaultstatus (état par défaut), et savedarginfo (informations de sauvegarde d'argument). Ces arguments correspondent aux options d'arguments CGI décrits section 3.8. Par exemple, dans le fichier main.cfg, par défaut, l'option de configuration cgiarg sert à positionner les valeurs par défaut des arguments CGI existants a et p à p et home, respectivement. Les paramètres de page sont un cas particulier d'arguments CGI qui correspondent aux paramètres des fichiers de macros de Greenstone. Par exemple, l'argument CGI l correspond directement au paramètre l= dans les fichiers de macros. On utilise l'option de configuration pageparam pour définir un argument CGI comme étant également un paramètre de page. La meilleure manière d'apprendre les différentes options de configuration possibles dans le fichier de configuration main.cfg est de faire des expériences avec ce dernier. Souvenez-vous que si vous utilisez la version «Bibliothèque locale» de Greenstone sous Windows, il faut redémarrer le serveur pour que toute modification des fichiers de configuration soit prise en compte. 4.2 Fichier de configuration de site
Table 21
Lignes du fichiergsdlsite.cfg
Le fichier de configuration de site gsdlsite.cfg positionne des variables utilisées par le logiciel de bibliothèque et le serveur web au moment de l'exécution, et se trouve dans le même répertoire que le programme library. La table 21 décrit les lignes de ce fichier; elles sont expliquées dans la section 5 du Guide d'installation de la bibliothèque numérique Greenstone. A. La bibliothèque standard de patrons (templates) pour C++La bibliothèque standard de patrons (STL) est une bibliothèque bibliothèque très répandue de code C++, développée par Silicon Graphics (www.sgi.com). Cette annexe donne un bref aperçu de ses fonctions principales, utilisées tout au long du code de Greenstone. Pour une description plus détaillée, consultez le manuel de référence officiel de STL, disponible en ligne sur le site webwww.sgi.com, ou l'un des nombreux manuels traitant de STL, tel que celui de Josuttis (1999). Comme le suggère le mot «patron», STL n'est pas juste une bibliothèque d'objets prêts à l'emploi. Couplée avec le mécanisme de patrons de C++, elle fournit aux programmeurs une solution pour développer leurs propres objets de manière concise, objets qui tapent dans les fonctionnalités algorithmiques embarquées dans STL. Voilà qui ajoute une couche de complexité, mais cela en vaut la peine. Pour aider à comprendre les extraits de code Greenstone donnés dans le présent manuel, nous donnons quelques exemples de STL à des fins de didacticiel. A..1 Listes
Figure 48
Programmer une liste d'entiers
Étudions tout d'abord deux programmes qui implémentent une liste d'entiers. L'un utilise des types C++ de base (la «bonne vieille manière de faire»), tandis que l'autre utilise STL. La figure 48 montre le code source de l'implémentation qui n'utilisepasSTL. Les lignes 5-8 définissent les structures de données de base que nous allons utiliser: le champ val stocke la valeur de l'entier, et next (prochain) pointe vers le prochain élément de la liste -- une implémentation classique d'une liste chaînée, en somme. Pour illustrer l'utilisation de la structure de données, le programme principal (lignes 23-32) initialise une liste d'entiers avec les éléments [5, 4]. Il appelle ensuite la fonction total_int_list (total des entiers de la liste, définie lignes 10-21), fonction qui prend pour unique argument un pointeur vers la tête d'une liste et qui fait la somme de toutes les valeurs que la liste contient. La valeur renvoyée («9», dans notre cas) est affichée à l'écran. Le gros du travail est accompli par les lignes 12-18. On commence par un peu d'initialisation: la variable locale total est mise à zéro, et curr (courant) pointe vers le début de la liste. Une boucle while ajoute ensuite l'élément entier courant au sous-total courant (total += curr->val;) avant de passer au prochain élément (curr = curr->next;). La boucle while termine quand curr vaut nil (vide), ce qui signifie qu'il ne reste plus aucun élément de la liste à traiter.
Figure 49
Programmer une liste d'entiers en utilisant STL
La figure 49 montre un programme équivalent qui utilise STL. Il n'est plus nécessaire de définir une structure de données adéquate dans le code; seule la directive #include <list> de la ligne 2, qui inclut le patron de liste défini dans STL, est nécessaire. L'objet est appelé une «classe de contenance» car lors de la déclaration d'une variable de ce type on spécifie aussi le type qu'on souhaite qu'elle stocke. On réalise une liste d'entiers ligne 19 avec l'instruction list<int> vals;. On peut ajouter des éléments à l'objet en utilisant la fonction membre push_back(), comme dans les lignes 20-21. Le gros du travail est accompli par les lignes 6-12. On commence toujours deux initialisations et une boucle while, mais à part cela la nouvelle syntaxe a fort peu en commun avec l'ancienne. Cette nouvelle manière de faire les choses gravite autour d'une variable de type iterator (itérateur, ligne 7). De nombreuses classes STL incluent des types iterator pour fournir une manière uniforme de traverser une suite d'objets de contenance. Le premier élément est renvoyé avec begin() (début) et l'élément qui suit le dernier élément est renvoyé avec end(). On passe à l'élément suivant par l'opération d'incrémentation ++, qui est surchargée par la classe d'itération pour implémenter cette tâche, et on accède à la valeur stockée par déréférenciation (*curr, ligne), opération elle aussi surchargée. L'implémentation STL de ce programme est un peu plus concise que le code conventionnel (25 lignes, à comparer aux 31 originales). Les gains sont plus importants dans des projets plus volumineux, car l'objet list (liste) de STL est plus puissant que ce que cet exemple en illustre ici. C'est par exemple une liste doublement chaînée qui supporte diverses manières d'insérer et d'effacer -- et il faudrait des efforts de programmation supplémentaires pour intégrer ces fonctionnalités à la version de liste d'entiers classique. Remarquez que le paramètre total_int_list de la figure 49 a été implémenté sous la forme d'un entier, pour correspondre au pointeur utilisé dans la variable total_int_list dans la figure 48. En STL, il est souvent plus naturel (et plus souhaitable) d'utiliser des références plutôt que des pointeurs. Le paramètre devient alors list<int>& head, (tête), et ses fonctions membre sont appelées par la syntaxe head.begin(); (début de tête) et ainsi de suite. A..2 CorrespondancesLorsque l'on implémente un système de bibliothèque numérique, il est utile de pouvoir stocker des éléments dans un tableau indicé par des chaînes de texte plutôt que par des nombres. Dans Greenstone, par exemple, ceci simplifie grandement le stockage des fichiers de macros après leur lecture; de même pour les divers fichiers de configuration. Un type de données qui permet un tel accès s'appelle untableau associatif, et les langages de programmation modernes de haut niveau en proposent souvent. On l'appelle aussi parfoistableau de hachage(surtout en Perl), puisque la technique habituelle d'implémentation d'un index de texte est de hacher (calculer une somme de contrôle) les valeurs du tableau associatif.
Figure 50
Utiliser des tableaux associatifs en STL
En STL, on fait des tableaux associatifs en utilisant l'objet map (carte, ou correspondance). La figure 50 présente un exemple quelque peu artificiel qui stocke l'âge de trois personnes (Alice, Pierre, et Marie) dans un tableau associatif indicé par leurs prénoms (lignes 19-22). Le problème est d'écrire une fonction qui calcule l'âge total de toutes les personnes présentes, sans savoir combien elles sont ni qui elles sont. Bien sûr, on pourrait résoudre ce problème avec un classique tableau d'entiers indicés numériquement. L'exemple est contraint d'illustrer les fonctionnalités de l'objet map et de mettre en valeur les similarités de traitement avec l'objet list équipé d'un iterator. Tout comme list, map est une classe de contenance. Cependant, lorsque l'on déclare une variable de ce type, il faut spécifier deux[5]choses: le type d'index, et le type d'élément. Comme on peut le voir ligne 19, on obtient un tableau associatif qui stocke des entiers indicés par des chaînes en écrivant char* (c'est la manière de déclarer une chaîne en C++) en tant que type d'indiçage suivi de int en tant que type d'élément. Il existe plusieurs manières de stocker des éléments dans le tableau associatif. Dans l'exemple, on utilise lignes 20-22 l'indice de tableau [ ], qui est surchargé, pour initialiser le tableau avec les âges des trois personnes. La ressemblance entre total_int_table -- qui effectue le calcul principal dans le programme -- et total_int_list de la figure 48 est frappante. Ces deux objets sont en fait presque identiques, et ce n'est pas une coïncidence. STL utilise lourdement l'héritage de sorte que des objets différents utilisent encore les mêmes opérations fondamentales. C'est particulièrement le cas des itérateurs (iterator). Les petites différences entre les deux fonctions sont que l'itérateur est maintenant tiré de map<char*, int>, et que l'accès à ses éléments se fait avec curr->second() -- en effet la déréférenciation de la variable (*curr) est définie comme devant renvoyer un objet de type pair. Ceci enregistre à la fois le nom d'index (first, ou «premier») et la valeur de l'élément (second, ou «deuxième»), mais seul la deuxième nous intéresse. À part cela, le code est identique. La seule différence restante -- le changement de l'unique argument de la fonction d'un pointeur vers une référence -- est superficielle. Greenstone utilise largement deux autres types STL: vector (vecteur), et set (ensemble). Le premier facilite les tableaux dynamiques, et le second supporte les opérations ensemblistes mathématiques telles que l'union, l'intersection, et la différence ensembliste. BibliographieAulds, C. (2000) Linux Apache Web Server Administration. Sybex. Bainbridge, D., Buchanan, G., McPherson, J., Jones, S., Mahoui, A. and Witten, I.H. (2001) «Greenstone: A platform for distributed digital library development». Rapport de recherche, département d'informatique, université de Waikato, Nouvelle-Zélande. Christiansen, T. Torkington, N. and Wall, L. (1998) Perl en action. Éditions O'Reilly. Coar, K.A.L. (1998) Apache Server For Dummies. IDG Books. Deitel, H.M. and Deitel, P.J. (1994) C++: How to Program. Prentice Hall, Englewood Cliffs, New Jersey. Dublin Core (2001) «The Dublin Core Metadata Initiative» at http://purl.org/dc/, le 16 janvier 2001. Josuttis, N.M. (1999) The C++ standard library: a tutorial and reference. Addison-Wesley, 1999. Keller, M. and Holden, G. (1999) Apache Server for Windows Little Black Book. Coriolis Group. Schwartz, R.L. and Christiansen, T. (1997) Introduction à Perl (2ème édition). Éditions O'Reilly. Slama, D., Garbis, J. and Russell, P. (1999) Enterprise CORBA. Prentice Hall, Englewood Cliffs, New Jersey. Stroustrup, B. (1997) The C++ Programming Language. Addison-Wesley. Thiele, H. (1997) «The Dublin Core and Warwick Framework: A Review of the Literature, March 1995-September 1997»D-Lib Magazine, janvier.<http://www.dlib.org/dlib/january98/01thiele.html> Wall, L., Christiansen, T. and Orwant, J. (2000) Programmation en Perl (3ème édition). Éditions O'Reilly. Weibel, S. (1999) «The State of the Dublin Core Metadata Initiative» D-Lib Magazine, Volume 5 Number 4; avril.<http://www.dlib.org/dlib/april99/04weibel.html> Witten, I.H., Moffat, A. and Bell, T.C. (1999) Managing gigabytes: compressing and indexing documents and images. Morgan Kaufmann, San Francisco. [1] ... Greenstone Sur des systèmes Windows 95/98, l'exécution de setup.bat peut échouer avec le message d'erreur Hors de l'espace d'environnement. Dans ce cas, éditez le fichier config.sys de votre système (qui se trouve habituellement sous Cconfig.sys) et ajoutez-y la ligne shell=C:command.com /e:4096 /p (où C représente la lettre de votre lecteur système) pour agrandir la taille de la table d'environnement. Il vous faudra redémarrer l'ordinateur pour que cette modification soit prise en compte. Répétez ensuite les étapes effectuées avant l'obtention de ce message d'erreur. [2] ...nugget» Attention: dans Greenstone, les expressions rationnelles sont interprétées dans le langage Perl, et les conventions diffèrent subtilement d'autres conventions. Par exemple, «*» correspond à zéro ou plusieurs occurrences du caractère qui précède, et «.» remplace n'importe quel caractère -- donc «nugget.*» correspond à toute chaîne commençant par «nugget», que ce préfixe soit suivi d'un point ou non. Pour imposer un point à cette position il faudrait échapper le point, et écrire «nugget..*» à la place. [3] ... collection Remarquez que les versions les plus récentes de la collection «Demo» utilisent un classificateur Hierarchy pour représenter les méta-données how to (comment faire). Dans de tels cas de figure, elles apparaîtront un peu différemment que dans la figure 12. [4] ... facilement La valeur gsdlhome provient du fichier gsdlsite.cfg situé dans le même répertoire que l'exécutable CGI library, alors que GSDLHOME est positionné en exécutant le script setup qui accède à un fichier différent; il est donc techniquement possible que les deux valeurs soient différentes. C'est possible, mais pas désirable, et le texte ci-dessus est écrit dans l'hypothèse où ces deux valeurs sont égales. [5] Technically there are four types, but the last two are optional. Since we are only giving a basic introduction to this STL class, details about these last two types are omitted. |
Copyright © 2002 2003 2004 2005 2006 2007 by the New Zealand Digital Library Project at the University of Waikato, New Zealand.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Documentation License.”