Manuel de développement :

1. Introduction :
Ce document est un guide ayant pour volonté d'expliquer à un programmeur comment développer une application communiquant avec n serveur EpiSEM Action.
Ce guide n'a pas pour vocation d'enseigner un langage de développement mais comment utiliser ce savoir-faire dans le cadre d'EpiSEM Action.
De plus, ce guide n'enseigne pas l'exploitation exhaustive d'EpiSEM Action mais seulement les outils employés dans l'application.
Pour de plus amples informations, il est conseillé de consulter la documentation fournie avec EpiSEM Action et l'équipe de développement d'EpiSEM Action.

1.1. L'application EpiAdmin :
EpiAdmin est une application client de gestion et d'administration du serveur d'EpiSEM Action.

1.2. L'application EpiBrowser :

EpiBrowser est une application qui a été conçue dans le but d'afficher le contenu d'un catalogue fourni par la plate-forme EpiSEM Action. Elle affiche les données sous forme de graphe 2D. Le développement d'EpiBrowser a nécessité l'utilisation de classes de l'application client ApiAdmin.

1.3. L'application EpiMuzz :
EpiBrowser est une application qui a été conçue dans le but d'afficher le contenu d'un catalogue fourni par la plate-forme EpiSEM Action. Elle affiche les données sous forme de graphe 2D. Le développement d'EpiBrowser a nécessité l'utilisation de classes de l'application client ApiAdmin.

2. Diagramme de cas d'utilisations :
EpiBrowser est une application qui a été conçue dans le but d'afficher le contenu d'un catalogue fourni par la plate-forme EpiSEM Action. Elle affiche les données sous forme de graphe 2D. Le développement d'EpiBrowser a nécessité l'utilisation de classes de l'application client ApiAdmin.



Figure 1 : Diagramme de cas d'utilisation


3. Choix du langage de programmation :
Tout langage de programmation capable de communiquer avec des webservices est utilisable. Dans notre contexte, pour une cohérence avec les classes java de l'application client EpiAdmin, le développement d'EpiMuzz s'est effectué en Java. En effet, les applications EpiAdmin et EpiBrowser fournissent des librairies de développement.
Les classes EpiMuzz sont regroupées dans des archives JAR exécutables sous Java Web Start.
Dans la suite du document, le langage considéré sera Java.

4. Librairies nécessaires :
Utilisant Java comme langage de programmation, qui est également celui des clients EpiBrowser et EpiAdmin, il est conseillé d'exploiter le fichier EpiBrowser-full.jar, archive compilée de EpiBrowser. Cette archive contient les classes du client EpiBrowser, ainsi que celles d'EpiAdmin.
Il est également possible d'utiliser l'archive de l'application EpiMuzz comme librairie.

5. Lexique des termes anglophones d'une ontologie :
- Project : un projet
- Catalogue : identique au terme français : un catalogue du projet
- Content : le contenu d'un catalogue
- Category : un concept
- Relation : une relation
- Subject : une instance


6. Le développement :


6.1. Le modèle Seeheim :
Le modèle de Seeheim est un modèle global qui comprend trois modules: la présentation , le contrôle du dialogue et l'interface avec l'application.


Figure 2 : Le modèle Seeheim


Pour des raisons de clarté et de rigueur, nous avons opté pour le modèle Seeheim dans le but de séparer la présentation, le moteur de l'application et le contrôleur.

6.2. La classe :
Dans ce qui suit, sera décrite la classe du moteur de l'application EpiMuzz.
La classe gérant la connexion doit implémenter l'interface ClientController pour autoriser les différentes connexions au serveur. Ceci implique la définition de deux méthodes :
- public LoginHandler getLoginHandler()
- public void setConnected(boolean b)

6.3. Connexion au serveurEpiSEM Action :
Pour assurer la connexion au serveur EpiSEM, la classe \textit{org.episemaction.util.epitools.LoginHandler} doit être initialisée. Dans le code source d'EpiMuzz, toutes les informations concernant les paramètres de connexion sont imposées mais, bien entendu, il est possible de développer une interface utilisateur permettant la modification de ces paramètres par l'utilisateur lui-même.
Deux adresses de serveur sont nécessaires :
- "http://127.0.0.1:8080/episemaction/services/" pour la connexion au web service
- "http://127.0.0.1:8080/episemaction/servlet/FileTransferServlet" pour le transfert de fichiers

Voici un script de connexion exploitant la classe LoginHandler:

//New login handler
lh = new LoginHandler(this);
//Servers adresses
lh.setServer(SERVEURSERVICES,SERVEURSERVLET);
//Connection thanks to the login handler with the user and its password
lh.doLogin(USER,PASSWORD);

6.4. Logique projet, projet, catalogue et contenu :
Une fois connecté au serveur, il est nécessaire de récupérer les éléments nécessaires, sans prendre en considération, pour l'instant, les entités enregistrées. Il s'agit alors seulement des catalogues et projets les contenant. Pour cela, chaque élément doit être récupéré une fois que son 'parent' a été défini.
Ainsi, il n'est pas possible de connaître un catalogue sans connaître le projet dont il fait partie.

