Le but d’une extension est de proposer des pages d’interface supplémentairesafin d’effectuer des traitements spécifiques. Par exemple, on peut imaginer une extension qui permet l’importation automatique de données dans un format particulier. Cela peut être également la génération de fichiers dans des formats particuliers sans passer par XSLT.
Toute extension a un nom : les pages de l’extension seront accessibles à partir de /ext/{nom de l'extension}/. L’organisation des pages de l’extension est libre ; la seule contrainte de l’extension est de proposer une implémenation des trois interfaces suivantes qui sont définies dans BdfServer.jar:
fr.exemole.bdfserver.BdfExtension : une instance de cette interface est appelée quand BaseDeFiches commence par /ext/{nom de l’extension}
fr.exemole.bdfserver.BdfExtensionFactory : sert à construire une instance de l’interface précédente.
fr.exemole.bdfserver.request.BdfRequest : comprend les paramètres du traitement à effectuer par BaseDeFiches.
Pour qu’une extension soit opérationnelle, il faut que les fichiers correspondant soient placés dans le répertoire WEB-INF de l’application, sous la forme d’un fichier jar dans WEB-INF/lib, soit sous la forme de classes dans WEB-INF/classes.
Pour que BaseDeFiches ait connaissance de l’existence d’une extension, il faut la déclarer. La procédure de déclaration est la suivante :
créer un répertoire bdfext, directement dans le répertoire WEB-INF de l’application
placer un ficher dans ce répertoire WEB-INF/bdfext avec comme nom {nom de l'extension}.properties
ajouter dans ce fichier la ligne suivante :
factory={nom d'une classe implémentant BdfExtensionFactory}
On voit que le nom d’une extension est déterminée par le nom du fichier présent dans WEB-INF/bdfext, c’est un nom « d’enregistrement » (Registration Name). En changeant le nom du fichier on modifie le nom de l’extension. Une extension doit d’ailleurs être opérationnelle quelque soit le nom d’enregistrement qu’on lui donne. D’ailleurs, l’interface fr.exemole.bdfserver.BdfExtensionFactory n’a qu’une seule méthode :
public BdfExtension newInstance(String registrationName, File parametersDirectory, File dataDirectory);
Cette méthode construit une instance de fr.exemole.bdfserver.BdfExtension en indiquant :
1) registrationName : le nom d’enregistrement de l’extension
2) parametersDirectory : le répertoire susceptibles de contenir des fichiers de paramétrage de l’extension
3) dataDirectory : le répertoire susceptible de contenir des fichiers de données de l’extension
La différence entre le répertoire des fichier sde paramétrage et le répertoire des données de l’extension, c’est que le premier peut être en lecture seule pour l’application Tomcat (ce qui est une sécurité supplémentaire) alors que le second doit être accessible en écriture par l’application Tomcat.
Les deux valeurs des répertoires peuvent être nulles. C’est à l’extension de décider de l’utilisation de ces répertoires.
Point important, la classe qui implémente fr.exemole.bdfserver.BdfExtensionFactory doit comporter un constructeur public sans argument (Class.forName({nom de la classe).newInstance() doit fonctionner).
Et, inversement, l’interface fr.exemole.bdfserver.BdfExtension possède une méthode qui renvoie le nom d’enregistrement qui lui a été transmis au moment de son instanciation :
public String getRegistrationName();
La deuxième méthode de l’interface BdfExtension est la suivante :
public BdfRequest getBdfRequest(String extensionPath);
Cette méthode transmet une instance de fr.exemole.bdfserver.request.BdfRequest construit avec le paramètre suivant :
String extensionPath : il s’agit de la chaine de caractères dans l’URL après la partie /ext/{nom de l'extension} ; c’est forcément une chaine non vide qui commence par une oblique /.
Comportement de BaseDeFiches
Pour mieux comprendre l’organisation d’une extension, voici une description du fonctionnement de BaseDeFiches
1) BaseDeFiches reçoit une URL commençant par /ext/{suite de caractères}/ (par exemple, /ext/fr-exemole-compta).
2) BaseDeFiches vérifie si la suite de caractères correspond au nom de fichier existant dans le répertoire /WEB-INF/bdfext (exemple /WEB-INF/bdfext/fr-exemole-compta.properties)
3.a) le fichier n’existe pas, il n’y a pas d’extension au nom demandé, un simple message 404 est transmis et le traitement est terminé
3.b) le fichier existe, BaseDeFiches vérifie la présence du paramètre factory et tente de construire une instance de la classe indiquée par le paramètre ; si ce paramètre est absent ou si un objet de cette classe ne peut être instanciée via Class.forName().newInstance() (autrement dit, la classe doit posséder un constructeur public sans argument), un message d’erreur est envoyé.
4) L’instance de BdfExtensionFactory créée au point précédent sert à créer une instance de BdfExtension en indiquant le nom d’enregistrement de l’extension.
5) Une instance de BdfRequest est demandée à l’extension
6) à partir de là, le traitement effectué par BaseDeFiches est le même que celui effectué pour les commandes de base.
Convention de nommage
Même si le nom d’enregistrement d’une extension doit pouvoir être modifié sans altérer le comportement de l’extension afin d’éviter un conflit entre noms, il est préférable de respecter une convention de nommage. Celle-ci pourra s’inspirer de la convention de nommage des paquets Java, convention qu’il est de toute façon nécessaire de suivre si l’on ne veut pas des conflits entre des classes de même nom.
On utilisera ainsi des minuscules et on pourra partir d’un nom de domaine inversé en utilisant des tirets plutôt que des points (par exemple, fr-exemole-compta). Il faut se souvenir que le nom de l’extension est déduite d’un nom de fichier et va servir dans des URLs, il est préférable de bannir espace et caractères accentués (la préconisation des tirets plutôt que des points (contrairement aux paquets Java) vient du fait que le point sert de séparateur de l’extension : fr-exemple-compta.properties est plus lisible que fr.exemole.compta.properties).
Exemple
Par exemple, Exemole a développé pour sa base de comptabilité analytique une extension permettant la récupération automatique des données de la comptabilité générale. Les classes Java sont dans le paquet fr.exemole.bdfext.exemolecompta, la classe implémentant BdfExtension s’appelle ComptaExemoleExtensionFactory
Il y a donc dans le répertoire /WEB-INF/bdfext/ un fichier appelé fr-exemole-compta qui comprend la ligne :
factory=fr.exemole.bdfext.comptaexemole.ComptaExemoleExtensionFactory
Une fois l’extension installée, l’action de l’extension est accessible via l’adresse /ext/fr-exemole-compta/form.html. Le choix du chemin /form.html est le choix fait par l’extension, ce n’est pas une obligation fixée par BaseDeFiches qui se contente de transmettre à l’extension tout ce qui est après /xt/fr-exemole-compta.