01/08/2018
Introduction
Cet article décrit comment développer un plugin permettant de fournir des valeurs, issues d’un référentiel, au sein d’un formulaire d’indexation.
Prérequis :
- Notion de JavaScript, Java, Spring Boot et Maven
- Formulaire d’indexation
- Un tag
Family
modifiable de typeCHOICELIST
avec deux valeursf1
etf2
- Un tag
Nature
modifiable de typeFREELIST
Développement du plugin
Ouvrez votre IDE préféré et commencez par créer un projet Maven.
Maven
Afin de configurer correctement notre plugin basé sur Spring Boot, modifiez le fichier pom.xml
généré tel que :
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.flower.docs.samples</groupId>
<artifactId>gui-plugin-sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<swagger.version>2.9.2</swagger.version>
<spring.boot.version>2.1.0.RELEASE</spring.boot.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
<goal>build-info</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
</dependencies>
</project>
Spring Boot Application
Ce plugin est basé sur le framework Spring Boot et packagé sous la forme d’un JAR exécutable. Pour que l’exécution du JAR expose le web service de notre plugin, il est nécessaire de définir l’application suivante.
@SpringBootApplication
@EnableSwagger2
public class SampleApplication
{
public static void main(String[] args)
{
SpringApplication.run(SampleApplication.class, args);
}
@Bean
public Docket api()
{
return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any()).build();
}
}
Note : L’annotation @EnableSwagger2
permet de générer automatiquement une documentation à l’aide de Swagger
Ensuite pour configurer cette application Spring Boot ajouter dans le répertoire src/main/resources
, le fichier application.properties
suivant :
spring.application.name=gui-plugin-sample
security.basic.enabled=false
server.port=3006
server.servlet.context-path=/sample
Web service REST
Le web service suivant permet de gérer les GET faits sur /sample/families/{famille}
et ainsi de retourner des natures correspondantes.
@RestController
@RequestMapping("/families")
public class FamiliesService
{
@RequestMapping(value = "/{family}", method = { RequestMethod.GET })
public Map<String, String> resolveNatures(@PathVariable final String family)
{
switch (family)
{
case "f1":
Map<String, String> natures = new HashMap<>();
natures.put("n1", "Nature1");
natures.put("n2", "Nature2");
return natures;
default:
Map<String, String> defaultNatures = new HashMap<>();
defaultNatures.put("unknown", "Unknown");
return defaultNatures;
}
}
}
Lancement du plugin
Après avoir ouvert un terminal et être allé dans le dossier du projet, exécuter les commandes suivantes :
mvn clean install
java -jar target/gui-plugin-sample-0.0.1-SNAPSHOT.jar
Intégration du plugin dans l’IHM
Maintenant que vous êtes en possession du plugin, nous allons l’intégrer dans un formulaire d’indexation afin que nous puissions profiter des valeurs qu’il renvoie.
Avant de commencer, il est nécessaire de définir le plugin au niveau de FlowerDocs GUI dans le fichier gui.properties
comme indiqué dans la documentation :
zuul.routes.sample.path=/plugins/sample/**
zuul.routes.sample.url=http://localhost:3006/sample
Consommons le plugin
A l’aide de la librairie jQuery, nous pouvons désormais consommer le web service exposé avec le script suivant :
var family = "f1";
$.ajax({
url: "./plugins/sample/families/"+family
}).then(function(data) {
console.log("Natures have been resolved for family="+family);
$.each(data, function(key, label) {
console.log("key="+key+", label="+label);
});
});
Intégration dans un formulaire
Afin d’intégrer le plugin, ouvrez la console JavaScript de votre navigateur et ajoutez le script suivant :
var inputTagName = "Family"; var outputTagName = "Nature";
JSAPI.get().registerForComponentChange(function(api, component, phase) {
if(api.hasField(inputTagName) && api.hasField(outputTagName)){
bindOnFamilyChange(api);
}
});
function bindOnFamilyChange(api){
api.registerForFieldChange(inputTagName, function(fieldName, fieldValue) {
resolveNatures(fieldValue, api);
});
}
function resolveNatures(family, api){
$.ajax({
url: "./plugins/sample/families/"+family
}).then(function(data) {
console.log("Natures have been resolved for family="+family);
var allowedValues = new Array();
$.each(data, function(key, label) {
allowedValues.push(buildAllowedValue(key, label));
});
api.setAllowedValues(outputTagName, allowedValues);
});
}
function buildAllowedValue(symbolicName, label) {
var language = new Language("EN");
var allowedValue = new AllowedValueDefinition();
allowedValue.setSymbolicName(symbolicName);
var displayNames = new I18NLabel()
displayNames.setLabel(language, label);
allowedValue.setDisplayNames(displayNames);
return allowedValue;
}
Famille
et Nature
.
Pour aller plus loin
Un plugin peut également être utilisé pour interagir avec FlowerDocs à travers les web services exposés. Pour cela, il est nécessaire de fournir un token utilisateur à FlowerDocs.
Commençons par ajouter la dépendance aux API FlowerDocs :
<dependency> <groupId>com.flower.docs.core</groupId> <artifactId>flower-docs-ws-client</artifactId> <version>${flower.version}</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency>
Ensuite nous ajoutons un filtre HTTP permettant d’initialiser le contexte utilisateur à partir du jeton fourni par FlowerDocs :
@Configuration @ImportResource(locations = { "classpath:flower-docs-security-token.xml", "classpath:flower-docs-services-webservices.xml" }) @ComponentScan("com.flower.docs.security.token") @EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled = false) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.addFilterBefore(tokenFilter(), BasicAuthenticationFilter.class); } @Bean TokenAuthenticationFilter tokenFilter() throws Exception { TokenAuthenticationFilter filter = new TokenAuthenticationFilter(); filter.setAuthenticationManager(authenticationManagerBean()); return filter; } }
Il ne nous reste plus qu’à interagir avec les services FlowerDocs. Dans l’exemple ci-dessous, nous comptons le nombre total de documents :
@RestController public class FlowerRestController { @Autowired private DocumentService documentService; @RequestMapping(value = "/count", method = RequestMethod.GET) public String generateFromTags() throws TechnicalException, FunctionalException { return "ok: " + documentService.search(new SearchRequest()).getFound(); } }