Dans l'ordre, il faut obtenir :
- La logique projet
- Le projet visé
- Le catalogue du projet
- Le contenu du catalogue

Pour cela, il est possible d'utiliser le code suivant, par exemple :

//To get the project logic
pl= lh.getProjectLogic();
//To get the project
pr=pl.getProject(PROJET);
//To get the catalogue
cat=pr.getCatalogue(CATALOGUE);
//To get the content of the catalogue
cont=cat.getContent();

- lh : LoginHandler ayant permis la connexion
- PROJET : variable String définie dans les attributs de la classe
- CATALOGUE : variable String définie dans les attributs de la classe

6.5. L'interface Entity :
Toute classe d'éléments, qu'ils soient concept, relation ou instance, implémente l'interface org.episemaction.knowledge.model.Entity. Il est possible à partir de cette interface, d'obtenir des informations telles que le label (ou nom unique) de l'élément, etc.

6.6. Les concepts :
Les concepts sont les éléments clé d'une ontologie : une relation lie différents concepts entre eux et une instance a les mêmes propriétés que son concept.
La classe permettant leur utilisation est la classe org.episemaction.knowledge.model.kaon.CategoryAdapter implémentant l'interface Category.
Il est possible d'obtenir l'ensemble des concepts d'un catalogue (plus précisément de son contenu) grâce à la méthode \textit{getCategories()} appliquée à une instance de la classe org.episemaction.knowledge.model.Content. Cette méthode renvoie une instance de java.util.Set qu'il est alors possible d'exploiter.

6.7. Relations et attributs :
Une relation lie deux concepts entre eux ou un concept et un attribut.
Il est possible d'obtenir différentes listes de relations à partir d'une instance de la classe Category :
- getRelationsTo(): cette méthode permet d'obtenir l'ensemble des relations pointant sur le concept courant
- getRelationsFrom(): cette méthode renvoie l'ensemble des relations partant du concept courant.

6.8. Les instances :
Il est possible de récupérer l'ensemble des instances d'un concept grâce à la méthode de l'interface Category : getSubjects()
A partir d'une instance, l'obtention des propriétés visées par une relation depuis une instance donnée se fait via une méthode précise de la classe SubjectAdapter, la méthode getDataAccessibleFromRelation(RelationAdapter rA). Cette méthode permet de connaître l'ensemble des données (qui peuvent ne pas être des instances de concept) \textit{visés} par une relation précise du concept auquel appartient l'instance.
Il est nécessaire de déterminer la relation du concept avant de rechercher l'élément visé par cette relation en fonction de l'instance du concept.
Cette fonction permet de récupérer un Set ; suivant la relation, il peut s'agir d'un Set d'instances (SubjectAdapter) ou d'un Set de chaînes de caractères, lorsque la relation ne lie pas deux concepts mais un concept et un attribut.

6.9. Les méthodes :
Nous considèrerons dans notre application qu'une catégorie (category) est un concept et qu'un sujet (subject) est une instance.


6.10. Relations et attributs :
Une relation lie deux concepts entre eux ou un concept et un attribut.
Il est possible d'obtenir différentes listes de relations à partir d'une instance de la classe Category :

getSubGender(genre, relation) : Cette méthode permet de renseigner les sous-genres directs d'un genre donné.
La fonction renvoie un tableau de type ArrayList. Elle prend en paramètres le genre et la relation "a\_pour\_sous\_genre".
La fonction \textit{getDataAccessibleFromRelation()} est une méthode de la classe \textit{SubjectAdapter} et sont décrites dans la javadoc d'EpiSEM et qui renvoie les données correspondantes à une relation donnée.
La fonction parcourt le tableau \textit{subjectsArray} qui contient l'ensemble des instances visées par la relation "a\_pour\_sous\_genre" et récupère leur nom.

getGenders(genre) : Cette fonction permet de renseigner l'ensemble des sous-genres d'un genre donné en parcourant toute l'arborescence de ces sous-genres. La fonction renvoie un tableau de type ArrayList. Le tableau catArray récupère toutes les catégories grâce à la fonction getCategories que nous verrons plus en détails ultérieurement. La fonction parcourt ce tableau et, si la catégorie trouvée est le genre, elle est alors récupérée par le tableau result. Ensuite on récupère les instances des genres dans le tableau instances par la méthode getSubjects() décrite dans la javadoc d'EpiSEM Action.

getNonRedundantList(liste) : Cette fonction sert à éviter la répétition dans un tableau de type ArrayList.

getCategories(contenu du catalogue) : Cette fonction sert à récupérer toutes les catégories (les concepts) d'un catalogue et les renvoie sous forme d'un tableau d'objets contrairement à la méthode équivalente de l'interface Content qui les renvoie sous forme de Set.

