Télécharger Installer Présentation Architecture Serveur Applications Bases de documents Entrepôt Multilinguisme Analyseurs Débuter Configuration Indexation Recherche OAI Javadoc Référence API-XSP Migration Schemas Performances | Bien débuter avec SDX-2Ca y est ! Vous venez d'installer SDX-2 avec succès : vous avez pu prendre contact avec les possibilités d'administration du serveur et accédé à l'application de démonstration. Vous y avez chargé des documents XML, peut-être même des documents HTML en provenance d'un système de fichiers local ou d'Internet, ce qui vous a donné une idée de la façon dont SDX indexait les documents. Ensuite, vous avez vu de quelle façon SDX pouvait restituer les documents à la suite d'une requête. Bref, vous avez compris les grandes lignes du fonctionnement de SDX. C'est décidé, vous allez monter une application, offrir un moteur de recherche permettant la diffusion de vos milliers de documents XML ou HTML sur la toile : votre chef sera content, vous allez être promu, vous pourrez négocier une augmentation en position de force, vous brillerez dans les salons, vos écrouelles vont miraculeusement disparaître si bien que vous allez pouvoir envisager des tas de conquêtes f/m... STOP !!! Avant toute chose, reportez vous à la documentation sur les applications : elle donne des pistes pour résoudre les épineux problèmes de responsabilité éditoriale et de responsabilité informatique. Dans ce document, nous prendrons le parti que vous êtes à la fois l'éditeur et le responsable informatique. Ainsi, vous pourrez commencer à développer votre première application sans avoir à vous soucier du fait que vos documents puissent être diffusés ou pas, que votre serveur puisse assumer la montée en charge qui sied à un site attractif, de qui a les droits en écriture sur votre base de documents... De plus, votre pare-feu vous protège du monde sauvage des hackers si bien que vous pouvez sans appréhension ouvrir un serveur HTTP comme l'est un moteur de servlets. N'oubliez cependant jamais que vous aurez tôt ou tard à résoudre le déploiement de votre application sur un serveur de production. Ensuite, vous devez réflechir au concept même de base SDX. A ce sujet il peut être intéressant de voir ou revoir ce que ce terme signifie.
Tout ceci étant dit, pourquoi choisir SDX ? Si l'on veut stocker des documents XML, pourquoi ne pas se contenter de bases de données XML comme XIndice ou eXist ? D'autant plus que celles-ci disposent d'un langage de requête standardisé, de cautions prestigieuses, de nombreux utilisateurs, d'une plus grande activité, d'un support technique plus performant... La réponse est simple... sur le plan théorique : parce que, à l'inverse des autres bases de données XML, SDX fait une distinction entre :
Qu'est-ce que c'est que ce charabia ? Prenons deux exemples simples : si vous stockez la valeur John Doe dans le champ name d'un SGDB SQL, vous vous attendez à pouvoir y accéder via une requête SELECT name FROM a_table WHERE name = 'John Doe';. De même, si vous stockez <NAME>John Doe</NAME> dans une base de données XML, vous vous attendez à pouvoir retrouver cet élément grâce à une requête de ce type : document(*)//NAME = 'John Doe'. Le problème est précisément là : pour rechercher le contenu d'un document on doit interroger sa structure et donc... la connaître ! Bien sûr, si vous pouvez garantir que tous vos documents XML auront la même structure (c'est à dire qu'ils partagent une même grammaire), vous pouvez envisager de les déployer sur une base de données, XML... ou autre. Mais, êtes vous prêt à payer le prix de langages de requêtes complexes et, surtout, pouvez-vous exiger des utilisateurs qu'ils connaissent la grammaire de vos documents ? Pour prendre un exemple simple, une DTD HTML, pensez vous que les utilisateurs penseront à interroger title alors qu'ils veulent un titre ? Et croyez-vous qu'ils penseront à interroger également h1, h2, h3... qui sont également des titres ? Si vous pensez que oui, rendez vous directement aux liens mentionnés ci-dessus. Si vous pensez que non, vous pouvez passer à la section suivante... Comme on vient de le voir, SDX stocke ou référence des documents XML : le concept est suffisament traditionnel pour pouvoir être immédiatement compris. En revanche, quelle est cette mystérieuse forme que revêtent les documents lorsqu'ils sont interrogés ? Tout d'abord, cette forme a un nom, l'indexation. Ce concept, lui aussi traditionnel, est clair : on prend les valeurs contenues dans les documents et on les référence, ce qui permet une recherche rapide car on n'a pas à interroger les documents un par un pour voir si la valeur recherchée y est présente... dans le cas le plus favorable. Ici encore, les SGDB sont responsables d'un glissement de sens. Un index est, chez eux, une liste de valeurs dont on pense qu'elles seront plus souvent interrogées que d'autres. Les SGDB sont donc éternellement en quête d'un compromis entre la sélectivité des index et leur taille. En effet, il serait contre-productif pour eux d'indexer l'intégralité de la base de données car l'interrogation des index prendrait, par définition, autant de temps que la consultation de chacun des documents. Certes, chaque SGDB y va de son optimiseur de requêtes, de son analyseur d'index, de son détecteur de requêtes longues, de son cache d'index... mais, fondamentalement, les index n'ont, pour eux, que vocation à être un résumé de la base de données. Avec SDX, la définition d'un index est la même, mais la doctrine d'emploi en est radicalement différente de celle d'un SGDB :
En résumé : vous pouvez définir (ou ne pas définir) vos index comme vous l'entendez et vous pouvez définir leur contenu comme vous l'entendez. Par ailleurs, vous pouvez les typer mais, pour l'instant, seuls les index de type chaîne de caractère et de type date sont possibles. Vous disposez de documents XML (ou HTML que SDX transformera en documents XML grâce à l'intégration native de JTidy dans son architecture) et vous allez devoir les indexer. Quelle doit être votre réflexion pour que ces documents puissent être indexés dans SDX ? Dans la plupart des cas, c'est l'information sémantique qui guidera votre choix. En effet, les informations de structure n'ont souvent aucun intérêt pratique pour un utilisateur de base et, parfois, pour un utilisateur avancé. Vous devez donc dresser la liste des sémantiques que vous voulez rendre interrogeables et, vous ne pourrez pas y passer sauf à développer des fonctions ad hoc, chercher les moyens de retrouver les sémantiques choisies dans vos différents types de documents. Ainsi, si vous disposez des documents suivants : <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE chapter PUBLIC "-//Norman Walsh//DTD DocBk XML V1.3//EN" "n:/share/sgml/Norman_Walsh/db31xml/db3xml.dtd"> <chapter> <title>Premier chapitre</title> <para> La première fois que j'ai vu <firstname>Nikita</firstname>... </para> </chapter> <?xml version="1.0" encoding="ISO-8859-1"?> <movie> <title>Nikita</title> <director>Luc Besson</director> <type>Thriller</type> <date>1990</date> <roles> <role> <character>Nikita</character> <actor>Anne Parillaud</actor> </role> </roles> </movie> <?xml version="1.0" encoding="ISO-8859-1"?> <rapport> <de>4eme bureau</de> <a>2eme bureau</a> <resume>Activités de <nom>Nikita</nom></resume> <detail>A récemment été vue à <lieu>Venise</lieu> où on la soupçonne d'avoir...</detail> </rapport> ... vous avez matière à indexer, et donc à rendre cherchable, des informations concernant des noms de personnes (mais n'oubliez pas de déclarer votre fichier à la CNIL). Pour ce faire, une solution évidente s'impose : XSLT. Profitons-en pour rappeler que SDX réclame une bonne connaissance de ce langage. C'est précisément le parti qu'a choisi SDX pour générer les valeurs d'index : il attend une transformation des documents XML d'origine pour parvenir à un document transformé répondant à la DTD suivante : <!ELEMENT sdx:document (sdx:field | sdx:attachedDocument)*> <!ATTLIST sdx:document id CDATA #REQUIRED > <!ELEMENT sdx:field (#PCDATA)> <!ATTLIST sdx:document name CDATA #REQUIRED > <!ELEMENT sdx:attacheddocument (EMPTY)> <!ATTLIST sdx:attacheddocument id CDATA #REQUIRED url CDATA #REQUIRED mimetype CDATA #REQUIRED > Votre document d'indexation devra donc comporter les éléments suivants
Vous disposez maintenant de tous les éléments pour créer un document d'indexation SDX. Vous pouvez, au choix, rédiger une ou plusieurs (mais une seule est préférable pour des raisons dont nous reparlerons : si vraiment vous ne pouvez résoudre votre problème qu'à l'aide de plusieurs XSL, considérez la définition de plusieurs bases) XSL qui seront à même de générer un document d'indexation à partir de vos documents XML. Dans l'exemple suivant, nous allons essayer de réaliser une feuille qui sera capable d'indexer, dans un index nommé personne, les noms contenus dans les documents montrés ci-dessus : <?xml version="1.0" encoding="ISO-8859-1"?> <!-- ne pas oublier le namespace SDX --> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx"> <!-- un paramètre recevant une valeur pour l'id du document --> <xsl:param name="doc_id">xxx</xsl:param> <xsl:template match="/"> <!-- soyons prudent : ne traitons que les documents que nous connaissons --> <xsl:apply-templates select="chapter"/> <xsl:apply-templates select="movie"/> <xsl:apply-templates select="rapport"/> </xsl:template> <xsl:template match="chapter"> <!-- on définit un document avec l'id définie en paramètre --> <sdx:document id="{$doc_id}"> <sdx:field name="personne"> <xsl:value-of select="//firstname"/> </sdx:field> </sdx:document> </xsl:template> <xsl:template match="movie"> <!-- on définit un document avec l'id définie en paramètre --> <sdx:document id="{$doc_id}"> <xsl:for-each select="//director | //character | //actor"> <sdx:field name="personne"> <xsl:value-of select="."/> </sdx:field> </xsl:for-each> </sdx:document> </xsl:template> <xsl:template match="rapport"> <!-- on définit un document avec l'id définie en paramètre --> <sdx:document id="{$doc_id}"> <sdx:field name="personne"> <xsl:value-of select="de"/> </sdx:field> <sdx:field name="personne"> <xsl:value-of select="a"/> </sdx:field> <sdx:field name="personne"> <xsl:value-of select="resume/nom"/> </sdx:field> </sdx:document> </xsl:template> </xsl:stylesheet> Cette transformation produit les résultats suivants :
Facile, non ? A vous de jouer désormais. Lorsque votre ou vos XSL seront prêtes et que tous vos documents XML vous donneront les résultats escomptés, nous pourrons passer à l'étape suivante. Si d'ores et déjà vos documents possèdent en leur sein un identifiant unique, ou que vous pouvez rendre unique (par une concaténation par exemple), n'hésitez pas à alimenter l'attribut id de <sdx:document/> avec une valeur moins arbitraire que celle de la XSL ci-dessus. En guise de cadeau, voici une XSL permettant d'indexer l'intégralité du contenu des éléments d'un document XML dans un index nommé contenu : <?xml version="1.0" encoding="ISO-8859-1"?> <!-- ne pas oublier le namespace SDX --> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx"> <xsl:template match="/"> <sdx:document id="xxx"> <sdx:field name="contenu"> <!-- la hiérarchie est passée en revue sous le contrôle du mode "fulltext" --> <xsl:apply-templates mode="fulltext"/> </sdx:field> </sdx:document> </xsl:template> <!-- un modèle générique pour tous les éléments --> <xsl:template match="*" mode="fulltext"> <!-- un appel, éventuellement récursif, sur le noeud texte et/ou les éléments contenus --> <xsl:apply-templates select="*|text()" mode="fulltext"/> </xsl:template> <!-- traitement des noeuds texte --> <xsl:template match="text()" mode="fulltext"> <xsl:value-of select="normalize-space(.)"/> <!-- on ajoute une espace entre les contenus des différents noeuds --> <xsl:if test="normalize-space(.) !=''"> <xsl:text> </xsl:text> </xsl:if> </xsl:template> </xsl:stylesheet> ... ce qui donne (en ISO-8859-1) : <?xml version="1.0" encoding="ISO-8859-1"?> <sdx:document id="xxx" xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx"> <sdx:field name="contenu">4eme bureau 2eme bureau Activités de Nikita A récemment été vue à Venise où on la soupçonne d'avoir... </sdx:field> </sdx:document> Ne vous inquiétez pas de cette agglutination de mots qui peut être très longue. Nous verrons sous peu comment SDX les gère. Considérez pour l'instant que cette transformation est équivalente à ce document d'indexation : <?xml version="1.0" encoding="ISO-8859-1"?> <sdx:document id="xxx" xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx"> <sdx:field name="contenu">4eme</sdx:field> <sdx:field name="contenu">bureau</sdx:field> <sdx:field name="contenu">2eme</sdx:field> <sdx:field name="contenu">bureau</sdx:field> <sdx:field name="contenu">Activités</sdx:field> <sdx:field name="contenu">de</sdx:field> <sdx:field name="contenu">Nikita</sdx:field> <sdx:field name="contenu">A</sdx:field> <sdx:field name="contenu">récemment</sdx:field> <sdx:field name="contenu">été</sdx:field> <sdx:field name="contenu">vue</sdx:field> <sdx:field name="contenu">à</sdx:field> <sdx:field name="contenu">Venise</sdx:field> <sdx:field name="contenu">où</sdx:field> <sdx:field name="contenu">on</sdx:field> <sdx:field name="contenu">la</sdx:field> <sdx:field name="contenu">soupçonne</sdx:field> <sdx:field name="contenu">d'avoir...</sdx:field> </sdx:document> Vous voilà donc en mesure de disposer de documents d'indexation pour tous vos documents grâce à une XSL ad hoc. Le grand moment est arrivé : nous pouvons passer au déploiement. Rappelons au préalable la structure de répertoires de SDX apès son installation : [TOMCAT_HOME]/webapps/sdx +META-INF +sdx +sdxworld +WEB-INF Le répertoire supérieur est le répertoire du contexte SDX. Les répertoires fils contiennent respectivement un répertoire pour les manifestes (qui permettent par exemple l'authentification des composants logiciels), un répertoire pour l'application d'administration de SDX (qui contient également quelques ressources que nous aurons l'occasion d'utiliser), un répertoire pour une l'application exemple sdxworldet un répertoire de configuration du serveur SDX. Vous pouvez maintenant créer un répertoire pour votre application. Appelons-le mon_app : [TOMCAT_HOME]/webapps/sdx +META-INF +mon_app +sdx +sdxworld +WEB-INF mon_app se déclare donc d'une façon strictement identique à celle des applications SDX "officielles". Etablissons maintenant une hiérarchie minimale dans ce répertoire : [TOMCAT_HOME]/webapps/sdx +META-INF -mon_app +conf +xsl +sdx +sdxworld +WEB-INF Les noms sont assez explicites : le premier répertoire recevra les fichiers de configuration de SDX, le second recevra les XSL à même de produire un résultat pour les clients, à savoir du code HTML. Nous allons passer à la configuration proprement dite. Copiez au préalable le fichier sdxworld/sitemap.xmap dans le répertoire mon_app : nous verrons quelques-unes de ses fonctionnalités par la suite. Copiez ensuite votre XSL d'indexation dans le répertoire mon_app/conf sous le nom indexation.xsl. Créez dans le même répertoire un autre fichier, XML, que vous devez appeler application.xconf. Vous devez donc disposer de la hiérarchie suivante : [TOMCAT_HOME]/webapps/sdx +META-INF -mon_app -conf application.xconf indexation.xsl +xsl sitemap.xmap +sdx +sdxworld +WEB-INF Nous devons désormais alimenter le fichier application.xconf de notre application :
Récapitulons le contenu de notre fichier application.xconf : <?xml version="1.0" encoding="UTF-8"?> <sdx:application xmlns="http://www.culture.gouv.fr/ns/sdx/sdx" xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx" id="domaine.sdx.mon_app" xml:lang="fr-FR"> <sdx:userDocumentBase> <sdx:repositories> <sdx:repository id="users" type="FS" baseDirectory="users/xml" depth="0" extent="1000"/> </sdx:repositories> <sdx:fieldList xml:lang="fr-FR" variant=""> <sdx:field name="name" type="field" brief="true"/> <sdx:field name="firstname" type="field" brief="true"/> <sdx:field name="lastname" type="field" brief="true"/> <sdx:field name="description" type="word"/> <sdx:field name="lang" type="field" brief="true"/> <sdx:field name="variant" type="field" brief="true"/> <sdx:field name="email" type="field" brief="true"/> <sdx:field name="content" type="word" default="true"> <sdx:name xml:lang="fr-FR">Texte intégral</sdx:name> </sdx:field> </sdx:fieldList> <sdx:index> <sdx:pipeline> <sdx:transformation id="index" type="XSLT" src="/sdx/resources/indexation/index-identity.xsl"/> </sdx:pipeline> </sdx:index> </sdx:userDocumentBase> <sdx:admin groupId="admins" userId="admin" userPassword="secret"/> <sdx:documentBases> <sdx:documentBase id="ma_base" type="lucene" default="true" keepOriginalDocuments="true"> <sdx:queryParser class="fr.gouv.culture.sdx.search.lucene.queryparser.DefaultQueryParser"/> <sdx:repositories> <sdx:repository type="FS" id="stockage" baseDirectory="entrepots/documents" depth="0" extent="100" default="true"/> <sdx:repository id="references" type="URL"/> </sdx:repositories> <sdx:fieldList xml:lang="fr-FR" variant="" analyzerConf="/sdx/resources/conf/analysis/fr.xml"> <sdx:field name="contenu" type="word" default="true"> <sdx:name xml:lang="fr">Mots</sdx:name> <sdx:name xml:lang="en">Words</sdx:name> <sdx:name xml:lang="ge">W_rter</sdx:name> <sdx:name xml:lang="ar">الكلمات</sdx:name> <sdx:name xml:lang="br">Gerioù</sdx:name> <sdx:name xml:lang="eu">Hitzak</sdx:name> </sdx:field> <sdx:field name="personne" type="field" brief="true"> <sdx:name xml:lang="fr">Personnes</sdx:name> <sdx:name xml:lang="en">Persons</sdx:name> <sdx:name xml:lang="ge">Personnen</sdx:name> <sdx:name xml:lang="ar">الأشخاص</sdx:name> <sdx:name xml:lang="br">Tud</sdx:name> <sdx:name xml:lang="eu">Pertsonak</sdx:name> </sdx:field> </sdx:fieldList> <sdx:index> <sdx:pipeline> <sdx:transformation id="mon_indexation" type="XSLT" src="indexation.xsl"/> </sdx:pipeline> </sdx:index> </sdx:documentBase> </sdx:documentBases> </sdx:application> Enfin, presque... il nous reste à faire une dernière petite chose avant de commencer. Créer une page XSP d'accueil pour notre application. Créons un fichier XML avec le contenu (très minimaliste) suivant : <?xml version="1.0" encoding="ISO-8859-1"?> <!-- ne pas oublier le namespace XSP --> <!-- ne pas oublier le namespace SDX --> <xsp:page language="java" xmlns:xsp="http://apache.org/xsp" xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx"> <sdx:page/> </xsp:page> Et copions-le dans le répertoire de notre application sous le nom index.xsp (nous verrons sous peu pourquoi choisir ce nom plutôt qu'un autre). On a donc : -mon_app -conf application.xconf indexation.xsl +xsl index.xsp sitemap.xmap Démarrons maintenant le moteur de servlets et connectons-nous en tant que super-utilisateur (http://serveur:port/sdx/sdx/admin/loginsu.xsp) : nous devons en effet ouvrir notre application. Truc : on peut également ouvrir une application un créant un fichier du nom du répertoire de l'application dans le répertoire [TOMCAT_HOME]/sdx/WEB-INF/sdx/applications et en redémarrant le moteur de sevlets. Son contenu importe peu, aussi le fichier peut-il être vide. Réciproquement, supprimer un fichier de ce type ferme une application. Après ouverture, osons enfin cliquer sur le lien qui nous amène vers l'application... (http://serveur:port/sdx/mon_app) Patatras !!! ...SDX nous renvoie une magnifique erreur : org.apache.cocoon.ProcessingException: Exception during processing of file:/C:/tomcat4/webapps/sdx/mon_app/sitemap.xmap: java.io.FileNotFoundException: [TOMCAT_HOME]\sdx\mon_app\sitemap.xmap (Le fichier spécifié est introuvable) Que s'est-il donc passé ? La réponse est dans sitemap.xmap. Premier point : <map:match pattern=""> <map:redirect-to uri="index.xsp"/> </map:match> Etant donné que nous avons demandé un répertoire plutôt qu'un fichier particulier, Cocoon a cherché à vous rediriger vers une page nommée... index.xsp. Second point : <map:match pattern="*.xsp"> <map:generate type="xsp" src="{1}.xsp"/> <map:transform src="xsl/{1}.xsl"> <map:parameter name="use-request-parameters" value="true"/> </map:transform> <map:serialize/> </map:match> ... Cocoon a cherché à transformer index.xsp avec la XSL xsl/index.xsl. Cette XSL n'existant pas (encore), ce qui s'est passé est tout à fait normal ! Maintenant, si vous cherchez à accéder à http://serveur:port/sdx/mon_app/index.xsp2sdx... ... vous avez enfin du contenu ! <?xml version="1.0" encoding="ISO-8859-1" ?> <sdx:document xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx" xmlns:xsp="http://apache.org/xsp" xml:lang="fr-FR" server="http://localhost:8080/sdx" api-url="http://localhost:8080/sdx/sdx/api-url" uri="http://localhost:8080/sdx/mon_app/index.xsp2sdxX" date="Thu Jan 23 22:57:38 CET 2003"> <sdx:user anonymous="true" /> </sdx:document> Certes, ce contenu n'est pas très intéressant, mais il est déjà bien plus fourni que votre XSP source puisque vous pouvez constater que SDX est en mesure de donner des informations sur sa configuration et de dire quel est statut de l'utilisateur. Comment ce "miracle" a-t-il pu avoir lieu ? Ici encore, la réponse est dans sitemap.xmap : <map:match pattern="**.xsp2sdx"> <map:generate type="xsp" src="{1}.xsp"/> <map:transform src="../sdx/resources/xsl/xml.xsl"/> <map:serialize type="html"/> </map:match> On voit que les extensions xsp2sdx sont sérialisées en HTML (c'est pour cela que le navigateur est capable d'afficher un résultat) et que la transformation est faite grâce à la précieuse XSL utilitaire mis à notre disposition dans sdx/sdx/resources/xsl/xml.xsl. Si votre navigateur est capable d'afficher décemment le XML, vous pouvez utiliser l'extension xsp2sdxX qui, elle, sérialise en text et que le navigateur sera en principe capable de reconnaître comme étant du XML, forme particulière de text. Nous voici désormais au coeur de SDX, notre application étant bien configurée, nous allons pouvoir définir sa logique applicative. Nous allons utiliser les réglages prédéfinis dans sitemap.xmap pour rédiger une XSL à même de transformer la XSP traitée par SDX en HTML utilisable sur un navigateur. Mais au préalable, nous allons définir une XSL commune à toute les pages de notre application ; cette XSL contiendra la logique applicative qui sera partagée entre toutes les pages de l'application. Pour faire simple, nous l'appellerons common.xsl et nous la mettrons, naturellement, dans le répertoire xsl. Cette XSL remplira les fonctions suivantes :
<?xml version="1.0" encoding="ISO-8859-1"?> <!-- ne pas oublier le namespace SDX --> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx" exclude-result-prefixes="xsl sdx"> <!-- doit-on proposer les liens d'aide au débogage ? --> <xsl:variable name="debug" select="true()"/> <!-- on récupère les infos concernant l'utilisateur --> <xsl:variable name="user" select="/sdx:document/sdx:user"/> <!-- le modèle pour la "racine" du contexte SDX --> <xsl:template match="/sdx:document"> <!-- le squelette du document HTML --> <html> <head> <title>Mon application</title> </head> <body> <!-- la barre de menus --> <xsl:call-template name="menubar"/> <!-- les modèles spécifiques à chaque XSP --> <xsl:apply-templates/> <!-- le bas de page --> <xsl:call-template name="footer"/> </body> </html> </xsl:template> <xsl:template name="menubar"> <!-- le contexte de notre application --> <xsl:variable name="app_context">/mon_app/</xsl:variable> <!-- on récupère le contexte SDX --> <!-- http://server:port/sdx par exemple --> <xsl:variable name="SDX_context" select="/sdx:document/@server"/> <!-- on récupère l'URI de la page courante --> <!-- http://server:port/sdx/mon_app/index.xsp par exemple --> <xsl:variable name="page_URI" select="/sdx:document/@uri"/> <!-- on en déduit le contexte de la page dans SDX --> <!-- /mon_app/index.xsp par exemple --> <xsl:variable name="page_SDX" select="substring-after($page_URI,$SDX_context)"/> <!-- on en déduit le contexte de la page dans l'application --> <!-- index.xsp par exemple --> <xsl:variable name="page_name" select="substring-after($page_URI,$app_context)"/> <!-- notre application insèrera un élément <admin_page/> pour les pages nécessitant des privilèges d'administrateur, s'il est detecté, on est dans une telle page --> <xsl:variable name="admin_page" select="boolean(/sdx:document/admin_page)"/> <table align="center" cellpadding="10"> <tr> <!-- si on n'est pas dans la page d'index, propose un lien vers elle --> <xsl:if test="not($page_name = 'index.xsp')"> <td> <a href="index.xsp">Index</a> </td> </xsl:if> <!-- si on n'est pas dans la page d'interrogation, propose un lien vers elle --> <xsl:if test="not($page_name = 'query.xsp')"> <td> <a href="query.xsp">Interrogation</a> </td> </xsl:if> <!-- si on n'est pas dans la page d'identification, propose un lien vers elle --> <xsl:if test="not($page_name = 'login.xsp')"> <td> <a href="login.xsp">Identification</a> </td> </xsl:if> <!-- si on est identifié hors d'une page d'administration, propose une déconnection : on reste sur la même page --> <xsl:if test="not($admin_page) and not($user/@anonymous)"> <td> <!-- truc SDX : il suffit de passer un paramètre logout non vide --> <a href="{$page_URI}?logout=yes">Fin d'identification</a> </td> </xsl:if> <!-- si on n'est pas sur la page d'ajout de documents et si on est administrateur, propose un lien vers elle --> <xsl:if test="not($page_name = 'query.xsp') and $user/@admin='true'"> <td> <a href="upload.xsp">Ajouter des documents</a> </td> </xsl:if> </tr> </table> <hr/> <br/> </xsl:template> <xsl:template name="footer"> <br/> <hr/> <xsl:call-template name="userinfo"/> <xsl:if test="$debug"> <xsl:call-template name="views"/> </xsl:if> </xsl:template> <xsl:template name="userinfo"> <!-- rien à faire si l'utilisateur est anonyme --> <xsl:if test="not($user/@anonymous)"> <!-- on reconstitue le nom de l'utilisateur --> <xsl:variable name="fullname"> <xsl:if test="$user/@firstname or $user/@lastname"> ( <xsl:if test="$user/@firstname"> <xsl:value-of select="$user/@firstname"/>  </xsl:if> <xsl:if test="$user/@lastname"> <xsl:value-of select="$user/@lastname"/>  </xsl:if> ), </xsl:if> </xsl:variable> <!-- on détermine son statut --> <xsl:variable name="user_status"> <xsl:choose> <xsl:when test="$user/@superuser='true'"> le super-utilisateur </xsl:when> <xsl:when test="$user/@admin='true'"> un administrateur </xsl:when> <xsl:when test="$user/@app"> un utilisateur </xsl:when> <!-- au cas où on aurait oublié quelque chose... --> <xsl:otherwise>bug !</xsl:otherwise> </xsl:choose> </xsl:variable> <!-- et on sort l'info --> <div class="user"> Vous <xsl:value-of select="$fullname"/> êtes identifié sous le code <span class="user_id"><xsl:value-of select="$user/@id"/></span>. Vous êtes <xsl:value-of select="$user_status"/> de l'application  <span class="app_id"><xsl:value-of select="$application"/></span>. </div> </xsl:if> </xsl:template> <xsl:template name="views"> <table> <tr> <td>Les étapes de cette page : </td> <td>1) <a href="{/sdx:document/@uri}2xsp{/sdx:document/@query}">XSP</a> </td> <td>2) <a href="{/sdx:document/@uri}2sdx{/sdx:document/@query}">SDX</a> </td> <td>3) <a href="{/sdx:document/@uri}2htm{/sdx:document/@query}">HTM</a> </td> </tr> </table> </xsl:template> <!-- un template qu'on pourra utiliser si un utilisateur cherche à faire des opérations pour lesquelles il n'a pas les privilèges suffisants --> <xsl:template match="nosuchprivileges"> <div class="privileges"> Vous n'avez pas les privilèges suffisants pour effectuer cette opération. </div> </xsl:template> </xsl:stylesheet> On le voit, l'essentiel de l'opération consiste à se procurer les différents attributs et sous-éléments de <sdx:document> pour définir la logique applicative en fonction de leurs valeurs. En attendant une documentation plus complète, une idée de l'architecture du contexte SDX est donnée dans un document exemple. L'objectif des étapes suivantes consistera à s'approprier ce contexte. Retouchons maintenant très légèrement notre index.xsp : <?xml version="1.0" encoding="ISO-8859-1"?> <!-- ne pas oublier le namespace XSP --> <!-- ne pas oublier le namespace SDX --> <xsp:page language="java" xmlns:xsp="http://apache.org/xsp" xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx"> <sdx:page> <!-- si un paramètre logout est présent, on se déconnecte --> <sdx:logout/> <!-- un élément personnalisé qui n'est pas dans le namespace SDX --> <myindex/> </sdx:page> </xsp:page> Nous devons maintenant rédiger la XSL chargée de traiter le code, ô combien spécifique, de index.xsp. Rappelons que selon sitemap.xmap, elle doit s'appeler index.xsl et se trouver dans le répertoire xsl. Nous allons faire très simple : <?xml version="1.0" encoding="ISO-8859-1"?> <!-- ne pas oublier le namespace SDX --> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx" exclude-result-prefixes="sdx"> <!-- on insère la XSL commune... --> <xsl:include href="common.xsl"/> <!-- puis un modèle spécifique pour notre contenu --> <xsl:template match="/sdx:document/myindex"> <!-- du code HTML --> <h1>Mon application</h1> <p>Voici ma première application SDX.</p> <p>Elle a une barre de menus, mais la plupart des pages sont en construction.</p> <p>Ne pas hésiter à utiliser les liens en bas de page pour le débogage !</p> </xsl:template> </xsl:stylesheet> Nous pouvons désormais accéder à l'URL http://serveur:port/sdx/mon_app/index.xsp et... voir le résultat. Comme prévu, nous avons bien une barre de menus (avec des liens qui ne sont pas encore actifs), notre contenu et nos liens d'aide au débogage qui nous permettent :
En revanche, aucune information sur l'utilisateur : c'est normal, nous avons volontairement choisi de masquer l'information quand l'utilisateur est anonyme. C'est aussi pour cela que nous n'avons pas de lien vers la page d'ajouts de documents. |
Auteur : Pierrick Brihaye ( Service Régional de l'Inventaire, DRAC Bretagne, MCC ) - 2003-06-03 |