Développer une application web W4 Engine en Java
Transcription
Développer une application web W4 Engine en Java
Note technique W4 Engine Développer une application web W4 Engine en Java Sommaire Cette note technique concerne uniquement le développement d'applications W4 en utilisant l'environnement Web et Java. Cela suppose donc de maîtriser l'utilisation de W4 Studio (pour pouvoir comprendre la modélisation de la procédure de test), la gestion d'un serveur W4 (pour éventuellement assigner des rôles, créer des acteurs, etc.) et le développement en HTML 3.2 et Javascript 1.1. 1 Installation et configuration 3 2 Organisation des packages Java 5 3 Développer l'application de Gestion des Messages Téléphoniques (GMT) 11 Référence : W4TN_JAVA_TUTORIAL_010_FR Note technique W4 Engine Développer une application web W4 Engine en Java © 1996 - 2007 W4. Tous droits réservés. L'acquisition du présent document confère un droit d'utilisation incessible, non exclusif et personnel et non un droit de propriété. L'utilisation, la copie, la reproduction et la distribution du présent document sont permises à condition : 1. que la mention de droits d'auteur ci-dessus figure sur toutes les copies et que cette mention de droits d'auteur et la présente mention d'autorisation apparaissent conjointement ; 2. que le présent document ne soit utilisé qu'à des fins d'information et non commerciales ; 3. que le présent document ne soit modifié de quelque manière que ce soit. Tous les produits et marques cités sont la propriété de leurs titulaires respectifs. Les informations contenues dans ce document pourront faire l’objet de modifications sans préavis. Installation et configuration 1 1.1 Installation du JDK Avant toute chose, il est nécessaire d'installer un Java Development Kit. Le toolkit java de W4 Engine nécessite l'utilisation d'un JDK1.2.x ou supérieur. Il est recommandé d'utiliser au minimum la version de production du JDK1.2.2. Vous pouvez l'obtenir à l'adresse suivante : http://java.sun.com/ Attention ! Installer de préférence le JDK dans un répertoire dont le nom ne contient pas d'espace blanc. 1.2 Installation du moteur de servlet Si vous utilisez un serveur d'application, vous pouvez passer cette section. W4 recommande Tomcat 4.2.1 ou 5.0. Tomcat est disponible à l'adresse suivante : http://jakarta.apache.org/site/downloads/index.html Pour l'installation et la configuration de Tomcat, veuillez vous référez à la documentation livrée avec ce produit. 1.3 Installation des bibliothèques Java de W4 Engine Le package Java de W4 Engine se compose d'une archive Java (wfjlib.jar) et d'une bibliothèque (WFjniClient.dll sous Windows et libWFjniClient.so sous les systèmes Unix supportés). Attention ! Sous Windows et pour les versions inférieures à 5.0, il existait deux bibliothèques : WFcLink.dll et WFjniClient.dll. Après la version 5.0, ces deux bibliothèques ont été regroupées en une seule : WFjniClient.dll. Vous trouverez toutes ces bibliothèques dans le répertoire W4Engine_Home/lib. Pour chaque wfjlib.jar chargée par la JVM une bibliothèque y est associée. Une même bibliothèque ne peut pas être chargée plusieurs fois par la JVM. Il faut donc déployer autant de bibliothèques que de wfjlib.jar. 3 NOTE TECHNIQUE Installation et configuration Déploiement pour les archives Java (wfjlib.jar) antérieures à la version 5.0 Pour le déploiement de la wfjlib.jar, vous devez ajouter la wfjlib.jar : soit dans la variable d’environnement CLASSPATH de sorte que : CLASSPATH=%CLASSPATH%;W4Engine_Home\lib\java\wfjlib.jar soit dans les bibliothèques communes du serveur d’application. La wfjlib.jar cherche les DLL associées dans l'environnement uniquement, c'est-à-dire : Sous Windows, vous devez modifier la variable d'environnement PATH (ou celle du serveur d'application) de sorte que : PATH=%PATH%;W4Engine_Home\lib\nt Sous Solaris et Linux, vous devez modifier la variable d'environnement LD_LIBRARY_PATH (ou celle du serveur d'application) de sorte que : LD_LIBRARY_PATH=$LD_LIBRARY_PATH:W4Engine_Home\lib\solaris Sous AIX, vous devez modifier la variable d'environnement LIBPATH (ou celle du serveur d'application) de sorte que : LIBPATH=$LIBPATH:W4Engine_Home\lib\aix Déploiement pour les archives Java (wfjlib.jar) depuis la version 5.0 Pour une version postérieure à 5.0, il est possible de déployer plusieurs wfjlib.jar dans un même environnement. Le déploiement de la wfjlib.jar peut alors être réalisé en ajoutant la wfjlib.jar : soit dans la variable d’environnement CLASSPATH de sorte que : CLASSPATH=%CLASSPATH%;W4Engine_Home\lib\java\wfjlib.jar soit dans le répertoire des bibliothèques communes du serveur d’application ; soit au niveau de l’application elle-même. La seule DLL (la wfclink.dll n'est plus nécessaire) chargée par la wfjlib.jar est cherchée dans l'ordre suivant : 1 dans le répertoire spécifié via paramètre de JVM WF_JNI_LIB_PATH ; 2 dans le même répertoire que la wfjlib.jar concernée ; 3 dans le sous-répertoire relatif à la plate-forme ("nt" pour windows, "linux" pour linux, etc.) ; 4 dans l'environnement global, comme pour les versions antérieures à 5.0. Cette solution implique que la wfjlib.jar est déployée soit au niveau du CLASSPATH, soit au niveau des bibliothèques communes. Depuis la version 5.0, il est donc possible de faire cohabiter plusieurs versions de la wfjlib.jar et de les déployer au niveau de l’application (c'est-à-dire dans le répertoire WEB-INF/lib). Attention ! Weblogic ignore les DLL et SO lors de l'expansion d'un WAR, interdisant les solutions 2 et 3 ce qui peut poser un problème. Auquel cas, on se tournera vers les solutions 1 et 4. W4 BPM Suite NOTE TECHNIQUE Développer une application web W4 Engine en Java 4 Organisation des packages Java 2 Les packages Java peuvent être décomposés en 2 sous-ensembles : Les classes reflétant les objets W4 Engine (dossier, tâche, acteur, rôle, ...) Les classes concernant la gestion des sessions W4 Engine Les classes "compagnon", c'est-à-dire les classes facilitant le développement d'applications W4 Engine comme le servlet W4 (fr.w4.http.W4Servlet), le gestionnaire de dictionnaires (fr.utils.TWFdictionaryFactory et fr.w4.utils.TWFdictionary), l'interpréteur XML, etc. 2.1 Les objets workflow L'organisation des objets Java reprend l'organisation des « objets » C et CGI, c'est-à-dire une classification des objets entre trois catégories : les objets « basic », les objets du « buildtime », les objets du « runtime ». Cependant les méthodes d'appel au serveur W4 Engine ne sont plus rattachées à des services (scheduler, dataminer, ...) mais directement aux objets. Par exemple, si l'on souhaite créer un rôle, il faut tout d'abord instancier un objet rôle, remplir ses champs puis appeler sa méthode « wfCreateRole » (bien sûr, on aura auparavant ouvert une session). 5 fr.w4 : ne contient que la classe TWFexception fr.w4.basic : représentent les objets qui ne font que composer d'autres objets. Ils ne sont pas liés directement au serveur W4 Engine. Exemple d'objets « basic » : TWFname, TWFdate, TWFduration, ... fr.w4.buildtime.basic : Ces objets sont des composants des objets du « buildtime.dynamic ». Exemple : TWFfont, TWFsizeRect. Ce package contient également la classe TWFdata qui représente une donnée workflow. Cette classe est utilisée par les packages du runtime. fr.w4.buildtime.dynamic : Ce sont les objets qui touchent à l'organisation. Il s'agit des procédures, des acteurs, des rôles. Ces objets peuvent être créés en dehors du serveur W4 Engine (dans l'environnement local de W4 Studio, par exemple). Il est possible d'effectuer sur eux deux opérations « serveur » : leur création et leur modification. fr.w4.buildtime.ref : Ces objets référencent des objets du « buildtime.dynamic ». Ils étendent la classe TWFname. Il est possible d'effectuer des opérations « serveur » sur ces objets. Exemple : TWFactorRef sur laquelle il est possible d'effectuer un wfGetActor() ou un wfDeleteActor(). fr.w4.runtime.dynamic : Il s'agit des dossiers, des tâches, des variables, des événements, etc. . Ces objets ne peuvent être créés en dehors du serveur W4 Engine. Pour les créer, il faut donc utiliser une « factory », classe fr.w4.runtime.dynamic.TWFruntimeFactory et fr.w4.runtime.dynamic.TWFnativeRuntimeFactory . Il est possible d'effectuer sur ces objets des opérations « serveur ». NOTE TECHNIQUE Organisation des packages Java fr.w4.runtime.ref : Ces objets référencent des objets du « runtime.dynamic ». Ils étendent la classe TWFname. Il est possible d'effectuer des opérations « serveur » sur ces objets. Exemple : TWFtaskRef sur laquelle il est possible d'effectuer un getTask() ou un processTask(). fr.w4.search : les critères de recherche. Les références La nouveauté par rapport aux APIs CGI et C est l'introduction des références. Les références permettent de concilier l'approche objet avec l'approche native web de W4 Engine (utilisation d'URL pour passer des ordres sur le workflow). Lorsque l'on travaille sur internet, il serait excessif de devoir véhiculer entre les formulaires la définition complète d'objets. C'est pourquoi une sous-catégorie d'objets appelée « référence » a été introduite dans les catégories des objets « buildtime » et « runtime ». Les références sont des extensions du type TWFname auquel elles apportent le « typage » puisqu'elles se rapportent à un objet précis (exemple : TWFroleRef référence un rôle). Les références contiennent les méthodes d'appel au serveur qui ne nécessitent que de détenir l'identifiant d'un objet. Par exemple, la classe TWFtaskRef contient notamment les méthodes wfProcessTask() (c'est-à-dire faire tâche), wfGetTask() (pour récupérer la définition complète de la tâche associée à cette référence). Toutes les classes "références" possèdent une méthode wfGet<OBJECT> qui permet de retrouver la définition complète de l'objet référencé (exemple : TWFactorRef a une méthode wfGetActor). Les références présentent un autre avantage : elles autorisent la navigation entre objets. Exemple : Si l'on détient une instance de TWFtask, pour retrouver la définition complète du dossier auquel elle est rattachée, il suffit d'écrire : TWFworkcase workcase = task.getWorkcaseRef().wfGetWorkcase() Cette facilité d'écriture peut avoir une conséquence fâcheuse : la sollicitation excessive du serveur W4 Engine. Pour remédier à ce défaut, une convention de nommage a été définie : Les méthodes commençant par les lettres wf sont celles qui interagissent avec le serveur W4 Engine. Les autres méthodes s'exécutent uniquement en local. Si l'on reprend l'exemple de code ci-dessus, on en déduit que la méthode getWorkcaseRef de la classe TWFtask s'exécute en local tandis que la méthode wfGetWorkcase de la classe TWFworkcaseRef appelle le serveur W4 Engine. W4 BPM Suite NOTE TECHNIQUE Développer une application web W4 Engine en Java 6 Hiérarchie entre les classes TWFname, TWFtaskRef et TWFtask : java.lang.Object | +--fr.w4.basic.TWFname | +--fr.w4.runtime.ref.TWFtaskRef | +--fr.w4.runtime.dynamic.TWFtask Les collections W4 Engine dispose d'un service de recherche (dataminer). Ce servive de recherche permet de retrouver des collections d'objets en fonction des critères de sélection utilisés (ils sont définis dans le package fr.w4.search). Ces collections d'objets ne concernent donc que les objets pouvant être retrouvés via le dataminer. Il s'agit des objets du buildtime (à l'exception du package fr.w4.buildtime.basic) et du runtime. C'est donc dans les packages fr.w4.buildtime.ref, fr.w4.buildtime.dynamic, fr.w4.runtime.ref et fr.w4.runtime.dynamic que l'on trouvera des classes représentant des collections (il existe donc des collections de références). On distingue les classes "collection" des autres parce qu'elles : héritent toutes de la classe fr.w4.basic.TWFcollection sont prefixées par les lettres TWFT (exemples : TWFTworkcase, TWFTrole, TWFTtaskRef), tandis que les classes "simples" sont prefixées par les lettres TWF Toutes les classes "collection" contiennent une méthode "static" wfSearch<OBJECT>. C'est par le biais de cette méthode qu'il est possible de solliciter le service de datamining. Les classes "collection" contiennent également, le cas échéant, d'autres méthodes permettant de modifier les propriétés d'un groupe d'objets sur le serveur W4 Engine. Par exemple, la classe TWFTworkcase a, en plus de la méthode wfSearchCase, les méthodes wfCancelTcase, wfDeleteTcase. La hiérarchie : de TWFcollection à TWFTworkcase : java.lang.Object | +--fr.w4.basic.TWFcollection | +--fr.w4.runtime.ref.TWFTworkcaseRef | +--fr.w4.runtime.dynamic.TWFTworkcase 7 NOTE TECHNIQUE Organisation des packages Java 2.2 La gestion des sessions (package fr.w4.session) La gestion des sessions est une nouveauté par rapport aux fonctionnalités jusque là disponibles via les APIs C. Le package fr.w4.session intègre les classes suivantes : TWFsessionContext : classe décrivant le contexte d'une session W4 Engine. Ce contexte contient le nom et l'instance du serveur W4 Engine, l'identifiant de l'acteur connecté ainsi que son identifiant de connexion et sa langue (si elle a été précisée lors de la création de l'acteur). TWFsessionFactory : crée une TWFnativeSession ou une TWFrmiSession selon le protocole qui a été utilisé. TWFsessionFactory permet de rendre les applications indépendantes du protocole réseau. TWFsession : classe abstraite (donc non instanciable) représentant une session W4 Engine. Cette classe définit les méthodes abstraites openConnection, closeConnection, login, logout. TWFnativeSession : implémentation de la classe TWFsession utilisant la "Java Native Interface" (JNI), c'est-à-dire l'encapsulation d'APIs C dans des APIs Java. TWFrmiSession : implémentation de la classe TWFsession utilisant "Remote Method Invocation" (RMI) (consulter la section RMI pour plus de détails) TWFsessionPool : référence les sessions ouvertes par thread. Hiérarchie entre les classes TWFsessionContext, TWFsession et TWFnativeSession : java.lang.Object | +--fr.w4.session.TWFsessionContext | +--fr.w4.session.TWFsession | +--fr.w4.session.TWFnativeSession Concrètement, pour ouvrir une session sur le serveur W4 Engine, il est nécessaire de procéder aux opérations suivantes : Instancier un objet TWFnativeSession ou TWFrmiSession Préciser le nom du serveur W4 Engine (seulement si le client est distant) et le nom de l'instance du serveur Ouvrir la connexion (création "physique" d'un canal vers le serveur W4 Engine) Se loguer Ouverture, fermeture d'une session native : TWFsession w4Session = null; try { w4Session = new TWFnativeSession(); w4Session.setServerName("epinal"); w4Session.setInstanceName("w4adm"); W4 BPM Suite NOTE TECHNIQUE Développer une application web W4 Engine en Java 8 /* ouverture de la connexion physique vers le serveur */ w4Session.openConnection(); /* ouverture d'une session pour l'acteur */ w4Session.login(actorName,password); ... w4Session.logout(); } catch(Exception e) { e.printStackTrace(); } /* on s'assure d'attraper tout type d'exception */ catch(Throwable t) { System.err.println(t.getLocalizedMessage()); } /* on s'assure de toujours fermer la connexion physique au serveur (même si une exception n'est pas "attrapée") */ finally { if(w4Session != null && w4Session.getSessionHandle() > 0) { try { w4Session.closeConnection(); } catch(Throwable t) { System.err.println(t.getLocalizedMessage()); } } } Attention ! Il n'est possible d'ouvrir qu'une seule session par thread. Dans le cas où un thread essayerait d'ouvrir une deuxième session, l'exception TWFsessionAlreadyOpenException est levée. A l'inverse, l'exception TWFnoSessionOpenException sera lancée si un thread tente de réaliser une opération serveur sans avoir au préalable ouvert une session. Utilisation de RMI RMI ou Remote Method Invocation permet de créer des applications " Java à java " distribuées, dans lesquelles les méthodes des objets Java distants peuvent être appelées depuis des machines virtuelles Java et sur différents hôtes. Pour utiliser RMI, il faut procéder de la manière suivante : 9 Écrire un fichier de gestion des droits (fichier policy) NOTE TECHNIQUE Organisation des packages Java Attention ! Dans cet exemple, pour simplifier, nous avons utilisé un fichier policy qui donne une autorisation globale à tous et de n'importe où. N'utilisez pas ce fichier policy dans un environnement de production. Pour avoir plus d'informations sur la façon d'accorder des droits en utilisant un fichier java.security.policy, reportez-vous aux documents suivants : Default Policy Implementation and Policy File Syntax Permissions in JDK1.2 grant { // Grants all the rights permission java.security.AllPermission; }; Démarrer le service RMI sur le serveur W4 Engine java -Djava.security.policy="server.policy" fr.w4.service.TWFrmiService [ServerName] [ServerPort] Il est impératif de renseigner les paramètres ServerName et ServerPort L'utilisation de RMI est démontrée dans l'application de gestion des messages téléphoniques décrite ci-dessous. 2.3 Les classes "compagnon" Ces classes se trouvent dans les packages fr.w4.utils, fr.w4.marshal et fr.w4.http. Leur utilisation est décrite ci-dessous - dans le même temps que la réalisation d'une application workflow en Java. Par ailleurs, le document suivant décrit l'utilisation du Servlet W4 et de l'interprétateur XML (tous deux membres du package fr.w4.marshal) : Note technique - API URL et XML Attention ! Il est déconseillé d'utiliser la classe fr.w4.log.TWFlog (hormis pour activer ou désactiver les traces). Elle est utilisée par W4 Engine pour loger les exceptions survenues. Le contenu de ce journal est exploité par le support de W4, il est donc préférable de ne pas y faire figurer les messages d'erreur de vos propres classes. Préférer donc utiliser la classe de log de votre moteur de servlet ou de votre serveur d'application. Dans le cas où vous ne disposeriez ni de l'un ni de l'autre, vous pouvez utiliser, par exemple, le package log4j disponible à l'adresse suivante : http://jakarta.apache.org/ W4 BPM Suite NOTE TECHNIQUE Développer une application web W4 Engine en Java 10 Développer l'application de Gestion des Messages Téléphoniques (GMT) 3 3.1 Création de la procédure GMT L'objectif de ce tutoriel n'étant pas la maîtrise de l'outil W4 Studio, le fichier d'environnement local fourni définit la procédure GMT et ses activités. Le fichier d'environnement local est disponible sous : W4Engine_Home\Docs\fr\java\sampleApp\procedure\PhoneMsg.w4e Créez sur le serveur W4 Engine les objets contenus dans cet environnement local. Rappel sur l'architecture L'architecture Java-Web est composée de plusieurs éléments : les navigateurs Web, le serveur HTTP, le servlet W4 : Il permet d'appeler le moteur W4 Engine depuis une URL. Ce n'est pas l'équivalent du CGI de W4 Engine dans la mesure où il n'est pas associé à un "template" W4 mais à une JSP. Le document suivant décrit la syntaxe à utiliser pour invoquer le servlet : Note technique - API URL et XML et enfin la Java Server Page (JSP template sur le graphique) : L'utilisation de la JSP est orientée sur la présentation, c'est-à-dire qu'elle sert à mettre en forme les résultats des appels du servlet W4 sur le moteur workflow. Mise en place du répertoire "projet" Il s'agit ici d'apprendre à gérer l'arborescence du projet GMT. Attention ! Les mécanismes décrits ci-dessous concernent Tomcat. Ils sont en principe adaptables aux autres produits du marché. Si tel n'était pas le cas, merci de contacter [email protected] 11 NOTE TECHNIQUE Développer l'application de Gestion des Messages Téléphoniques (GMT) Dans le répertoire webapps de Tomcat, créer un nouveau répertoire du nom de MsgTel. Dans le répertoire MsgTel, créer les répertoires suivants : Activities : contient les formulaires des activités. Templates : contient les écrans "hors procédure", c'est-à-dire la page de connexion à l'application, la corbeille des tâches, l'écran de recherche des messages téléphoniques. docs : espace de stockage des documents qui seront "uploadés" par les utilisateurs. Public : contient l'ensemble des documents publics de l'application. Images : contient les images de l'application. Développement des Java Server Pages (JSP) Conception générale La procédure de gestion des messages téléphoniques est très simple. Elle ne comporte que quatre noeuds. Derrière le noeud d'envoi se trouve l'activité W4_MsgTel_envoi. Quant au noeud Réception, il utilise l'activité W4_MsgTel_Reception. La cinématique des formulaires correspondant à cette procédure est, elle aussi, très simple. L'utilisateur se connecte à l'application. Il consulte la liste des messages téléphoniques qu'il a reçus. Il peut, alors, décider de : W4 BPM Suite NOTE TECHNIQUE Développer une application web W4 Engine en Java 12 lire l'un de ces messages (page Activities/W4_MsgTel_Reception.jsp), de faire une recherche (page Templates/search.jsp), de créer un nouveau message téléphonique (page Activities/W4_MsgTel_envoi.jsp), de consulter les messages qu'il a commencés à rédiger (page Templates/toWrite.jsp), de se déconnecter de l'application (page Public/index.jsp). Principes de développements Attention ! L'un des objectifs principaux de ce tutoriel est d'apprendre à factoriser au maximum les développements. Pour ce faire, il faut essayer de considérer une page JSP comme un objet à part entière. Chaque page devra répondre à un schéma par particulier. Dans le cadre de ce tutoriel, ce schéma est très simple (il est la plupart du temps suffisant) : La gestion du contexte utilisateur Un bandeau comprenant un menu de navigation (à affichage optionnel) Un formulaire de saisie des données Il faut, par contre, enrichir ce schéma pour les formulaires d'activités puisque dans chaque activité, il sera possible d'attacher des documents ou des commentaires au dossier - et de les consulter. Ces JSP répondront donc au schéma suivant : La gestion du contexte utilisateur Un bandeau comprenant un menu de navigation (à affichage optionnel) Un formulaire de saisie des données Un pied de page pour la gestion des documents et commentaires Dès lors que ces schémas sont fixés, il est possible d'avoir une "vision orientée-objet" du développement des JSP et de poser le modèle de développement suivant : 13 NOTE TECHNIQUE Développer l'application de Gestion des Messages Téléphoniques (GMT) Chaque page est une extension de l'objet context.jsp. Elle hérite des attributs de cette page ; en l'occurrence le contexte de la session et les deux dictionnaires de l'application. Les "templates" incluent un bandeau de navigation. Et les activités sont composées en plus de ces éléments d'un pied de page. Remarque Différences entre les tags <jsp:include page/> et <%include file%/> <%include file%/> : correspond à la notion d'héritage car les codes sources des 2 pages sont fusionnés. <jsp:include page/> : correspond à la notion UML de composition car c'est le résultat produit qui est inclus Le contexte (Templates/context.jsp) Cette page - cet objet - n'a pas de représentation visuelle puisqu'elle a en charge de récupérer le contexte utilisateur et de charger les dictionnaires de l'application. code de la page context.jsp : <%@ page import="java.util.*,fr.w4.TWFexception,fr.w4.basic.*, fr.w4.session.*,fr.w4.search.*,fr.w4.buildtime.basic.*, fr.w4.buildtime.dynamic.*,fr.w4.runtime.dynamic.*, fr.w4.http.*,fr.w4.utils.*" %> <% /* get the context */ TWFhttpContext context = (TWFhttpContext)request.getAttribute("context"); /* ever reload the dictionaries during development time. */ TWFdictionaryFactory.setUseCache(false); TWFdictionary res = null; TWFdictionary stateDic = null; /* get the application dictionary if the user language is defined */ try { res = TWFdictionaryFactory.getDictionary("http://vodka/W4Public/dictionaries/", "messages",(context != null ) ? context.getLanguage():null); stateDic = TWFdictionaryFactory.getDictionary("http://vodka/W4Public/dictionaries/", "wk_state",(context != null ) ? context.getLanguage():null); } catch(TWFnoSuchResourceException nsre) { nsre.printStackTrace(); } %> Pour plus de détails sur le mécanisme de gestion du contexte utilisateur, veuillez vous référez au document suivant : Note technique - API URL et XML W4 BPM Suite NOTE TECHNIQUE Développer une application web W4 Engine en Java 14 Les dictionnaires d'application offrent la possibilité d'externaliser les "String" de l'application. Cette externalisation peut se faire ou non en fonction de la langue de l'utilisateur. Dans la page context.jsp, deux dictionnaires sont chargés : le dictionnaire messages_fr.properties et le dictionnaire wk_state_fr.properties. Le premier contient tous les messages de l'application (intitulés des champs, nom de l'application, etc.) et le second concerne les états des tâches et des dossiers. Le dictionnaire messages_fr.properties est disponible sous : W4Engine_Home\Docs\fr\java\sampleApp\dictionaries\messages_fr.properties Sa version anglaise messages_en.properties est disponible sous : W4Engine_Home\Docs\en\java\sampleApp\dictionaries\messages.properties Le dictionnaire wk_state_fr.properties est disponible sous : W4Engine_Home\Docs\fr\java\sampleApp\dictionaries\wk_state_fr.properties Sa version anglaise wk_state.properties est disponible sous : W4Engine_Home\Docs\en\java\sampleApp\dictionaries\wk_state.properties La gestion de la "localisation" s'effectue de la manière suivante : si une langue est précisée, le TWFdictionaryFactory va chercher à charger le fichier messages_LG.properties. Si ce fichier n'est pas trouvé, il va, alors, essayer de charger le fichier messages.properties. Attention ! Les dictionnaires peuvent aussi servir à gérer les migrations d'une application W4 d'un serveur à un autre. Par exemple, sur le développement, l'ensemble des documents attachés au dossier est stocké dans le répertoire c:/W4Docs. Lors du passage en production, on souhaite que les documents soient stockés sur e:/RAID5/W4Docs. Pour remédier à ce problème, il suffit d'externaliser le chemin du répertoire de stockage dans un dictionnaire. 15 NOTE TECHNIQUE Développer l'application de Gestion des Messages Téléphoniques (GMT) Le bandeau de navigation (Templates/navBanner.jsp) Code de la page navBanner.jsp : <%@ page language="java" import="java.util.*, fr.w4.*, fr.w4.basic.*, fr.w4.buildtime.basic.*, fr.w4.buildtime.ref.*, fr.w4.buildtime.dynamic.*, fr.w4.runtime.ref.*, fr.w4.runtime.dynamic.*, fr.w4.session.*, fr.w4.marshal.*,fr.w4.http.*,fr.w4.search.*,fr.w4.utils.*" %> <%@ include file="../Templates/context.jsp" %> <% <!-- Get the hideMenu parameter --> String temp = request.getParameter("hideMenu"); boolean hideMenu = (temp != null && temp.compareTo("true") ==0); %> <table border="0" cellpadding="0" cellspacing="0" width="750"> <tr valign="top"> <td><img name="barre_r1_c1" src="../Images/barre_r1_c1.gif" width="223" height="105" border="0"></td> <td> <table border="0" cellpadding="0" cellspacing="0" width="527"> <tr valign="top"> <td width="527" height="59" bgcolor="#0860A8" valign="middle"><p><font color="#BEDDEB"> <%=res.getKeyValue("application.title")%> </font></td> </tr> <tr> <td valign="top" height="3"> <img name="barre_r2_c2" src="../Images/barre_r2_c2.gif" width="527" height="3" border="0"></td> </tr> <!-- MENU : print out only if the context is set and a task is not in process --> <% if (context != null && !hideMenu) { %> <tr> <td bgcolor="#FFFFFF" valign="top"> <!-- Create a new message --> <a href="/MsgTel/servlet/fr.w4.http.W4Servlet?<%=context.writeCtx()%> &inv1=runtimeFactory.newCaseWithInitiator &inv1.newCaseWithInitiator.procedure.str=W4_MsgTel &inv1.newCaseWithInitiator.initiator.id=<%=context.getActorId()%> &inv1.newCaseWithInitiator.makesUniqueName=true &inv1.newCaseWithInitiator.prefixCaseName.str=msgTel &[email protected] &[email protected] &hideMenu=true"> <font face="verdana" color="#0860A8" size="1"> <%=res.getKeyValue("menu.newCase")%></a> <!-- View the workitems --> | <a href="/MsgTel/servlet/fr.w4.http.W4Servlet?<%=context.writeCtx()%> &template=Templates/corbeille.jsp"> W4 BPM Suite NOTE TECHNIQUE Développer une application web W4 Engine en Java 16 <font face="verdana" color="#0860A8" size="1"> <%=res.getKeyValue("menu.workitems")%></a> <!-- View the messages under 'construction' --> | <a href="/MsgTel/servlet/fr.w4.http.W4Servlet?<%=context.writeCtx()%> &template=Templates/toWrite.jsp"> <font face="verdana" color="#0860A8" size="1"> <%=res.getKeyValue("menu.toFinish")%></a> <!-- Search messages --> | <a href="/MsgTel/servlet/fr.w4.http.W4Servlet?<%=context.writeCtx()%> &template=Templates/search.jsp"> <font face="verdana" color="#0860A8" size="1"> <%=res.getKeyValue("menu.history")%></font></a> <!-- Quit the application --> | <a href="/MsgTel/servlet/fr.w4.http.W4Servlet?<%=context.writeCtx()%> &inv=session.logout&logout.actorName=w4adm &template=Public/index.jsp&hideMenu=true"> <%=res.getKeyValue("menu.quit")%></a> </font></td> </tr> <% } %> </table> </td> </tr> </table> L'intérêt de cette page réside dans ses exemples d'utilisation du servlet (création de dossier, changer le template courant tout en conservant le contexte utilisateur). Page de connexion à l'application (Public/index.jsp) La page de connexion permet à l'utilisateur de saisir son nom de connexion et son mot de passe. Le bouton "connexion" soumet le formulaire au servlet W4. Ce dernier exécute l'API login puis appelle le template workitem.jsp (affichage de la corbeille des tâches). Pour réaliser cette page, il faut donc créer une page JSP capable d'appeler l'API login. On pourrait considérer qu'une simple page HTML suffirait cependant l'application GMT doit être multilingue ce qui introduit de la dynamicité dans la page et donc nécessite le recours au JSP. La balise form : <FORM NAME="connexion" METHOD="POST" ACTION="/MsgTel/servlet/fr.w4.http.W4Servlet?inv=session.login&template=Templat es/workitem.jsp"> ... </FORM> L'important, ici, est de spécifier que l'on "poste" les données vers le servlet W4 et que l'on invoque l'API login de l'objet session. Cela se fait simplement en donnant la valeur suivante à l'attribut ACTION de la balise FORM : 17 NOTE TECHNIQUE Développer l'application de Gestion des Messages Téléphoniques (GMT) /MsgTel/servlet/fr.w4.http.W4Servlet?inv=session.login Pour indiquer que la page à afficher est la corbeille des tâches, on ajoute à la requête le paramètre template en lui donnant la valeur workitem.jsp. La conséquence est qu'une fois que l'API login aura été appelée, le servlet W4 appellera la page workitem.jsp. Il ne reste plus qu'à créer un champ de type texte et un champ de type "mot de passe" à l'intérieur du formulaire. Ces champs doivent porter le nom des paramètres de l'API login qui sont respectivement : actorName et password. Au final, vous devez donc obtenir un code JSP qui ressemble à celui-ci : Code la page index.jsp : <%@ page language="java" import="java.util.*, fr.w4.*, fr.w4.basic.*, fr.w4.buildtime.basic.*, fr.w4.buildtime.ref.*, fr.w4.buildtime.dynamic.*, fr.w4.runtime.ref.*, fr.w4.runtime.dynamic.*, fr.w4.session.*, fr.w4.marshal.*, fr.w4.http.*,fr.w4.search.*,fr.w4.utils.*" %> <%@ include file="../Templates/context.jsp" %> <html> <head> <title>W4 - World Wide Web Workflow</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> </head> <body bgcolor="white" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0"> <jsp:include page="../Templates/header.jsp" flush="true"/> <p> </p> <form method="post" action="/MsgTel/servlet/fr.w4.http.W4Servlet?wfs=w4adm &inv=session.login&template=Templates/workitems.jsp"> <table width="881" border="0" cellspacing="0" cellpadding="0" height="32"> <tr> <td width="411"> <table width="381" border="0" cellspacing="0" cellpadding="0"> <tr> <td width="176"> <img src="../Images/terre1.gif" width="176" height="175"> </td> <td width="205"> <img src="../Images/terre.gif" width="227" height="175"> </td> </tr> <tr> <td width="176"> <img src="../Images/terre3.gif" width="176" height="173"> </td> <td width="205"> <img src="../Images/terre4.gif" width="227" height="173"> </td> W4 BPM Suite NOTE TECHNIQUE Développer une application web W4 Engine en Java 18 </tr> </table> </td> <td width="470" valign="top"> <table width="300" border="0" align="left"> <tr> <td colspan="2"> <b><font color="#000066"> <%=res.getKeyValue("login.message")%> </font></b></td> </tr> <tr> <td> <font color="#FFCC00"><b><font color="#FF9900"> <%=res.getKeyValue("login.loginField")%> :</font> </b></font></td> <td><input type="text" name="login.actorName"> </td> </tr> <tr> <td><font color="#FFCC00"><b><font color="#FF9900"> <%=res.getKeyValue("login.passwordField")%> : </font></b></font></td> <td><input type="password" name="login.password"></td> </tr> <tr> <td> </td> <td><input type="submit" name="Submit" value="<%=res.getKeyValue("login.submit")%>"> </td> </tr> </table> </td> </tr> </table> </form> </body> </html> La liste des messages à traiter (Templates/workitems.jsp) Le code source de la page workitems.jsp est disponible W4Engine_Home\Docs\fr\java\sampleApp\templates\workitems.jsp sous : La liste des messages en cours de rédaction (Templates/toWrite.jsp) Cette page est à 90 % similaire à la page "liste des messages à traiter". Seul le critère de la recherche WF_CRIT_NODE change puisqu'on recherche les tâches concernant le noeud Envoi et non plus Rédaction. Cette liste offre, par contre, un exemple utile d'utilisation des collections d'objets. En l'occurrence, il s'agit des TWFTworkcaseRef et des appels successifs via URL des méthodes wfCancelCase et wfDeleteCase. L'objectif de cette fonctionnalité est de permettre à l'utilisateur de détruire des messages erronés ou dont il aurait communiqué le contenu par autre moyen que le workflow. 19 NOTE TECHNIQUE Développer l'application de Gestion des Messages Téléphoniques (GMT) L'envoi d'un nouveau message (Activities/W4_MsgTel_Envoi.jsp) L'intérêt de cette page est de montrer la manipulation, en lecture et écriture, des variables de tâches en Java. La consultation d'un message (Activities/W4_MsgTel_Reception.jsp) Cette page est similaire à la précédente hormis que cette fois-ci, les variables présentées sont celles du dossier et qu'elles ne le sont qu'en lecture seule. La page de ré-activation de la session (Templates/loginConfirm.jsp) L'écran de confirmation du login permet à utilisateur de ré-activer sa session lorsque celle-ci a expiré ou est suspendue (erreur 613 et 614). L'application de gestion des messages téléphoniques fournit un exemple d'utilisation du 'loginConfirm' (page Templates/loginConfirm.jsp). Pour utiliser cette fonctionnalité dans une application existante, il faut suivre les étapes suivantes : Ajouter un paramètre d'initialisation à la W4Servlet (dans le fichier web.xml, si vous utilisez le moteur de servlet Tomcat) Modification à apporter au fichier WEB-INF/web.xml : <init-param> <param-name>login.confirm</param-name> <param-value>Templates/loginConfirm.jsp</param-value> </init-param> Les modifications suivantes sont à effectuer pour activer cette fonctionnalité dans les applications existantes Utilisation de la commande session.checkLogin Modifier les URL… http://127.0.0.1:8080/PhoneMessages/servlet/fr.w4.http.W4Servlet?id=12&l id=545&wfs=w4adm&template=Templates/workitems … par : http://127.0.0.1:8080/PhoneMessages/servlet/fr.w4.http.W4Servlet?id=12&l id=545&wfs=w4adm&inv1=session.checkLogintemplate=Templates/workitems. En effet, dans ce type d'URL, aucune interaction avec le moteur n'était faite. Il faut donc y ajouter l'appel la méthode checkLogin. Cela permet de vérifier la validité de la session. Modifier la récupération des résultats transmis par la W4Servlet Jusqu'à présent pour récupérer les résultats transmis par la W4Servlet, il fallait écrire le code suivant : TWFresponse response = context.getLastCommandResult(); W4 BPM Suite NOTE TECHNIQUE Développer une application web W4 Engine en Java 20 TWFTworkcase tworkcase = (TWFTworkcase)resp.resultAt(0); Il faut désormais utiliser la fonction resultOf qui se fonde non pas sur la position de l'objet dans le tableau résultat, mais sur le nom de la méthode appelée. TWFresponse response = context.getLastCommandResult(); TWFTworkcase tworkcase = (TWFTworkcase)resp.resultOf("searchCase"); Cette modification est nécessaire car lorsque l'écran loginConfirm sauvegarde la requête de l'utilisateur sous forme de champs cachés. Il incrémente l'indice des invocations de 1 et place comme première invocation la commande login. Dès lors, si la méthode resultAt est utilisée dans la page suivante, elle ne retournera pas un objet de la classe attendue puisque toutes les commandes ont été décalées de 1. 21 NOTE TECHNIQUE Développer l'application de Gestion des Messages Téléphoniques (GMT) Note technique W4 Engine Développer une application web W4 Engine en Java Pour toute remarque ou suggestion concernant ce document, vous pouvez contacter le support technique W4, en précisant la référence W4TN_JAVA_TUTORIAL_010_FR : par le service de traitement des dossiers Supportflow sur MyW4.com, à l’adresse suivante : http://support.myw4.com par courrier électronique : [email protected] par téléphone : 33 (0) 820 320 762