getRelationsFrom(categorie) : Cette fonction permet de récupérer toutes les relations issues d'un concept. C'est une fonction prédéfinie dans EpiAdmin et elle renvoie un objet de type Set (ensemble) contenant les relations. Pour des raisons de simplicité, nous avons défini une fonction du même nom mais qui renvoie des relations dans un objet de type ArrayList car ce type offre plus de souplesse que le type Set.

getRelationsTo(categorie) : Cette fonction permet de récupérer toutes les relations allant vers un concept donné. Il s'agit de la réciproque de getRelationsFrom.

getRelationsFromTitle() : Il s'agit d'une application de la fonction \textit{getRelationsFrom} au concept Titre.
La méthode récupère toutes les catégories.

getData(liste de relations, langue, label de relation) : Elle sert à renvoyer une relation issue d'un ensemble de relations en fonction de son nom.
La fonction prend en paramètres un tableau de relations, la langue et une relation donnée. Le programme parcourt le tableau de relations, au moment où il trouve la relation donnée en paramètre, la fonction renvoie cet élément du tableau qui est la relation.

mainSearch(langue, critere, champ) : C'est la méthode de recherche d'un titre dans l'ontologie. La méthode prend en paramètres la langue, le critère et une chaine de caractères appelée field.
Si le critère entré par l'utilisateur est relatif au genre musical alors la valeur retournée est la valeur de la fonction searchGender appelée avec les mêmes paramètres. Sinon c'est la fonction commonSearch qui est appelée.

searchGender(langue, critere, champ) : C'est la méthode qui permet de faire une recherche suivant le genre.
La variable sub est de type ArrayList et contient l'ensemble des sous-genres du genre field renseigné par l'utilisateur. La variable result est de même type que la précédente et contient la valeur de la fonction commonSearch.
Si sub n'est pas vide alors on le parcourt cela veut dire qu'on parcourt l'ensemble des sous-genres et la fonction est appelée par récursivité avec en paramètres la langue, le critère et le sous-genre trouvé. Cela signifie que la méthode searchGender est appliquée à tous les sous-genres du genre renseigné. Ce qui revient à dire que lorsqu'une recherche se fait suivant le genre musical, elle se fait automatiquement suivant tous les sous-genres correspondant ce qui est un des points forts de notre application.

commonSearch(langue, critere, champ) : C'est une méthode de recherche suivant un critère donné.
On récupère tous les concepts dans un tableau qu'on parcourra. Si le concept est le titre alors la variable publique result, déclarée au début du programme, contiendra ce concept.
On définit ensuite, la variable relArray qui récupère les relations du concept, la variable results qui contiendra le résultat recherché et la variable instances de type tableau qui contient les instances des concepts.
On parcourt le tableau des instances et on récupère la valeur de la relation dans la variable currentSet de type ensemble qu'on transformera en type tableau.
On teste si la relation est un attribut alors on récupère le nom de l'instance dans la variable name par le biais de la fonction getInstanceName. Sinon, si la relation n'est pas un attribut alors on récupère la valeur de la relation dont le type est transformé en une chaîne de caractères.

compare(liste) : Si l'utilisateur fait, par exemple, une recherche sur le genre Rock et sur l'artiste Johny Hallyday en sachant que le genre Rock lui correspondent plusieurs titres de chansons et que l'artiste Johny Hallyday a interprété plusieurs titre. Le résultat souhaité sera donc les titres en commun a ses deux ensembles et donc du point de vue mathématique, ce sera l'intersection des deux ensembles. Cette intersection est réalisée par la méthode compare.
La méthode compare prend en paramètre une liste. Cette liste contient à son tour plusieurs autres listes d'instances. Supposons que l'utilisateur a fait une recherche sur trois critères (concepts), la liste mainList contiendra trois listes, chacune contenant les résultats pour chaque critère. La variable base récupère la première liste et donc le premier élément de mainList, pour le comparer aux autres éléments. Pour que l'intersection des trois listes soit non vide, il suffit de comparer la première liste aux deux autres et de trouver au moins un élément dans les trois listes.
La méthode compare est utilisée par la méthode searchResults que nous détaillerons ultérieurement.

getInstanceName(ensemble d'instances) :Cette méthode sert à récupérer le nom d'une instance récupérée par une relation dans le but de l'afficher. Elle prend en paramètre un ensemble d'instances.

getElementsToPrint(tableau) : C'est la méthode qui va regrouper toutes les instances des concepts en listes d'instances, récupère leur nom, les insère dans un tableau de type ArrayList pour pouvoir les afficher.

searchResults(requetes) : C'est la seule fonction appelée par le contrôleur de l'application. Elle fait appel à trois autres fonctions définies dans notre application : la méthode mainSearch pour faire la recherche d'un titre dans l'ontologie, la méthode compare pour faire l'intersection des listes des résultats et la méthode getElementsToPrint pour afficher le résultat final.