· web viewaermc manuel du développeur. framework de l’agence de l’eau. auteur : rémi...

82
Date : 29/05/2022 Manuel du développeur AERMC Manuel du développeur Framework de l’agence de l’eau Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE Mise à jour Version Date Nature de la modification 1.0 Novembre 2014 Evolutions pour industrialisation 1.1 Aout 2015 Evolutions pour éditions BDOC

Upload: others

Post on 25-Nov-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

AERMC

Manuel du développeurFramework de l’agence de l’eau

Auteur :  Rémi BERTHET Vérificateur : Jérôme PAIRE

Mise à jourVersion Date Nature de la modification

1.0 Novembre 2014 Evolutions pour industrialisation1.1 Aout 2015 Evolutions pour éditions BDOC1.2 Octobre 2016 Evolutions   liées   au   développement   de   l’application   QEE   [BAO 

V3.1] Navigation en Mode « mono-onglet » File d’Ariane Conservations des critères Import de fichier CSV (librairie OpenCSV) Export de fichier CSV Déclaration des beans Spring en annotation Masquage des colonnes dans les tableaux de résultats Zone de texte extensible

1.3 Mars 2017 Précisions sur les évolutions de la BAO liées à QEE [BAO V3.1]

Page 2:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

DiffusionPour Agence de l’eau

Réf. : AERMC- Guide développeur V1.2

Page 3:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

SOMMAIRE1. Architecture globale du framework................................................................................................52. Evolutions apportées dans la version 3.1 / Généralisation.............................................................53. Configuration Spring.......................................................................................................................5

3.1. Préambule..............................................................................................................................53.2. XML.........................................................................................................................................5

3.2.1. Beans Spring...................................................................................................................63.2.2. Tiles / Ressources statiques............................................................................................63.2.3. Données..........................................................................................................................73.2.4. Intercepteurs..................................................................................................................83.2.5. Batchs.............................................................................................................................8

3.3. Annotations JAVA...................................................................................................................83.3.1. Classe de configuration référente...................................................................................93.3.2. Tiles...............................................................................................................................103.3.3. Données........................................................................................................................113.3.4. Batchs...........................................................................................................................14

4. Controller Spring : AbstractListFicheController.............................................................................144.1. Scénario courant...................................................................................................................144.2. Exemples de méthodes génériques......................................................................................154.3. Héritages..............................................................................................................................16

4.3.1. IListeController.............................................................................................................164.3.2. IFicheController............................................................................................................17

4.4. Interfaçage des Controllers...................................................................................................184.4.1. IActionForm : pour les validations de formulaires........................................................184.4.2. IModelAttributes : pour les attributs Spring..................................................................184.4.3. IModelForm : pour les modèles associés aux formulaires............................................18

5. Mapping Hibernate......................................................................................................................195.1. Table sans « PK »..................................................................................................................195.2. Utilisation de séquence........................................................................................................195.3. Astuces « OneToMany ».......................................................................................................19

6. Repository JPA..............................................................................................................................206.1. Querydsl...............................................................................................................................20

7. Services métier : IModeleService<M>...........................................................................................207.1. Besoins Hibernate.................................................................................................................207.2. Exécution de procédure stockée..........................................................................................21

7.2.1. A l’aide d’un SimpleJdbcCall.........................................................................................227.2.2. A l’aide d’un JdbcTemplate...........................................................................................22

7.3. Exécution de requête SQL.....................................................................................................237.3.1. En SQL direct.................................................................................................................237.3.2. En HQL..........................................................................................................................24

8. Intégration de nouveaux tags.......................................................................................................248.1. FwkLabelTag.........................................................................................................................258.2. FwkOngletsTag.....................................................................................................................258.3. FwkErreurChampOngletTag..................................................................................................25

Page 4:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

8.4. FwkPlusCriteresTag...............................................................................................................258.5. FwkUploadFileTag.................................................................................................................26

9. Introduction de nouvelles annotations.........................................................................................269.1. Contraintes de validation......................................................................................................26

9.1.1. Définition......................................................................................................................269.1.2. Utilisation......................................................................................................................27

9.2. Formatage de données.........................................................................................................279.2.1. Définition......................................................................................................................279.2.2. Déclaration dans la configuration Spring......................................................................299.2.3. Utilisation......................................................................................................................29

10. Externalisation de la connexion à la base de données..............................................................2910.1. Mode de connexion..........................................................................................................3010.2. Déclaration dans Tomcat..................................................................................................3010.3. Déclaration dans Spring....................................................................................................30

11. Définition des profils dans le LDAP...........................................................................................3111.1. Structure du LDAP.............................................................................................................3111.2. Requêtage dans le LDAP (service LdapDao)......................................................................3211.2.1. getDetailsFromNomUser(username)............................................................................3211.2.2. getDetailsFromNumint(numInt)....................................................................................3211.2.3. getProfilsUserApplication(username, codApp).............................................................3311.2.4. getProfilsApplication(codApp)......................................................................................3311.2.5. getApplications()...........................................................................................................33

12. Besoins spécifiques de l’Agence de l’Eau..................................................................................3312.1. Onglets applicatifs (jQuery)..............................................................................................33

12.1.1. Fonctionnement ‘léger’................................................................................................3312.1.2. Fonctionnement ‘complexe’.........................................................................................33

12.2. Onglets utilisateur (navigateur)........................................................................................3412.3. Mode de navigation..........................................................................................................34

12.3.1. Description....................................................................................................................3412.3.2. Fonctionnement du fil d’Ariane....................................................................................3512.3.3. Conservation des critères.............................................................................................3712.3.4. Paramétrage.................................................................................................................37

12.4. Export générique des tableaux de résultats.....................................................................3712.4.1. Problématiques.............................................................................................................3712.4.2. Principe de fonctionnement.........................................................................................3712.4.3. Prérequis Java...............................................................................................................3712.4.4. Application dans la JSP..................................................................................................38

12.5. Ecrans de suivi des Batchs................................................................................................3812.6. CSV....................................................................................................................................38

12.6.1. Imports.........................................................................................................................3912.6.2. Exports..........................................................................................................................40

12.7. Auto authentification avec Kerberos................................................................................4012.7.1. Paramétrage du serveur...............................................................................................4012.7.2. Paramétrage client.......................................................................................................4012.7.3. Création du fichier ‘keytab’...........................................................................................41

Page 5:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

12.8. Utilisation courante..........................................................................................................4112.8.1. DataTables....................................................................................................................4112.8.2. Auto complétion...........................................................................................................4212.8.3. Popups..........................................................................................................................4212.8.4. Dialog jQuery................................................................................................................4312.8.5. Actions XHR..................................................................................................................4612.8.6. Menus...........................................................................................................................4612.8.7. Multi-select...................................................................................................................4712.8.8. Upload..........................................................................................................................48

13. Gestion des éditions avec BDOC...............................................................................................4813.1. JAXB..................................................................................................................................4813.2. Traitement asynchrone.....................................................................................................49

13.2.1. Exemple........................................................................................................................4913.2.2. Paramétrage du batch..................................................................................................50

13.3. Traitement synchrone......................................................................................................5013.3.1. Génération directe........................................................................................................5013.3.2. Génération via Web Service..........................................................................................51

14. Système de batchs....................................................................................................................5314.1. Fonctionnement...............................................................................................................53

14.1.1. Utilisation d’un lanceur.................................................................................................5414.2. Configuration XML............................................................................................................5414.3. Exemples de cas fréquents :.............................................................................................56

14.3.1. Export (génération) de fichier XML...............................................................................5614.3.2. Import de fichier XML...................................................................................................56

15. Bibliothèque logicielle JAVA.....................................................................................................5716. Bibliothèque JavaScript............................................................................................................58

16.1. Plugins jQuery utilisés.......................................................................................................5816.2. Descriptif du contenu des fichiers JS spécifiques..............................................................58

16.2.1. ajaxForm.js....................................................................................................................5816.2.2. cookies.js......................................................................................................................5916.2.3. datatable.js...................................................................................................................5916.2.4. dialogRecherche.js........................................................................................................6016.2.5. framework.js.................................................................................................................6016.2.6. jq-styled-input.js...........................................................................................................6116.2.7. jqueryWidgetFramework.js..........................................................................................6116.2.8. xhrUtils.js......................................................................................................................62

Page 6:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

1. Architecture globale du framework

Voir le document « AERMC - Guide développeur V0 4.docx ».

2. Evolutions apportées dans la version 3.1 / Généralisation

Dans les paragraphes suivants, nous allons étudier quelles améliorations ont été ajoutées à la version initiale pour satisfaire aux besoins d’une industrialisation de cette BAO.

3. Configuration Spring

3.1. Préambule

Depuis la version 3 de Spring, il est possible de configurer une application basée sur ce framework à partir de classes JAVA (annotations) et non seulement des fichiers XML.

Dans le cadre de la BAO, la version initiale se basait sur une configuration XML. Au fur et à mesure des   différentes   évolutions   de   celle-ci,   la   configuration   par   annotation   a   été   introduite   afin   de bénéficier un certain nombre de ses avantages :

Permet de généraliser une configuration sur plusieurs applications (sans dupliquer les fichiers XML)

Syntaxe vérifiée à la compilation plutôt qu'à l'exécution  Complétion dans Eclipse sans plugin  Import Java mettant en évidence les dépendances non présentes  Refactoring facilité de la configuration  Ajout de code possible lors de la déclaration de beans (ex : logs)  Accélère le chargement du contexte applicatif  Traite la configuration comme du code  Navigation dans la configuration facilitée  Mixité possible avec la configuration XML  Plus besoin de connaitre les namespaces XML Syntaxe plus "moderne"

3.2. XML

Le   fichier  applicationContext.xml  utilisé   par   défaut   permet   de   déclarer   un   certain   nombre   de composants (Beans, vues, …) auprès de Spring.

Page 7:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

Ce fichier de configuration XML doit être déclaré au niveau du  web.xml  de l’application, là où est déclarée la Servlet Spring.

<!-- Définition de la Servlet --><servlet>

<servlet-name>Framework Spring</servlet-name><servlet-class>

fr.eau.rmc.framework.web.servlet.FrameworkSpringDispatcherServlet</servlet-class><init-param>

<param-name>contextConfigLocation</param-name><param-value>/WEB-INF/applicationContext.xml</param-value>

</init-param><load-on-startup>1</load-on-startup>

</servlet>

3.2.1. Beans Spring

Ces beans sont des singletons qui peuvent être injectés dans n’importe quel autre bean Spring grâce à l’annotation @Autowired. Ces beans peuvent être catégorisés en 3 familles :

@Service : permet d’identifier le bean en tant que service @Controller : permet d’identifier le bean en tant contrôleur Spring MVC @Component : annotation générique pouvant s’appliquer sur n’importe quel bean.

Ces   beans   sont   déclarés   à   l’aide   de   la   balise  <context:component-scan   base-package=’…’ »  qui permet de scanner  les différents packages  identifiés comme parent des beans Spring et ainsi   les partager avec les autres beans.

<!-- Déclaration du package à scanner pour les Controller --><context:component-scan base-package="fr.eau.rmc.framework.web" />

<!-- Déclaration du package à scanner pour les Service Métier --><context:component-scan base-package="fr.eau.rmc.framework.utils" /><context:component-scan base-package="fr.eau.rmc.framework.service" />

<!-- Déclaration du package à scanner pour les DAO --><context:component-scan base-package="fr.eau.rmc.framework.dao" />

<!-- Déclaration du package à scanner pour les utilitaires divers --><context:component-scan base-package="fr.eau.rmc.framework.utils" />

3.2.2. Tiles / Ressources statiques

Pour la configuration de Tiles, au moins 2 éléments doivent être déclarés dans le fichier XML :  TilesViewResolver TilesConfigurer

<!-- Déclaration des ressources statiques --><mvc:resources location="/resources/" mapping="/resources/**" />

Page 8:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

<mvc:resources location="/js/" mapping="/js/**" /><mvc:resources location="/css/" mapping="/css/**" /><mvc:resources location="/images/" mapping="/images/**" /><mvc:resources location="/swf/" mapping="/swf/**" />

<!-- TILES resolver --><bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">

<property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView" /></bean>

<!-- Definition Tiles --><bean id="tilesConfigurer"

class="org.springframework.web.servlet.view.tiles3.TilesConfigurer"><property name="definitions">

<list><value>/WEB-INF/tiles.xml</value>

</list></property>

</bean>

3.2.3. Données

La déclaration de la DataSource, de la configuration Hibernate ainsi que la gestion des transactions doivent aussi se faire dans le fichier XML.  <!-- Data Source Declaration (JNDI) --><jee:jndi-lookup id="dataSource" jndi-name="${database.gfr.jndi.name}" cache="false" lookup-on-startup="true" proxy-interface="javax.sql.DataSource" />

<bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean"> <property name="entityManagerFactory" ref="entityManagerFactory"/></bean> <!-- Déclaration EntityManager --><bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

<property name="dataSource" ref="dataSource" /><property name="packagesToScan">

<array> <value>fr.eau.rmc.framework.model</value> </array> </property>

<property name="jpaVendorAdapter"><bean

class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"><property name="showSql" value="${dev}" /><property name="generateDdl" value="false" /><property name="databasePlatform"

value="org.hibernate.dialect.Oracle10gDialect" /></bean>

</property></bean>

Page 9:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

<!-- Publishing session factory to be able access HibernateSessionFactory --><bean id="sessionFactory" factory-bean="entityManagerFactory" factory-method="getSessionFactory" />

<!-- Declaration TransactionManager JPA --><bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">

<property name="entityManagerFactory" ref="entityManagerFactory" /><property name="jpaDialect" ref="hibernateJpaDialect" />

</bean>

<bean id="hibernateJpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />

<tx:annotation-driven transaction-manager="transactionManager" /><!-- Declaration package des repositories JPA --><jpa:repositories base-package="fr.eau.rmc.framework.dao.repositories" factoryclass="fr.eau.rmc.framework.dao.repositories.FrameworkRepositoryFactoryBean" />

3.2.4. Intercepteurs

Les intercepteurs (avant et après l’exécution de la requête HTTP) doivent également être déclarés dans le fichier XML.

<!-- Configures Handler Interceptors --><mvc:interceptors>

<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />

<bean class="fr.eau.rmc.framework.web.interceptors.TempsExecutionInterceptor" />

<bean class="fr.eau.rmc.framework.web.interceptors.HistoriqueNavigationInterceptor" />

<bean class="fr.eau.rmc.framework.web.interceptors.CrudableInterceptor" /><bean class="fr.eau.rmc.framework.web.interceptors.RechercheInterceptor" />

</mvc:interceptors>

3.2.5. Batchs

Les batchs sont définis dans un fichier XML séparé mais qui  doit cependant être déclaré dans le fichier applicationContext.xml.

<!-- ######################### Batchs ######################### --><import resource="appBatchJobs.xml" />

3.3. Annotations JAVA

Comme pour la configuration XML, celle par annotations est définie au niveau de la servlet Spring dans le web.xml où est indiquée la classe référence de la configuration par annotation.

Page 10:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

<!-- Définition de la Servlet --><servlet>

<servlet-name>Framework Spring</servlet-name><servlet-class>

fr.eau.rmc.framework.web.servlet.FrameworkSpringDispatcherServlet</servlet-class><load-on-startup>1</load-on-startup>

</servlet>

<!-- Paramètres Spring --><context-param> <param-name>contextClass</param-name> <param-value> org.springframework.web.context.support.AnnotationConfigWebApplicationContext </param-value></context-param><context-param> <param-name>contextConfigLocation</param-name> <param-value> fr.eau.rmc.gda.configuration.GdaConfiguration </param-value></context-param>

3.3.1. Classe de configuration référente

Chaque classe de configuration, s’identifie par l’annotation @Configuration.

A partir de cette classe, il est notamment possible de définir : l’import d’une configuration basée sur un fichier XML (@ImportResource) des classes sœurs dont la configuration sera chargée au démarrage (@Import) les packages à scanner pour trouver les Beans Spring à instancier (@ComponentScan) le fichier de propriétés de l’application (@PropertySource)

@Configuration@ImportResource({ "/WEB-INF/gdaBatchJobs.xml", })@Import(value = { //

FrameworkWebConfig.class, //FrameworkViewResolverConfig.class, //FrameworkMailConfig.class, //GdaJmxConfig.class, //GdaDataSourceConfig.class, //GdaInfrastructureConfig.class, //FrameworkSecurityInfrastructureConfig.class, //FrameworkSecurityConfig.class, //FrameworkSecurityKerberosConfig.class, //

})@ComponentScan(basePackages = { //

"fr.eau.rmc.gda.web", "fr.eau.rmc.gda.service", "fr.eau.rmc.gda.webservice", //

"fr.eau.rmc.gda.interfaces.editique", "fr.eau.rmc.gda.dao", "fr.eau.rmc.gda.aop" //

Page 11:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

})@EnableJpaRepositories(basePackages = { "fr.eau.rmc.gda.dao.repositories" }, repositoryFactoryBeanClass = FrameworkRepositoryFactoryBean.class)@PropertySource({ "file:/appli/propappli/gda.properties" })@EnableWebMvc@EnableAspectJAutoProxypublic class GdaConfiguration extends FrameworkConfiguration {

} Classe mère : FrameworkConfiguration

@Configuration@PropertySource({ "file:/appli/propappli/activeDirectory.properties" })@ComponentScan(basePackages = { //

"fr.eau.rmc.framework.web", "fr.eau.rmc.framework.service", "fr.eau.rmc.framework.dao", "fr.eau.rmc.framework.aop", "fr.eau.rmc.framework.utils", //})@EnableJpaRepositories(basePackages = { "fr.eau.rmc.framework.dao.repositories" }, repositoryFactoryBeanClass = FrameworkRepositoryFactoryBean.class)@EnableSchedulingpublic abstract class FrameworkConfiguration extends WebMvcConfigurerAdapter {

@Beanpublic CsUserService csUserService() {

return new CsUserServiceImpl();}

@Beanpublic LdapDao ldapDao(Environment environment) {

LdapDaoImpl ldapDao = new LdapDaoImpl(); […]

return ldapDao;}

[…]

@Overridepublic void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(localeChangeInterceptor());registry.addInterceptor(crudableInterceptor());registry.addInterceptor(rechercheInterceptor());registry.addInterceptor(historiqueNavigationInterceptor());

}

@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {

super.addResourceHandlers(registry); registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");

registry.addResourceHandler("/js/**").addResourceLocations("/js/");registry.addResourceHandler("/css/**").addResourceLocations("/css/");

registry.addResourceHandler("/images/**").addResourceLocations("/images/");registry.addResourceHandler("/swf/**").addResourceLocations("/swf/");

}

Page 12:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

}

Dans cette classe, sont définis les Beans Spring du Framework qui sont amenés à être utilisés dans les différentes applications (services LDAP, utilisateurs, …). On retrouve également les intercepteurs et les ressources statiques.

3.3.2. Tiles

Une classe dédiée à la configuration de Tiles (or déclaration des vues qui reste paramétrée dans le fichier tiles.xml) : FrameworkViewResolverConfig (qui pourra être surchargée au besoin dans chaque application).

@Configurationpublic class FrameworkViewResolverConfig {

private interface VIEW {String FRAMEWORK_EXCEPTION_ONGLET = "frameworkExceptionOngletView";String FRAMEWORK_EXCEPTION = "frameworkExceptionView";

}

@Autowiredprivate ServletContext servletContext;

@Beanpublic UrlBasedViewResolver tilesViewResolver() {

UrlBasedViewResolver urlBasedViewResolver = new UrlBasedViewResolver();

urlBasedViewResolver.setViewClass(FwkTilesView.class);return urlBasedViewResolver;

}

@Beanpublic TilesConfigurer tilesConfigurer() {

TilesConfigurer tilesConfigurer = new TilesConfigurer();tilesConfigurer.setDefinitions("/WEB-INF/tiles.xml");return tilesConfigurer;

}

[…]

@Beanpublic SimpleMappingExceptionResolver simpleMappingExceptionResolver() {

SimpleMappingExceptionResolver mappingExceptionResolver = new SimpleMappingExceptionResolver();

Properties mappings = new Properties();mappings.put(FrameworkException.class.getName(),

VIEW.FRAMEWORK_EXCEPTION);mappings.put(FrameworkExceptionInOnglet.class.getName(),

VIEW.FRAMEWORK_EXCEPTION_ONGLET);mappings.put(IllegalArgumentException.class.getName(),

VIEW.FRAMEWORK_EXCEPTION);mappings.put(HttpRequestMethodNotSupportedException.class.getName(),

VIEW.FRAMEWORK_EXCEPTION);

Page 13:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

mappingExceptionResolver.setExceptionMappings(mappings);return mappingExceptionResolver;

}}

3.3.3. Données

3.3.3.1. Accès BD

Pour accéder à la base de données, une classe abstraite (FrameworkDataSourceConfig) a été créée au niveau du Framework où l’implémentation doit uniquement fournir le nom de la connexion JNDI correspondante à l’application (en fait, il y a 2 connexions JNDI : 1 pour la partie sécurité et 1 pour l’application en elle-même).

@Configurationpublic abstract class FrameworkDataSourceConfig {

protected abstract String getJndiName(Environment env);

protected abstract String getJndiConnexionName(Environment env);

@Beanpublic JndiObjectFactoryBean dataSource(Environment env) throws

IllegalArgumentException {JndiObjectFactoryBean dataSource = new JndiObjectFactoryBean();dataSource.setJndiName(this.getJndiName(env));dataSource.setCache(false);dataSource.setLookupOnStartup(true);dataSource.setProxyInterface(DataSource.class);return dataSource;

}

@Beanpublic JndiObjectFactoryBean dataSourceConnexion(Environment env) throws

IllegalArgumentException {JndiObjectFactoryBean dataSource = new JndiObjectFactoryBean();dataSource.setJndiName(this.getJndiConnexionName(env));dataSource.setCache(false);dataSource.setLookupOnStartup(true);dataSource.setProxyInterface(DataSource.class);return dataSource;

}

}

Avec un exemple de son implémentation :

@Configurationpublic class GdaDataSourceConfig extends FrameworkDataSourceConfig {

Page 14:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

@Overrideprotected String getJndiName(Environment env) {

return env.getProperty("database.gda.jndi.name");}

@Overrideprotected String getJndiConnexionName(Environment env) {

return env.getProperty("database.gda.cnx.jndi.name");}

}

3.3.3.2. Hibernate

Pour le paramétrage Hibernate, une classe abstraite (FrameworkInfrastructureConfig) a été créée au niveau du Framework où l’implémentation doit uniquement fournir le nom des packages à scanner (pour effectuer le mapping Hibernate).

@Configurationpublic abstract class FrameworkInfrastructureConfig {

@Autowiredprivate DataSource dataSource;

protected abstract String[] getPackagesToScan();

@Beanpublic SharedEntityManagerBean entityManager(Environment env) {

SharedEntityManagerBean entityManagerBean = new SharedEntityManagerBean();

entityManagerBean.setEntityManagerFactory(entityManagerFactory(env));return entityManagerBean;

}

@Beanpublic EntityManagerFactory entityManagerFactory(Environment env) {

LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();

em.setDataSource(this.dataSource);em.setPackagesToScan(this.getPackagesToScan());em.setJpaVendorAdapter(jpaVendorAdaper(env));em.afterPropertiesSet();return em.getObject();

}

@Beanpublic JpaVendorAdapter jpaVendorAdaper(Environment env) {

HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();

hibernateJpaVendorAdapter.setShowSql(Boolean.valueOf(env.getProperty("dev")));hibernateJpaVendorAdapter.setGenerateDdl(false);

Page 15:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

hibernateJpaVendorAdapter.setDatabasePlatform("org.hibernate.dialect.Oracle10gDialect");

return hibernateJpaVendorAdapter;}

@Beanpublic JpaTransactionManager transactionManager(Environment env) {

JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();

jpaTransactionManager.setEntityManagerFactory(entityManagerFactory(env));jpaTransactionManager.setJpaDialect(hibernateJpaDialect());return jpaTransactionManager;

}

@Beanpublic JpaDialect hibernateJpaDialect() {

return new HibernateJpaDialect();}

}Avec un exemple de son implémentation :

@Configuration@EnableTransactionManagementpublic class GdaInfrastructureConfig extends FrameworkInfrastructureConfig {

@Overrideprotected String[] getPackagesToScan() {

return new String[] { "fr.eau.rmc.gda.model", "fr.eau.rmc.framework.model" };

}}

3.3.4. Batchs

Le paramétrage des  batchs  se  fait   toujours  à   l’aide  d’un fichier  XML qu’il   faut   importer  dans  la configuration Spring de base.

@Configuration@ImportResource({ "/WEB-INF/gdaBatchJobs.xml", })@Import(value = { //

FrameworkWebConfig.class, //FrameworkViewResolverConfig.class, //FrameworkMailConfig.class, //GdaJmxConfig.class, //GdaDataSourceConfig.class, //GdaInfrastructureConfig.class, //FrameworkSecurityInfrastructureConfig.class, //FrameworkSecurityConfig.class, //FrameworkSecurityKerberosConfig.class, //

})@ComponentScan(basePackages = { //

"fr.eau.rmc.gda.web", "fr.eau.rmc.gda.service", "fr.eau.rmc.gda.webservice",

Page 16:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

//"fr.eau.rmc.gda.interfaces.editique", "fr.eau.rmc.gda.dao",

"fr.eau.rmc.gda.aop" //})@EnableJpaRepositories(basePackages = { "fr.eau.rmc.gda.dao.repositories" }, repositoryFactoryBeanClass = FrameworkRepositoryFactoryBean.class)@PropertySource({ "file:/appli/propappli/gda.properties" })@EnableWebMvc@EnableAspectJAutoProxypublic class GdaConfiguration extends FrameworkConfiguration {

}

Il est possible d’activer (ou désactiver) le système de batchs, en modifiant la valeur (booléen) de la propriété execBatch au niveau du fichier de propriétés. Par défaut, la valeur sera true.

4. Controller Spring : AbstractListFicheController

4.1. Scénario courant Saisie de critères

Recherche correspondante

Modification de l’élément via une fiche

Ce scénario s’appuyant sur un type d’élément déterminé, il  semble logique de typer le Controller associé à cet ensemble d’actions. Ainsi, et de manière générique, il  sera possible d’accéder à des méthodes qui seront prédéfinies dans le Controller abstrait et qui devront être implémentées dans le Controller final.Ce Controller permet également de factoriser des algorithmes génériques : recherche par critères, création/modification de l’objet de référence (fiche)

4.2. Exemples de méthodes génériques

/** * Initialise les données suite à l'exécution de la recherche * * @param criteres * @return * @throws FrameworkException */protected void executerRecherche(final FormCriteres<T> criteres) throws FrameworkException {

// lancement de la rechercheList<T> listFromBD;if (this.getRecherchePageable() != null) {

// restriction de la recherche à l'aide d'un Pageable si celui-ci// est définiPage<T> pageRechercheElements =

Page 17:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

getModeleServiceRecherche().pageRechercheElements(criteres, this.getRecherchePageable());

listFromBD = pageRechercheElements.getContent();} else {

// recherche complètelistFromBD =

getModeleServiceRecherche().rechercherElements(criteres);}this.getLog().info(listFromBD.size() + " éléments correspondant à la

recherche !");// mise à jour de la liste de résultats sur l'objet CriteresFormcriteres.setList(listFromBD);// mise à jour de la liste de l'objet CriteresFormthis.setFormCriteres(criteres);// libération de la liste d'objets mappéslistFromBD = null;

// sauvegarde des critèresthis.setCriteresRechercheSauvegardes(criteres);

}

/** * Persiste la modification de l'objet de référence de la fiche * * @throws FrameworkException */protected void modifier() throws FrameworkException {

this.getModeleServiceFiche().modifier(this.getModeleFiche());}

/** * Persiste la création de l'objet de référence de la fiche * * @throws FrameworkException */protected void creer() throws FrameworkException {

this.getModeleServiceFiche().creer(this.getModeleFiche());}

4.3. Héritages

Ce Controller gérant à la fois la recherche et le cycle de vie d’un élément donné, 2 interfaces ont été introduites afin d’orienter le développeur dans ses choix de développement.

4.3.1. IListeController

Cette interface fournit toutes les méthodes nécessaires à l’exécution d’une recherche :

public interface IListeController<T extends MappedModel> extends IActionForm {

/** * Renvoie le nom de la vue associée à la recherche

Page 18:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

* * @return */String getViewRecherche();

/** * Renvoie l'action portée par le formulaire de recherche * * @return */@ModelAttribute(ACTION_FORM_RECHERCHE)String getRechercheActionForm();

/** * Initialise les données suite à l'exécution de la recherche * * @param criteres * @return * @throws FrameworkException */void executerRecherche(FormCriteres<T> criteres) throws FrameworkException;

/** * Service utilisé pour la recherche * * @return */IModeleService<T> getModeleServiceRecherche();

/** * Renvoie un Pageable (qui permet de limiter le nombre d'élément de la

liste de résultats) * * @return */Pageable getRecherchePageable();

}

4.3.2. IFicheControllerCette interface fournit les méthodes nécessaires au cycle de vie de l’élément (création, modification, suppression) :

public interface IFicheController<T extends MappedModel> extends IActionForm {

/** * Renvoie le nom de la vue associée à la fiche * * @return */String getViewFiche();

/** * Renvoie l'action portée par le formulaire de la fiche

Page 19:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

* * @return */@ModelAttribute(ACTION_FORM_FICHE)String getFicheActionForm();

/** * Renvoie l'objet Form correspondant à la fiche * * @param obj * @return */IFicheForm<T> getFormFicheFromModel(T obj);

/** * Persiste la création de l'objet de référence de la fiche * * @throws FrameworkException */void creer() throws FrameworkException;

/** * Persiste la modification de l'objet de référence de la fiche * * @throws FrameworkException */void modifier() throws FrameworkException;

/** * Persiste la création de l'objet de référence de la fiche * * @throws FrameworkException */void supprimer() throws FrameworkException;

/** * Service utilisé dans la fiche * * @return */IModeleService<T> getModeleServiceFiche();

}

4.4. Interfaçage des Controllers

Ces   interfaces  permettent  de  généraliser   l’injection  de  variables  dans   le   contexte  Spring :   noms d’action de validation, noms d’objet de base …Ces   interfaces   sont   implémentées   par   le   Controller   abstrait   (bien   qu’elles   ne   contiennent uniquement des constantes)

4.4.1. IActionForm : pour les validations de formulaires

public interface IActionForm {

Page 20:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

String ACTION_FORM_RECHERCHE = "actionFormRecherche";String ACTION_FORM_FICHE = "actionFormFiche";

}

4.4.2. IModelAttributes : pour les attributs Spring

public interface IModelAttributes {String RESULTATS_LIST = "resultats";String LIST_OPERATORS = "listOperators";String ERREUR = "erreur";String INFOS = "infos";

}

4.4.3. IModelForm : pour les modèles associés aux formulaires

public interface IModelForm {String CRITERES_FORM_OBJ = "criteresForm";String FICHE_FORM_OBJ = "ficheForm";

}

5. Mapping Hibernate

5.1. Table sans « PK »

Il est possible de rencontrer certaines tables ne possédant pas de « Primary Key ». Or, Hibernate a besoin  d’une PK pour  valider  son mapping.  Pour  contourner   le  problème, il   suffit de  mapper   le « rowid » en tant qu’identifiant de la table :

@Entity@Table(name = "cs_batch_erreur")public class BatchErreur implements MappedModel<Serializable>, Serializable { […]

@Id@Column(name = "ROWID", updatable = false, insertable = false, nullable =

false)private String rowID;

}

NB : ce mapping permet uniquement des ordres SQL de type ‘SELECT’, pour les mises à jour (‘INSERT’, ‘UPDATE’, ‘DELETE’) il faudra passer manuellement des ordres SQL.

5.2. Utilisation de séquence

Page 21:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

Exemple standard d’utilisation de déclaration de séquence :

@Entity@Table(name = "cs_batch_lance")public class BatchLance implements MappedModel<Long>, Serializable {

private static final long serialVersionUID = -3149271265373705542L;

@Id@Column(name = "NUMJOB", unique = true, nullable = false)@SequenceGenerator(name = "NUMJOB_GENERATOR", sequenceName =

"DBSECUR.SQ_NUMJOB_CS")@GeneratedValue(strategy = GenerationType.AUTO, generator =

"NUMJOB_GENERATOR")private Long numjob;

}

Ici,   « NUM_JOB_GENERATOR »   désigne   le   nom   du   générateur   de   séquence   à   utiliser   et « DBSECUR.SQ_NUMJOB_CS » le nom de la séquence à laquelle le générateur est associé.

5.3. Astuces « OneToMany »

Pour la suppression en cascade d’une liste d’objets liés par un « OneToMany », il faut bien penser à ajouter l’option ‘orphanRemoval’.

@OneToMany(fetch = FetchType.LAZY, mappedBy = "demandeAide", cascade = { CascadeType.ALL }, orphanRemoval = true)private List<DemandeAidePieces> listDemandeAidePieces = new ArrayList();

6. Repository JPA

6.1. Querydsl

Avec Spring Data JPA, il est possible de générer des requêtes simplement à l’aide de méthodes dont le nom s’appuie sur les critères de la requête. Ces méthodes sont à définir dans le Repository ET ne nécessite pas d’implémentation.

public interface CommuneRepository extends FrameworkRepository<Commune, String> {List<Commune> findByNumcomStartsWithOrderByNumcomAsc(String numcom);

List<Commune> findByNomcomIgnoreCaseStartsWithOrderByNomcomAsc(String nomcom);}

Page 22:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

Cf. doc Spring Data JPA :  http://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/ 

7. Services métier : IModeleService<M>

Avec cette interface, les méthodes standard devront être explicitement implémentées !

public interface IModeleService<M extends MappedModel> extends IHibernateService<M> {

List<M> rechercherElements(FormCriteres<M> criteres) throws FrameworkException;

M rechercherElementById(Serializable id) throws FrameworkException;

Page<M> pageRechercheElements(FormCriteres<M> criteres, Pageable pageable) throws FrameworkException;

void modifier(M modele) throws FrameworkException;

void creer(M modele) throws FrameworkException;

void supprimer(M modele) throws FrameworkException;}

7.1. Besoins Hibernate

Initialisation de listes ‘Lazy’      :  Afin de traiter de manière générique les initialisations d’objets Hibernate, un niveau d’abstraction a été ajouté pour traiter cette initialisation de façon générique. Pour cela, il faudra utiliser la classe abstraite AbstractModeleService :

public abstract class AbstractModeleService<M extends MappedModel<I>, I extends Serializable> implements IHibernateService<M> {

@Autowiredprivate JpaTransactionManager transactionManager;

/* (non-Javadoc) * @see

fr.eau.rmc.framework.service.IHibernateService#refresh(java.lang.Object) */@Overridepublic void refresh(M mappedModel) {

Session currentSession = createSession();currentSession.refresh(mappedModel);closeSession(currentSession);

}

private Session createSession() {

Page 23:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

EntityManagerFactory entityManagerFactory = transactionManager.getEntityManagerFactory();

EntityManager createEntityManager = entityManagerFactory.createEntityManager();

Session currentSession = createEntityManager.unwrap(Session.class);return currentSession;

}

private void closeSession(Session currentSession) {currentSession.close();

}

}

L’implémentation finale du service devra étendre cette classe :

@Servicepublic class CsBatchLanceServiceImpl extends AbstractModeleService<CsBatchLance, Long> implements CsBatchLanceService {

@Autowiredprivate CsBatchLanceRepository repository;

[…]

}

7.2. Exécution de procédure stockée

Ici, l’objectif est d’éviter au développeur de définir une nouvelle implémentation de l’appel à une procédure stockée à chaque fois qu’il en a besoin. De plus, la factorisation de ce code évite l’injection du ‘transactionManager’ (nécessaire à l’appel de la procédure stockée) dans chacun des services mais une fois et une seule via la classe abstraite.

7.2.1. A l’aide d’un SimpleJdbcCall

Pour utiliser cette solution, une méthode a été implémentée dans la classe ‘AbstractModeleService’ : « callProcStockWithSimpleJdbcCall(mapParametres, nomPackage, nomProcedure) » .Les paramètres sont les suivants :

mapParametres : définition des paramètres à passer en entrée de la procédure nomPackage : nom du package contenant la procédure nomProcedure : nom de la procédure

NB : pour pouvoir utiliser cette méthode, il faut que le service sur lequel on est en train de travailler étende la classe ‘AbstractModeleService’

Exemple : […]Map<String, Object> mapParameters = new HashMap<String, Object>();mapParameters.put("p_numint", numint);

Page 24:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

mapParameters.put("p_typeEmis", typeEmission);mapParameters.put("p_typeInterro", typeInterrogation);mapParameters.put("p_anexe", anexe);mapParameters.put("p_numtit", numtit);Map<String, Object> mapResult = this.callProcStockWithSimpleJdbcCall(mapParameters, "PARECHPIECE", "PRRECHPIECE");BigDecimal p_numrechor = (BigDecimal) mapResult.get("P_NUMRECHOR");[…]

ATTENTION : cette méthode ne fonctionne pas si le propriétaire (Oracle) n’est pas le même que celui utilisé pour l’application ! Si on est dans ce cas, il faudra utiliser la méthode définie ci-dessous.

7.2.2. A l’aide d’un JdbcTemplate

Cette méthode se rapproche de ce qui était fait dans la version 2.x de la BAO.Ici,   il   suffit   de   passer   l’ordre   SQL   correspondant   à   l’appel   de   la   procédure   stockée   désirée  « callProcStockWithJdbcTemplate(sqlCallProcStock, listSqlParameter, mapParameters) ». Les paramètres sont les suivants :

sqlCallProcStock : ordre SQL d’appel de la procédure listSqlParameter : déclaration des paramètres (IN et OUT) de la procédure maParameters : définition des paramètres à passer en entrée de la procédure

Exemple :[…]List<SqlParameter> listSqlParameter = new ArrayList<SqlParameter>();// déclaration des paramètres INlistSqlParameter.add(new SqlParameter("pcodappli", Types.VARCHAR));listSqlParameter.add(new SqlParameter("pnumint", Types.VARCHAR));[…]// déclaration des paramètres OUTlistSqlParameter.add(new SqlOutParameter("padr0", Types.VARCHAR));listSqlParameter.add(new SqlOutParameter("padr1", Types.VARCHAR));[…]listSqlParameter.add(new SqlOutParameter("retour", Types.NUMERIC));

Map<String, Object> mapParameters = new HashMap<String, Object>();mapParameters.put("pcodappli", numint);mapParameters.put("pnumint", numint);[…]String sql = "{CALL PRADRCPL (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)}";Map<String, Object> mapResult = this.callProcStockWithJdbcTemplate(sql, listSqlParameter, mapParameters);BigDecimal retour = (BigDecimal) mapResult.get("retour");[…]

7.3. Exécution de requête SQL

Page 25:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

Pour exécuter directement une requête SQL, il est nécessaire de récupérer la Session Hibernate. Afin d’éviter la création de Session dans chaque service qui en aura besoin, celui-ci sera déporté dans la classe ‘AbstractModeleService’.

NB :   une   Session   Hibernate   ne   doit   pas   être   utilisée   directement   dans   le   Service   créé   par   le développeur. Chaque besoin devra être déporté dans la classe abstraite.

7.3.1. En SQL direct

Il est possible d’exécuter directement une commande SQL (cf. org.hibernate.SQLQuery) à l’aide de la méthode « createSqlQuery(sqlQuery)» où sqlQuery est la commande SQL à exécuter.

7.3.1.1. Objet FwkHibernateSQLQuery

L’appel   de   la   méthode   « createSqlQuery(sqlQuery)»   renvoie   un   objet   de   type ‘FwkHibernateSQLQuery’.  Cet objet s’appuie sur  l’utilisation de la classe ‘SQLQuery’ de Hibernate ainsi que la Session Hibernate (invisible à l’extérieur).

Les méthodes visibles sont les suivantes :  setParameter(nomParam, valParam) : valParam peut être aussi bien un String, un Double, un 

Long, une Date, une List, … addEntity(classEntity) getList : exécute la méthode ‘list()’ de SQLQuery et ferme la session getUniqueResult : exécute la méthode ‘uniqueResult()’ de SQLQuery et ferme la session exeUpdate : exécute la méthode ‘executeUpdate()’ de SQLQuery et ferme la session

7.3.1.2. Exemple

[…]StringBuffer sb = new StringBuffer();sb.append("select vw.* ");sb.append(" from VW_SSBVPERIM@dbl_ig vw");sb.append(" where vw.codssbvperim in ( ");sb.append(" select c.codssbv ");sb.append(" from IG_NUMCOM@dbl_ig n, FC_INT i,IG_COMSSBV@dbl_ig c ");sb.append(" where n.lettre_corse = c.num_com ");sb.append(" and c.pourcent>=5 ");sb.append(" and n.texte = i.numcom ");if (!obj.isEPCI()) {

sb.append(" and i.numint = :numint ");} else {

sb.append(" and i.numcom in (:listNumcom )");}sb.append(" ) ");

FwkHibernateSQLQuery q = createSqlQuery(sb.toString());q.addEntity(VwSsbvperim.class);

Page 26:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

if (!obj.isEPCI()) {q.setParameter("numint", obj.getNumint());

} else {q.setParameter("listNumcom", obj.getListNumcom());

}

obj.setListVwSsbvperim((List<VwSsbvperim>) q.getList());[…]

7.3.2. En HQL

Il  est possible d’exécuter directement une commande SQL (cf.  org.hibernate.Query) à l’aide de la méthode « createHqlQuery(hqlQuery)» où hqlQuery est la commande HQL à exécuter.

7.3.2.1. Objet FwkHibernateQuery

L’appel   de   la   méthode   « createHqlQuery(hqlQuery)»   renvoie   un   objet   de   type ‘FwkHibernateHQLQuery’. Cet objet s’appuie sur l’utilisation de la classe ‘Query’ de Hibernate ainsi que la Session Hibernate (invisible à l’extérieur).

Les méthodes visibles sont les suivantes :  setParameter(nomParam, valParam) : valParam peut être aussi bien un String, un Double, un 

Long, une Date, une List, … getList : exécute la méthode ‘list()’ de Query et ferme la session getUniqueResult : exécute la méthode ‘uniqueResult()’ de Query et ferme la session exeUpdate : exécute la méthode ‘executeUpdate()’ de Query et ferme la session

8. Intégration de nouveaux tags

Les tags fournis par Spring peuvent ne pas être suffisant pour les besoins exprimés. Pour répondre à cette problématique, de nouveaux tags ont été introduit (notamment pour gérer les cas spécifiques liés aux onglets jQuery, cf. paragraphe sur les besoins spécifiques).

8.1. FwkLabelTag

Comme son nom l’indique,  ce tag (<aermc:label>)  se rapproche du  LabelTag  de Spring avec une petite évolution permettant d’intégrer un astérisque lorsque le champ associé est obligatoire et les ‘:’ faisant suite au libellé.

<aermc:label path="critereNumjob" cssClass="intituleChamp"><spring:message code="criteresBatch.numJob" />

</aermc:label>

Page 27:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

8.2. FwkOngletsTag

Ce tag (<aermc:onglets>) permet de générer des onglets jQuery à l’aide d’une seule balise. Celle-ci devra embarquer une map associant chaque libellé d’onglets à l’URL correspondante, cette map sera injectée dans la vue Spring.

<aermc:onglets mapOnglets="${mapOnglets}" id="ongletsLotsRapports" ongletInFiche="true"/>

8.3. FwkErreurChampOngletTag

Afin de gérer les messages lors de la validation du formulaire d’un onglet, il  a fallu introduire un nouvel élément (la validation Spring n’étant pas effective en XHR) permettant de gérer les retours du serveur.Ce tag est semblable au tag ErrorsTag de Spring.

<aermc:erreurChampOnglet champAssocie="selection" />

8.4. FwkPlusCriteresTag

Ce   tag   (<aermc:plusCriteres>)   permet  de   gérer   la   réduction  de   l’espace   dédié  aux   critères   (par extension, n’importe quel élément d’affichage) afin de gagner de la place. Par défaut, cette solution est implémentée sur tous les écrans de critères (elle contiendra l’ensemble des éléments de critères ainsi que le bouton « Rechercher »).

Les DIV qui seront « pliables » devront posséder la class CSS « optional » afin d’être correctement pris en compte lors des différentes actions.

Il existe 2 formes d’affichage du « Afficher / Masquer », soit sous la forme  , soit sous la forme  . Par défaut, l’affichage choisi est le second (triangle orienté vers le bas) mais il est possible d’afficher le premier (le « moins ») en affectant l’attribut « plusMoins » à « true ».

<form:form method="POST" action='${actionFormRecherche}' commandName="criteresForm">

<div class="fondBleu ui-corner-all" id="divCriteresForm"><aermc:plusCriteres path="displayCriteres" plusMoins="true">

<div id="criteresPage" class="optional"><tiles:insertAttribute name="page" />

</div><div id="criteresButtons" class='criteresButtons optional'>

<button type="submit" class="submit jq-searchbutton">Rechercher</button>

</div></aermc:plusCriteres>

</div></form:form>

Page 28:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

NB : penser à utiliser la fonction JavaScript apply_togglebutton() qui est appelée par défaut dans la page footerSimple.jsp.

8.5. FwkUploadFileTag

Ce   tag   (<aermc:uploadFile>)   permet  de  personnaliser   l’affichage  d’un  champ  de  chargement  de fichier (surtout pour le bouton « Parcourir »).

<form:form method="POST" action="${actionOnglet2}" commandName="formOnglet2" enctype="multipart/form-data">[…]

<aermc:label path="multipartFile" class="intituleChamp">Fichier</aermc:label>

<aermc:uploadFile path="multipartFile"/>[…]</form:form>

NB 1 : ne pas oublier la propriété « enctype » dans le formulaire englobant ce champ.NB 2 : penser à utiliser la fonction JavaScript apply_upload() qui est appelée par défaut dans la page footerSimple.jsp.

9. Introduction de nouvelles annotations

9.1. Contraintes de validation

9.1.1. Définition

Sur le modèle de l’interface  @Pattern, une annotation spécifique a été créée - afin de prendre en compte un libellé ‘intelligible’ lors de l’affichage du message d’erreur pour le pattern associé - dans le package « fr.eau.rmc.framework.web.validations.annotations » :

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })@Retention(RUNTIME)@Documented@Constraint(validatedBy = FwkPatternValidator.class)public @interface FwkPattern {

String nomChamp() default "";

String regexpExplicite() default "";[…]

}

Comme défini ci-dessous, cette annotation doit être associée à un Validator :

Page 29:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

public class FwkPatternValidator implements ConstraintValidator<FwkPattern, String> {

private java.util.regex.Pattern pattern;

public void initialize(FwkPattern parameters) { […]

}

public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {

if (value == null) {return true;

}Matcher m = pattern.matcher(value);return m.matches();

}}

9.1.2. Utilisation

public class CriteresListInterlocuteurs extends FormCriteres<Interlocuteur> implements Serializable {

@FwkPattern(regexp = "[\\d]{5}", message = "{error.champ.regexp}", nomChamp = "Numéro", regexpExplicite = "5 caractères numériques")

private String critereNumint;[…]

}

9.2. Formatage de données

9.2.1. Définition

De la même manière que pour les contraintes de validation, il est possible de créer des annotations permettant   de   gérer   le   formatage   des   données   (dans   le   package « fr.eau.rmc.framework.formatters.annotations ») :

@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })@Retention(RetentionPolicy.RUNTIME)public @interface NumIntFormat {}

Ici,   il   sera   nécessaire   de   définir   un  Formatter  qui   lui   sera   associé   à   l’aide   d’une   factory (AnnotationFormatterFactory) :

public class NumIntFormatter implements Formatter<String> {private final int numintLongueur;

Page 30:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

public NumIntFormatter(Integer numIntLongueur) {this.numintLongueur = numIntLongueur;

}

@Overridepublic String print(String object, Locale locale) {

return object;}

@Overridepublic String parse(String text, Locale locale) throws ParseException {

if (text.length() == numintLongueur || text.length() == 0) {return text;

}return StringUtils.leftPad(text, numintLongueur, "0");

}}

public class NumIntFormatterFactory implements AnnotationFormatterFactory<NumIntFormat> {

private Integer longueurNumInt;

public Integer getLongueurNumInt() {return longueurNumInt;

}

public void setLongueurNumInt(Integer longueurNumInt) {this.longueurNumInt = longueurNumInt;

}

@Overridepublic Set<Class<?>> getFieldTypes() {

Set<Class<?>> set = new HashSet<Class<?>>();set.add(String.class);return set;

}

@Overridepublic Printer<?> getPrinter(NumIntFormat annotation, Class<?> fieldType) {

return new NumIntFormatter(this.getLongueurNumInt());}

@Overridepublic Parser<?> getParser(NumIntFormat annotation, Class<?> fieldType) {

return new NumIntFormatter(this.getLongueurNumInt());}

}

9.2.2. Déclaration dans la configuration Spring

Pour déclarer la(les)  Factory correspondant aux différents  Formatter, il est nécessaire de les définir dans   le   fichier   XML   de   configuration   de   Spring   à   l’aide   du   bean FormattingConversionServiceFactoryBean :

Page 31:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

<beans xmlns=http://www.springframework.org/schema/beans […] ><!-- Déclaration des annotations MVC --><mvc:annotation-driven conversion-service="fwkConversionService" />

<bean id="fwkConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">

<property name="formatters"><list>

<bean class=" fr.eau.rmc.framework.formatters.NumIntFormatterFactory">

<property name="longueurNumInt" value="5" /></bean>

</list></property>

</bean>[…]

</beans>

9.2.3. Utilisation

public class CriteresListInterlocuteurs extends FormCriteres<Interlocuteur> implements Serializable {

@NumIntFormatprivate String critereNumint;

[…]

}

10.Externalisation de la connexion à la base de données

La solution choisie pour répondre à cette problématique est de créer une ressource JNDI au sein du serveur applicatif (Tomcat dans ce cas).

10.1. Mode de connexion

Le mode de connexion qui a été choisi est la ressource JNDI (cf § 9.2).

10.2. Déclaration dans Tomcat

Pour définir la ressource JNDI dans Tomcat il suffit de modifier le fichier context.xml du serveur (sur les   serveurs   d’intégration   ce   fichier   doit   se   trouver   dans  /appli/tomc-<appli>/tomcat/conf,   s’il n’existe pas il faudra le créer à l’identique de celui utilisé en local).

Page 32:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

<?xml version="1.0" encoding="UTF-8"?><Context>

<!-- Default set of monitored resources --> <WatchedResource>WEB-INF/web.xml</WatchedResource>

<!-- Datasource Jedi --><Resource name="jdbc/jedi" auth="Container"

driverClassName="oracle.jdbc.OracleDriver" maxActive="20" maxIdle="10" maxWait="10000" password="test" type="javax.sql.DataSource" url="jdbc:oracle:thin:@DEVSRV:1526:ETSIA" username="test" testOnBorrow="true" validationQuery="SELECT 1 FROM DUAL" validationQueryTimeout="10"/>

<!-- Datasource Security Jedi --><Resource name="jdbc/jedi-security" auth="Container"

driverClassName="oracle.jdbc.OracleDriver" maxActive="20" maxIdle="10" maxWait="10000" password="test" type="javax.sql.DataSource" url="jdbc:oracle:thin:@DEVSRV:1526:ETSIA" username="test" testOnBorrow="true" validationQuery="SELECT 1 FROM DUAL" validationQueryTimeout="10"/>

</Context>

Ici, deux ressources sont définies : Celle utilisée par l’application elle-même (jdbc/jedi) Celle utilisée pour l’authentification (jdbc/jedi-security) [celle-ci sera utilisée pour récupérer 

en base des infos lors de la connexion]

10.3. Déclaration dans Spring

La déclaration de la ressource JNDI dans Spring se fait  dans le fichier de configuration « <appli>-context.xml » à l'aide de la balise <jee:jndi-lookup>.

Par exemple :

<beans xmlns="http://www.springframework.org/schema/beans" [...]

xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="http://www.springframework.org/schema/mvc [...] http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd">

[...]<!-- Data Source Declaration -->

<jee:jndi-lookup id="dataSource" jndi-name="${database.jedi.jndi.name}" cache="false" lookup-on-startup="true" proxy-interface="javax.sql.DataSource" />

[...]

</beans>

Page 33:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

Dans   cet   exemple,   la   variable   « database.jedi.jndi.name »   sera   externalisée   dans   le   fichier   de propriétés de l’application :

[…]database.jedi.jndi.name=java:comp/env/jdbc/jedi[…]

Page 34:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

11.Définition des profils dans le LDAP

11.1. Structure du LDAP

Désormais les profils ne seront plus gérés dans une table ORACLE mais dans le LDAP. Le découpage s’effectue par Environnements / Applications / Profils / Utilisateurs selon le schéma ci-dessous établi par l’Agence de l’Eau.

Page 35:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

11.2. Requêtage dans le LDAP (service LdapDao)

11.2.1. getDetailsFromNomUser(username)Cette méthode permet de récupérer dans le LDAP les informations de l'utilisateur en fonction de son nom d'utilisateur.

11.2.2. getDetailsFromNumint(numInt)

Cette méthode permet de récupérer dans le LDAP les informations de l'utilisateur en fonction de son numéro (numInt).

11.2.3. getProfilsUserApplication(username, codApp)

Cette  méthode  permet  de   récupérer  dans   le   LDAP   la   liste  des  profils  d'un  utilisateur  pour  une application donnée.

11.2.4. getProfilsApplication(codApp)

Cette méthode permet de récupérer la liste des profils d'une application.

11.2.5. getApplications()

Cette méthode permet de récupérer la liste des applications.

12.Besoins spécifiques de l’Agence de l’Eau

12.1. Onglets applicatifs (jQuery)

12.1.1. Fonctionnement ‘léger’

Les onglets ‘applicatifs’ pourront être gérés de façon simple à l’aide de différents div déclarés dans la JSP.

<div class="onglets" style="height: 120px;" id="ongletsCriteresLotsRapports"><ul>

<li><a href="#onglet1">Onglet 1</a></li><li><a href="#onglet2">Onglet 2</a></li>

Page 36:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

</ul><div id="onglet1">

[…]</div><div id="onglet2">

[…]</div>

</div>Ce type de solution pourra être utilisée par exemple dans le cas de présentation de critères sous la forme d’onglets

12.1.2. Fonctionnement ‘complexe’

Pour les onglets plus évolués – faisant appel à une page dédiée, la balise ‘<aermc:onglets>’ définie plus haut (cf. utilisation §6.2) devra être utilisée (par exemple dans une fiche).

Le principe de fonctionnement d’une fiche avec onglets est le suivant : Un seul bouton ‘Enregistrer’ pour toute la fiche Validation du format des données saisies   lors  du changement  d’onglet   (implicite  grâce  à 

l’utilisation de la balise ‘<aermc:onglets>’) Un objet ‘formulaire’ pour la fiche possédant en attribut chacun des objets associés à chacun 

des onglets. Cet objet sera stocké dans le contexte Spring à chaque changement d’onglet afin de ne pas perdre les informations correctement saisies.

La validation de la cohérence des données ne sera effectuée uniquement lors de l’action ‘Enregistrer’

12.2. Onglets utilisateur (navigateur)

Afin de conserver l’intégrité des données au moment où l’utilisateur ouvre un nouvel onglet (ou une nouvelle fenêtre) de son navigateur, il est impératif que le ‘scope’ du Controller Spring n’ait pas la valeur ‘session’ !

12.3. Mode de navigation

Suivant les besoins des utilisateurs, plusieurs modes de navigation ont été envisagés : Chaque lien s’ouvre dans un nouvel onglet (navigateur) [solution retenue pour l’application 

GDA] Chaque lien s’ouvre dans un unique onglet [solution retenue pour l’application QEE]

12.3.1. Description

12.3.1.1. Mode multi-ongletsLe mode multi-onglets se définit de la manière suivante :

Tous les items du menu s’ouvrent dans un nouvel onglet

Page 37:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

Tous les liens référencés dans une liste de résultats s’ouvrent dans un nouvel onglet

Fil d’Ariane :

Avec ce mode de navigation, un fil d’Ariane n’a pas de sens, il a donc été supprimé.

Bouton « Retour » :

La navigation à l’aide du bouton « Retour », situé en bas de page, se traduit par la fermeture de l’onglet courant (après validation de l’utilisateur si des modifications sont en cours) dans la plupart des cas ou par un équivalent du « Précédent » du navigateur s’il n’y a pas eu d’ouverture d’onglet préalable.

NB :   ce   mode   de   navigation   se   rapproche   de   ce   qui   était   fait   dans   les   anciennes   applications développées en PowerBuilder.

12.3.1.2. Mode mono-ongletLe   mode   mono-onglet   se   définit   par   une   navigation   au   sein   d’un   seul   et   unique   onglet   (rien n’empêche l’utilisateur de faire un clic droit > « Ouvrir dans un nouvel onglet » mais ce n’est pas le mode de navigation recommandé dans ce cas).

Fil d’Ariane :

Avec ce mode de navigation, la présence d’un fil d’Ariane est nécessaire (son fonctionnement sera défini dans le  § 11.3.2).

Bouton « Retour » :

La navigation à l’aide du bouton « Retour », situé en bas de page, se traduit par un retour vers la page précédente (rechargement de la page s’il s’agit d’un écran « fiche », relance de la recherche s’il s’agit d’un écran « recherche »).Si des modifications sont en cours dans l’écran courant,  alors une confirmation sera demandée à l’utilisateur s’il souhaite conserver ses modifications ou non avant le retour à la page précédente.

NB :   ce   mode   de   navigation   se   rapproche   de   ce   qui   était   fait   dans   les   anciennes   applications développées avec les versions précédentes de la BAO (2.7 et antérieures).

12.3.2. Fonctionnement du fil d’Ariane

Le fil d’Ariane (ou BreadCrumb) est généré à partir de la navigation de l’utilisateur : à chaque appel de lien depuis le navigateur, celui-ci sera intercepté afin d’établir une Map d’actions pour chacun des utilisateurs de l’application concernée.

Page 38:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

12.3.2.1. HistoriqueNavigationInterceptor

HistoriqueNavigationInterceptor est un Interceptor Spring qui permet : Avant l’exécution côté serveur :

De gérer la pile d’actions de chaque utilisateur (ajout, ràz) : celle-ci exclut les ressources statiques   de   l’application   (images,   css,   js,   resources,   …)   mais   également   toutes   les requêtes POST ou Ajax pour conserver uniquement les liens qui seront nécessaires à la navigation.

Après l’exécution côté serveur :D’enrichir le Model Spring afin de mettre à jour le fil d’Ariane et d’ajouter d’éventuelles informations   supplémentaires  dans   la  page   (cas  d’un   retour   vers  une   recherche  avec rechargement des résultats correspondant aux critères).

12.3.2.2. FwkBreadCrumbManager

FwkBreadCrumbManager  est   un   singleton   permettant   de   gérer   les   piles   d’actions   de   chaque utilisateur – identifiées par leur numéro de session HTTP.Celui-ci permet de :

Ajouter un élément à la pile d’action de la session courante Supprimer le dernier élément de la pile Supprimer les éléments postérieurs à l’élément courant  Réinitialiser la pile d’une session utilisateur (notamment lors du retour sur la page d’Accueil) Retrouver le Controller responsable d’une recherche à partir de son URL (et ré-exécuter la 

recherche)

12.3.2.3. FwkBreadCrumb

FwkBreadCrumb est l’objet JAVA qui permet d’afficher le contenu du fil d’Ariane à l’écran. Il possède 2 attributs : un libellé et une url (lien vers la page correspondante).

12.3.2.4. FwkViewPreparer (Tiles)

FwkViewPreparer  permet d’enrichir   le   contexte  Tiles  de   la  page courante  après   l’exécution côté serveur mais avant la restitution côté client.Dans ce cas, il sert à restituer le même titre au niveau de la page HTML que dans le fil d’Ariane (titre récupéré   dans   le   fichier   properties   de   messages,   à   partir   d’un   code   suivant   le   format « ecran.<codeEcran> »)

Par défaut, cette classe est déjà paramétrée au niveau du layout de base dans le fichier  tiles.xml généré par l’archetype :

<!-- Définition des Layouts --><definition name="base.definition" template="/WEB-INF/jsp/base/layout.jsp"

Page 39:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

preparer="fr.eau.rmc.framework.web.servlet.tiles.FwkViewPreparer"><put-attribute name="title" value="" /><put-attribute name="titrePage" value="" /><put-attribute name="ecranID" value="" type="string" cascade="true" /><put-attribute name="header" value="/WEB-INF/jsp/base/header.jsp" /><put-attribute name="nav" value="/WEB-INF/jsp/base/nav.jsp" /><put-attribute name="breadcrumbs" value="/WEB-INF/jsp/base/breadcrumbs.jsp"

/><put-attribute name="criteres" value="" /><put-attribute name="resultats" value="" /><put-attribute name="fiche" value="" /><put-attribute name="section" value="" /><put-attribute name="footer" value="/WEB-INF/jsp/base/footerSimple.jsp" />

<!-- currentMenu correspond à l'ID de la balise <li> du menu que l'on souhaite mettre en évidence -->

<put-attribute name="currentMenu" value="" type="string" cascade="true" /> </definition>

12.3.2.5. HistoriqueController

HistoriqueController  est un Controller Spring permettant de gérer  le clic sur  le bouton « Retour » (correspondant à l’url /appli/retour).Celui-ci récupère l’URL appelant le retour et dépile cet élément de la liste des actions de l’utilisateur puis retourne  l’élément précédent de  la pile  (dont  l’URL sera appelée côté client).  Si  nécessaire, recharge la liste de résultats avec les critères conservés en mémoire.

12.3.3. Conservation des critères

En fonction du mode de navigation choisi, il peut être possible de conserver les critères saisis lors d’une recherche.Ceux-ci  seront  sauvegardés par session HTTP   auprès  du contexte  de Spring qui   les   restituera  à chaque constitution de la page.

12.3.4. Paramétrage

Ces différentes solutions sont paramétrables au niveau du fichier properties de l’application : displayBreadCrumb (booléen avec comme valeur par défaut, false) : affichage du fil d’Ariane ouvertureNouvelOnglet   (booléen avec comme valeur par défaut,  false) :  navigation multi-

onglets conserveCriteres (booléen avec comme valeur par défaut, false) : conservation des critères

12.4. Export générique des tableaux de résultats

Page 40:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

12.4.1. Problématiques

Générer un document XLSX (pas de limite sur le nombre de lignes) Possibilité d’afficher des données différentes du tableau de résultat (cas de colonnes où le 

contenu est tronqué, pour gagner de la place)

12.4.2. Principe de fonctionnement

Les données récupérées sont stockées dans le contexte de Spring après l’exécution de la recherche.Une vue (au sens Spring) spécifique est définie afin de récupérer ces données et les générer sous la forme d’un fichier XLSX à l’aide de l’API POI.

12.4.3. Prérequis Java

Les données sauvegardées dans le contexte Spring doivent se présente sous la forme d’une List d’objets IExportable (NB : l’interface IModelListView étend cette classe).

L’implémentation de cet objet  IExportable  nécessite la déclaration des colonnes à afficher dans   le   fichier   Excel   ainsi   que   le   mode   de   récupération   des   données   via   une Map<NomColonne,   MethodeAAppeler>).   Cette   Map   permettra   de   récupérer   par introspection les données correspondantes pour chacun des objets appartenant à la liste.

Exemple d’implémentation des méthodes de IExportable :

@Overridepublic String[] getHeadersForExport() {

return new String[] { "numjob", "codbatch"};}

@Overridepublic Map<String, String> getMapContentMethodsForExport() {

return new HashMap<String, String>() {{

put("numjob", "getNumJob");put("codbatch", "getCodBatch");

}};

}

12.4.4. Application dans la JSP

Dans le DataTable, une classe CSS est nécessaire pour permettre le bon fonctionnement de l’export. Elle   doit   se   présenter   sous   la   forme   « exportClassNomClasseObjetReference »   où NomClasseObjetReference  représente   l’objet  mappé  de   référence  du  Controller.  Cette   référence servira d’identifiant pour la liste de données à exporter ainsi que pour le nom du fichier Excel qui sera généré.

Page 41:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

Exemple de déclaration de tableau exportable :

<table id="executionsBatchs" class="dataTableStandard avecTri avecFiltre exportClassCsBatchLance"> […]</table>

12.5. Ecrans de suivi des Batchs

Des écrans de suivi des batchs (criteresExecutions.jsp, listExecutions.jsp, detailExecution.jsp) seront présents   dans   chaque   application   utilisant   la   BAO   v3.1.   Ces   écrans   s’appuient   sur   les   objets (CsBatchLance,  CsBatchAppli,  CsBatchErreur)  et  le Controller  (SuiviBatchController)  qui sont situés dans le framework-core.

Il est tout à fait possible de déroger à ces écrans et définir un nouveau Controller de suivi. 

12.6. CSV

Dans   le   cadre  de   l’application  QEE,  des  besoins  d’imports  et  d’exports  de  fichiers  CSV  ont  été identifiés. La librairie ‘OpenCsv’ a été choisie afin de répondre à ces besoins. Bien que la librairie soit tout à fait intégrable en l’état, un certain nombre de classes utilitaires ont été développées dans le Framework afin de faciliter les développements.

12.6.1. Imports

L’import des données à l’aide de fichier CSV s’appuie sur un objet de référence dont les propriétés à renseigner seront annotées (@CsvBindByName).

Ces   annotations   permettent   de   faire   le   lien   entre   l’entête   de   colonne   (quel   que   soit   son positionnement ; le nom de la colonne doit impérativement être en MAJUSCULES) et les données à récupérer et ainsi constituer un jeu de données (parser.getList()).Si   une   erreur   se   produit   lors   de   la   récupération   d’une   donnée   (format   incorrect,   donnée   non renseignée alors qu’elle est obligatoire) alors cette ligne n’est pas prise en compte mais l’erreur est tout de même stockée dans le parser (parser.getCapturedExceptions()).

Les   données   ne   doivent   pas   nécessairement   être   des   String,   la   librairie   ‘OpenCsv’   permet   des conversions automatiques vers des objets de types Integer, Long, Boolean, Short, Date, …

public void readCsv() throws IOException {FwkCsvParser<YourOrderBean> parser = new FwkCsvParser<YourOrderBean>();parser.parse(TestJCSV.csvFile, YourOrderBean.class);List<YourOrderBean> list = parser.getList();List<CsvException> capturedExceptions = parser.getCapturedExceptions();

}

Page 42:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

public class YourOrderBean implements FwkCsvExport {@CsvBindByName(column = "SIRET")private Long siret;

@CsvBindByName(column = "CODE PLVT EDI")private String codePlvtEdi;

@CsvBindByName(column = "CODE PRIX")private String codePrix;

@CsvBindByName(column = "LIEU PREL")private String lieuPlvt;

@CsvBindByName(column = "DATE PRÉLÈVEMENT")@CsvDate("dd/MM/yy")private Date datePlvt;

@CsvBindByName(column = "HEURE PRÉLÈVEMENT")@CsvDate("HH:mm:ss")private Date heurePlvt;

}

12.6.2. Exports

Pour générer un fichier CSV, le framework s’appuie sur un ensemble d’objets héritant de la classe FwkCsvExport. Celle-ci possède deux méthodes :

getHeaders() : retourne un tableau (statique) de String représentant l’entête du fichier CSV  getData() :   retourne une représentation sous forme de tableau de String de  la donnée à 

exporter

NB : afin de conserver une cohérence des données, l’ordre des colonnes devra être identique dans les 2 méthodes !

Par défaut, le fichier généré sera un fichier temporaire mais il est tout à fait possible de paramétrer un fichier précis comme résultat de l’export.

public void writeCsv() throws IOException {List<FwkCsvExport> dataIn = getData();FwkCsvWriteFile fwkCsvWriter = new FwkCsvWriteFile();File writeCsv = fwkCsvWriter.writeCsv(dataIn);

}

public interface FwkCsvExport {String[] getHeaders();String[] getData();

}

Page 43:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

12.7. Auto authentification avec Kerberos

ATTENTION : l’authentification Kerberos n’est pas possible si le serveur et le client correspondent à la même machine.

12.7.1. Paramétrage du serveur

Afin que le serveur applicatif puisse dialoguer avec le serveur nécessaire, il est nécessaire de créer un fichier ‘keytab’ à paramétrer dans le fichier de configuration de Spring Security.

Il est également possible de désactiver l’auto authentification Kerberos simplement à  l’aide de la propriété ‘dev’ incluse dans le fichier de propriétés de l’application (aura pour valeur ‘false’ si l’on souhaite conserver l’authentification Kerberos et ‘true’ pour se connecter à l’aide d’un écran de login – sans mot de passe).

12.7.2. Paramétrage client

Afin de tester l’authentification Kerberos à partir de la session Windows courante, il faut effectuer les actions suivantes :

Dans Intenet Explorer : s’assurer que la case ‘Options Internet > Sécurité > Personnaliser le niveau > Authentification utilisateur > Connexion automatique …’ soit cochée ainsi  que celle correspondant à ‘Options Internet > Avancé > Sécurité > Activer l’authentification intégrée’

Dans Firefox : aller à la page ‘about:config’ et ajouter le serveur applicatif à la liste des uri identifiées à la ligne ‘network.negotiate-auth.trusted-uris’

12.7.3. Création du fichier ‘keytab’

Pré-requis sous Windows : il est nécessaire d’avoir un fichier ‘krb5.ini’ dans ‘C:\Windows’ si l’on veut créer un fichier ‘keytab’ (le fichier ‘krb5.ini’ est en réalité identique au fichier ‘krb5.conf’ utilisé dans la BAO v2).

Ce fichier doit contenir les utilisateurs (et mots de passe) nécessaires à la communication avec le serveur   Kerberos.   En   dév,   l’utilisateur   est   ‘APP-KRB-DEV’,   en   intégration   ‘APP-KRB-INT’   et   en production ‘APP-KRB-PRO’. Chaque utilisateur devra être ajouté à l’aide de la commande suivante, à exécuter à partir du répertoire ‘bin’ de la ‘JRE’ utilisée.  

C:\java\jdk1.6.0_27\bin> ktab -a <user> "<password>"

Par  défaut,   le  fichier   sera  créé  dans   le  dossier   ‘C:\Users\<userWindows>’  et   il   faudra ensuite   le transférer dans le répertoire ‘/appli/propappli’.

Page 44:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

12.8. Utilisation courante

12.8.1. DataTables

Dans la version initiale,  les DataTables s’affichaient suite à l’appel d’une méthode JavaScript bien précise.Ceci   a  été   simplifié  et   l’appel   aux  DataTables  –   ainsi  que  ses  options  –   se   fait   à  partir  de   ses différentes classes CSS et à son identifiant (ces classes ne doivent pas être déclarées dans un des fichiers CSS) qu’il faudra positionner sur la balise ‘table’ de référence.

Pour le moment, les classes suivantes ont été définies (dans le fichier ‘datatable.js’) : dataTableStandard    : déclaration d’un DataTable de base exportClass<ObjetRef>    : déclaration d’un bouton ‘Excel’ permettant l’export du résultat de la 

recherche (Attention : l’export s’effectue sur les données fournies par Hibernate et non pas sur ce qui est affiché, c’est-à-dire que les tris ne sont pas pris en compte par exemple)  cf. § 7.6

Le   bouton     sera   rajouté   dans   l’entête   du   tableau,   permettant   l’export   des données.

avecTri    : ce DataTable sera triableL’icône   sera rajouté dans l’entête de chacune des colonnes du tableau.

avecFiltre    : ce DataTable sera filtrable tableauRecherchePopup    : ce DataTable sera positionné dans une popup, en conséquence les 

valeurs possibles du nombre de lignes par page seront réduites treetable    : ce DataTable sera un TreeTable masqueColmn : ce DataTable permettra de rendre invisible certaine colonne du tableau

Une nouvelle ligne apparaitra alors dans l’entête du tableau permettant de rendre visible ou invisible chacune des colonnes du tableau 

12.8.2. Auto complétion

Dans la solution initiale,   la méthode utilisée pour récupérer  les  informations nécessaires à  l’auto complétion était basée sur un document XML. Cependant  il  serait plus simple de mettre en place un document JSON à retransmettre à la page HTML (la signature de la méthode Javascript n’évoluant pas par rapport à la version initiale présentée plus haut). 

En effet, du point de vue du Controller  il suffit d’effectuer la recherche en fonction des paramètres puis de sérialiser le résultat en JSON.NB : ne pas oublier l’annotation @ResponseBody !!!

Page 45:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

Par exemple : 

@RequestMapping(value = "/ac/numInt", method = RequestMethod.GET)@ResponseBodypublic Serializable getListAutocompleteNumint(@RequestParam(defaultValue = "") String saisie, @RequestParam(defaultValue = "false") Boolean sansRestrictionSaisie) {

List<Interlocuteur> commenceParNumInt = this.interlocuteurService.commenceParNumInt(saisie);

List<LovValues> listNumInt = new ArrayList<LovValues>();for (final Interlocuteur interlocuteur : commenceParNumInt) {

listNumInt.add(new LovValues() {@Overridepublic String getLibelle() {

return interlocuteur.getNomint1() + " - " + interlocuteur.getNomint2();

}

@Overridepublic String getCode() {

return interlocuteur.getNumint();}

});}return listNumInt.toArray(new LovValues[listNumInt.size()]);

}

12.8.3. Popups

Afin de réduire le nombre de fenêtres ouvertes, les popups seront gérées en tant que ‘dialog’ jQuery. L’ouverture de la ‘dialog’ se base sur le clic d’un bouton (ex : « Recherche interlocuteur ») ou un lien faisant référence à une nouvelle URL (« href ») – identifiée par la classe CSS ‘openRecherche’.

<form:input id="nomPrenomInterlocuteur" cssClass="valeurChamp" path="nomPrenomInterlocuteur"/><a class="valeurChamp openRecherche jq-personbutton-notext" href="${editUserUrl}">...</a>

Cependant,   ici,   cette URL ne  sera pas  appelée dans  une nouvelle   fenêtre  mais   redirigée  vers   le contenu de la div ‘dialog’.

// Renvoie le contenu de la page dans la Dialog$(document).on("click", ".openRecherche", function(event) { event.preventDefault();

// get dialog content $.get(this.href).done(function(data, textStatus, jqXHR) { $("#dialogRecherche").empty().append(data); $("#dialogRecherche").dialog("open"); });});

Page 46:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

Dans notre  exemple  de recherche,   le  document renvoyé par   la   recherche devra également être redirigé   vers   la   dialog.   Pour   cela,   il   suffit   d’ajouter   la   classe   ‘submitRecherche’   au   bouton correspondant et ainsi le clic sur celui-ci permettra de poster le formulaire de recherche avant le retour du contenu dans la ‘dialog’.

// Renvoie le contenu du post de la recherche dans la Dialog$(document).on("click", ".submitRecherche", function(event) { event.preventDefault(); var form = $(this).closest("form"); // get dialog content $.post($(form).attr('action'), $(form).serialize()).done(function(data, textStatus, jqXHR) { $("#dialogRecherche").empty().append(data); $("#dialogRecherche").dialog("open"); });});

En conclusion, pour l’appel à une méthode de type ‘GET’, il faudra utiliser un bouton possédant la classe ‘openRecherche’ ;  pour une méthode ‘POST’, il faudra utiliser un bouton ‘submitRecherche’.

NB : la ‘dialog’ s’ouvrira en fenêtre modale, ce qui veut qu’aucune action ne sera possible dans la page appelante.

12.8.4. Dialog jQuery

NB : les méthodes JavaScript permettant de gérer l’ouverture et la fermeture des ‘dialog’ se trouvent dans le fichier ‘framework.js’

12.8.4.1. Fenêtre d’attente

Lors de l’appel d’une méthode pouvant prendre un certain temps, il est nécessaire de bloquer toute action utilisateur supplémentaire. Pour cela, une fenêtre modale sera affichée tant que le serveur n’aura pas rendu la main.

Par exemple, lors du clic sur un bouton ‘Rechercher’, affichage de la fenêtre suivante :

L’appel  sera  fait  en   jQuery  de manière  implicite  à  partir  du moment  où  le  bouton  ‘Rechercher’ possède la classe CSS ‘jq-searchbutton’.

12.8.4.2. Fenêtre d’alerte

Page 47:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

Pour   ouvrir   une   alerte   dans   une   fenêtre   modale,   il   faut   utiliser   la   méthode « openAlertDialog(message)  » où le message attendu devra être passé en paramètre (récupéré à partir du fichier properties).

/** * Ouvre la dialog d'affichage des alertes * * @param message */function openAlertDialog(message) {

$('#alertDialog').find('.messageDialog').html(message);$('#alertDialog').dialog('open');

}

12.8.4.3. Fenêtre de confirmation

Pour   ouvrir   une   fenêtre   modale   de   confirmation,   il   faut   utiliser   la   méthode « openConfirmDialog(msg, textOui, textNon, actionOui, actionNon) ». Celle-ci attend en paramètre : 

msg    :   le   message   principal   à   afficher   dans   la   fenêtre   (libellé   récupéré   depuis   le   fichier properties)

textOui    : le texte correspondant au libellé du bouton « Oui » textNon    : le texte correspondant au libellé du bouton « Non » actionOui    : l’action JavaScript à appeler lors du clic sur le bouton « Oui » (redirection, appel 

XHR, etc.) – la fermeture de la dialog étant déjà gérée, il n’est pas utile de la redéfinir ici actionNon    : l’action JavaScript à appeler lors du clic sur le bouton « Non » (redirection, appel 

XHR, etc.) – la fermeture de la dialog étant déjà gérée, il n’est pas utile de la redéfinir ici

/** * Ouverture d'une dialog de confirmation * * @param msg : message à afficher dans la dialog * @param textOui : libelle du bouton 'Oui' * @param textNon : libelle du bouton 'Non' * @param actionOui : action JavaScript à évaluer lors du clic sur le bouton 'Oui' * @param actionNon : action JavaScript à évaluer lors du clic sur le bouton 'Non' */function openConfirmDialog(msg, textOui, textNon, actionOui, actionNon) {

// initialisation des paramètres si non définisif (!msg) {

msg = "Etes vous sur de vouloir effectuer cette action ?";}if (!textOui) {

textOui = 'Oui';}if (!textNon) {

textNon = 'Non';}if (!actionOui) {

actionOui = function() {

Page 48:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

$(this).dialog("close");return true ;

};} else {

var origActionOui = actionOui;actionOui = function() {

eval(origActionOui);$(this).dialog("close");return true ;

};}if (!actionNon) {

actionNon = function() {$(this).dialog("close");return false ;

};} else {

var origActionNon = actionNon;actionNon = function() {

eval(origActionNon);$(this).dialog("close");return false;

};}

$('#confirmDialog').find('.messageDialog').html(msg);var tabBtns = $('#confirmDialog').dialog( "option", "buttons" );tabBtns['Oui'] = {

text: textOui,click: eval(actionOui),

};tabBtns['Non'] = {

text: textNon,click: eval(actionNon),

};$('#confirmDialog').dialog( "option", "buttons", tabBtns);$('#confirmDialog').dialog('open');

}

12.8.5. Actions XHR

Une action XHR permet d’interroger le serveur en Ajax et ainsi rafraichir certaines parties de l’écran sans rafraichir l’entièreté de la page.

Afin d’être le plus générique possible, une méthode JavaScript a été introduite. Celle-ci prend en paramètre :

L’élément source de l’événement L’élément cible qui sera rafraichi (champ texte, LOV, page complète, div, …) L’action serveur qu’il faudra appeler (postage du formulaire auquel le champ est rattaché) La fonction JavaScript qui sera appelée au retour de l’appel serveur

Page 49:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

function xhr(element, targetElement, actionServer, jsFunctionToCall) {// affichage de la fenêtre d'attente$('#waitingAreaForAjax').dialog('open');if (actionServer) {

// récupération du formulaire à postervar form = $(element).closest("form");// postage du formulaire auprès du serveur$.post(actionServer, form.serialize()).done(function(data) {

// appel de la méthode javascript en fonction des données renvoyées par le serveur (valeur d'un champ, page complète, ...)

if (jsFunctionToCall) {eval(jsFunctionToCall)(targetElement, data);

}// fermeture de la fenêtre d'attente$('#waitingAreaForAjax').dialog('close');

}).fail(function (readyState) {alert('Erreur lors de l\'execution du POST !!!\nErreur '

+readyState.status+ ' : '+readyState.statusText);$('#waitingAreaForAjax').dialog('close');

});} else {

console.log('Pas d\'action définie pour ce xhr !!!');$('#waitingAreaForAjax').dialog('close');

}}

12.8.6. Menus

Les menus sont gérés dans la JSP ‘nav.jsp’ sous forme de balises ‘<ul><li>’. Ces balises seront mises en ordre à l’aide du plugin jMenu.

$("#jNavFwk").jMenu({openClick : false,ulWidth :'150px',TimeBeforeOpening : 100,TimeBeforeClosing : 11,animatedText : false,paddingLeft: 1,effects : {

effectSpeedOpen : 150,effectSpeedClose : 150,effectTypeOpen : 'slide',effectTypeClose : 'slide',effectOpen : 'swing',effectClose : 'swing'

}});

// Mise en evidence du menu sélectionné$("#jNavFwk").find("#"+currentMenu).addClass('ui-widget-menu-accueil');

Par exemple: 

Page 50:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

Ces menus pourront évidemment être personnalisés à l’aide des feuilles CSS correspondantes.

12.8.7. Multi-select

Par exemple : 

Pour   gérer   ce  genre  d’exemple,   il   suffit  de  définir  un  élément  HTML  <select>  sur   lequel  on  va appliquer le plugin multi-select.

// JSP

<form:form method="POST" action="${actionOnglet2}" commandName="formOnglet2" enctype="multipart/form-data">[…]

<form:select path="multipleSelect" multiple="multiple" items="${listDelegationsMultiple }" itemLabel="libelle" itemValue="code"/>[…]</form:form>// JavaScript

<script>$(document).ready(function() {

$('#multipleSelect').multiSelect();apply_widgets();

});</script>

Page 51:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

12.8.8. Upload

Page 52:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

12.8.9. Textarea élastique

Il  est possible de rendre les zones de saisie de type textarea auto-extensible en fonction de leur contenu. Une limitation de la hauteur peut être définie, au-delà de laquelle la zone de texte ne s’agrandira plus.Pour ce faire, la BAO intègre le composant JQUERY « elastic »

13.Gestion des éditions avec BDOC

Le besoin d’éditions BDOC s’exprime de 2 façons : Besoin immédiat (asynchrone) avec un affichage de l’édition demandée dans le navigateur Besoin   différé   (asynchrone) :   l’édition   sera   générée   par   un   traitement   régulier   avec 

possibilité d’envoyer l’impression sur une imprimante choisie

13.1. JAXB

La librairie JAXB permet de générer un ensemble de classes correspondant au besoin exprimé dans le fichier XSD. Les classes ainsi générées devront être utilisées afin de générer le document XML valide et l’envoyer par la suite vers BDOC.

Pour générer les classes :

Résultat : 

Page 53:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

13.2. Traitement asynchrone

Le   traitement   asynchrone   d’édition   se   traduit   par   le   postage   d’un   batch   dans   la   table « CS_BATCH_LANCE » sur une action utilisateur. Ce batch sera ensuite traité par le système de batchs dédié suivant un ordonnancement défini.Suivant le principe de traitement des batchs de façon asynchrone, il   faut définir un lanceur pour chacun des « CODBATCH » à traiter. Dans le cas de la génération de document BDOC, il faut utiliser un lanceur de type BdocXmlGenerator qui permettra de générer un fichier XML dans un répertoire local avant de le transférer vers le serveur BDOC via FTP pour qu’il soit traité par le service BDOC Online.

13.2.1. Exemple

public class GdaBdocXmlGenerator extends BdocXmlGenerator {@Autowiredprivate BdocService bdocService;

/** * Retourne un objet (JAXB) sérialisable à partir des données du batch * * @return */

@Overrideprotected Object getData() {

Page 54:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

return this.bdocService.populateData(this.getBatchEnCours());}

}

13.2.2. Paramétrage du batch

# paramètres nécessaires à la génération du fichier XMLbatchTableCSTaskKey.RBE.replocal=/appli/pdfappli/chemin/vers/repertoire/local/creationXmlbatchTableCSTaskKey.RBE.racineFichierXML=BDOCbatchTableCSTaskKey.RBE.nomFichierXSD=file:/appli/pdfappli/chemin/vers/repertoire/XSD/monValidateur.xsdbatchTableCSTaskKey.RBE.namespace=http://aramis.primevere.agence.eau.fr/model/in/v1u0

# paramètres nécessaires au transfert du fichier XML vers BDOC via FTPbatchTableCSTaskKey.RBE.nameRemoteConnexion=SRVFTP_BDOCbatchTableCSTaskKey.RBE.repLog=/appli/tomc-gda/log/tomcat/batchTableCSTaskKey.RBE.b=truebatchTableCSTaskKey.RBE.repremote=/appli/data/chemin/vers/repertoire/distant

NB      :    les   informations   relatives   à   la   connexion   FTP   doivent   être   définies   dans   le   fichier « remote.properties ».

13.3. Traitement synchrone

Le   traitement   synchrone   se   traduit   par   la   création   du   document   dans   un   répertoire   prédéfini (répertoire temporaire pour le moment)  et  éventuellement son ouverture dans  le navigateur.  La génération du document se fera à l’aide des API fournies par BDOC, soit par Web Service soit en se connectant directement au serveur BDOC.Quelque soit le type de génération choisie, il existe 2 possibilité de transmettre les données : 

A l’aide d’un fichier XML généré (et valide) A l’aide d’objets JAVA résultant du fichier XSD correspondant (générés par JAXB) 

L’ensemble des méthodes nécessaires à un traitement synchrone sont regroupées dans une même classe : BdocApiUtils qui sera injectée par Spring. Dans les différents cas, plusieurs paramètres sont nécessaires :

Le nom du domaine BDOC à laquelle appartient l’édition désirée Le nom du template BDOC associée à l’édition Les données à fournir : soit sous forme de fichier XML, soit sous forme d’objet JAVA (générés 

par JAXB) 

13.3.1. Génération directe

/** * Génération directe du PDF à partir d'un document XML * * @param domaine

Page 55:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

* @param bdocTemplate * @param xmlSourceFilename * @return */public String generatePdfDirectWithXml(final String domaine, final String bdocTemplate, final String xmlSourceFilename) {

LOG.info("Appel direct à BDOC --- template " + bdocTemplate + " du domaine " + domaine + " avec le fichier " + xmlSourceFilename);

return composeDocument(connect(), domaine, bdocTemplate, xmlSourceFilename,null);

}

/** * Génération directe du PDF à partir d'un objet JAXB * * @param domaine * @param bdocTemplate * @param objectJaxb * @return */public String generatePdfDirectWithObject(final String domaine, final String bdocTemplate, final Object objectJaxb) {

LOG.info("Appel direct à BDOC --- template " + bdocTemplate + " du domaine " + domaine + " avec un objet de type " + objectJaxb.getClass().getSimpleName());

return composeDocument(connect(), domaine, bdocTemplate, null, objectJaxb);}

/** * Connects to Bdoc-Web */private JBApplication connect() {

try {JBConnection connection = new JBConnection(this.getHost(),

this.getPort());return new JBApplication(connection);

} catch (BDocException e) {e.printStackTrace();return null;

}}

/** * Composes document * * @param application * @param domaine * @param templateName * @param xmlSourceFile * @param objectJaxb * @return */private String composeDocument(final JBApplication application, final String domaine,

final String templateName, final String xmlSourceFile, final Object objectJaxb) { […]}

Page 56:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

13.3.2. Génération via Web Service

/** * Génération via le WS Bdoc du PDF à partir d'un document XML * * @param templateName * @param domaine * @param xmlFileName * @return */public String generatePdfWsWithXml(final String templateName, final String domaine, final String xmlFileName) {

LOG.info("Appel au WS de BDOC --- template " + templateName + " du domaine " + domaine + " avec le fichier " + xmlFileName);

BdocWsClient client = getBdocWsClient(domaine, templateName);String documentPath =

client.getDocumentFromFile(SpringSecurityUtils.getSecuritySessionId(), new File(xmlFileName));

LOG.info("Le fichier " + documentPath + " a été généré avec succès !");return documentPath;

}

/** * Génération via le WS Bdoc du PDF à partir d'un objet JAXB * * @param templateName * @param domaine * @param objectJaxb * @return */public String generatePdfWsWithObject(final String templateName, final String domaine, final Object objectJaxb) {

LOG.info("Appel au WS de BDOC --- template " + templateName + " du domaine " + domaine + " avec un objet de type " + objectJaxb.getClass().getSimpleName());

try {BdocWsClient client = getBdocWsClient(domaine, templateName);ByteArrayOutputStream out = new ByteArrayOutputStream();SerializatorObject.serialize(objectJaxb, out);String documentPath =

client.getDocumentFromOut(SpringSecurityUtils.getSecuritySessionId(), out);LOG.info("Le fichier " + documentPath + " a été généré avec

succès !");return documentPath;

} catch (JAXBException e) {LOG.error("Erreur lors de la sérialisation de l'objet de type " +

objectJaxb.getClass().getSimpleName(), e);return null;

}}

private BdocWsClient getBdocWsClient(final String domaine, final String templateName) {

return new BdocWsClient(this.getUrlWebService(), domaine, templateName);}

Page 57:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

14.Système de batchs

14.1. Fonctionnement

Le système de batchs de la BAO v3.1 s’appuie sur ce qui avait été déjà fait dans la version 2.7 de la BAO.  Celui-ci   s’articule  autour  de Spring  avec des  déclenchements  périodiques  gérés  par  Quartz (QuartzJobBean).

Chaque  Job Quartz  défini   sera associé  à  une tâche   (IFwkScheduledTask)  qui  elle-même se verra rattacher 2 éléments : un déclencheur de tâche (IFwkDeclencheur) et un exécuteur de tâche.

Les déclenchements périodiques de Job sont généralement élaborés à partir d’expression Cron. 

Page 58:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

A ce moment-là,   le déclencheur associé vérifie si   le traitement doit s’effectuer ou non (méthode isEnclenche()).   Si   oui,   alors   l’exécuteur   entre   en   action   (méthode  executeTraiement())   avec éventuellement des traitements pré et/ou post traitement.

14.1.1. Utilisation d’un lanceur

Dans le cas de batchs postés dans la table ‘CS_BATCH_LANCE’, seul une tâche est définie (avec un déclencheur,   l’enregistrement  est  présent  en base  de données,  et  un exécuteur,  exécution d’un traitement batch) alors que les traitements diffèreront si des batchs différents ont été postés au même moment.Pour  différencier   les  différents   traitements,   la notion de  ‘Lanceur’  a  été  introduite au niveau de l’exécuteur de batch (FwkBatchExecutor). Ce lanceur correspond au traitement spécifique d’un batch (clé <CODAPP, COBATCH> dans la table ‘CS_BATCH_LANCE’) et il faudra donc instancier un ‘lanceur’ par batch (dans le sens ‘CS_BATCH_LANCE’).

14.2. Configuration XML

Déclaration du Job :<bean name="job.purgeBatchLance" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">

<property name="jobClass" value="fr.eau.rmc.framework.tacheAsynchrone.FwkBatchJob" />

<property name="jobDataAsMap"><map>

<entry key="taskFactory" value ref="scheduledTaskFactory.purgeBatchLance" />

</map></property>

</bean>

Déclaration de la Task :<bean id="scheduledTaskFactory.purgeBatchLance" class="fr.eau.rmc.framework.tacheAsynchrone.IScheduledTaskFactory">

<lookup-method name="getNewInstance" bean="task.purgeBatchLance"/>

</bean>

<bean id="task.purgeBatchLance" class="fr.eau.rmc.gda.tachesAsynchrones.GdaScheduledTask" parent="baoTask" scope="prototype">

<property name="declencheur" ref="batchDeclencheur.true" /><property name="executor" ref="batchExecutorPurgeBatchLance" /><property name="taskKey" value="dureeRetention" />

</bean>

Page 59:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

Déclaration du Declencheur :<bean id="batchDeclencheur.true" class="fr.eau.rmc.gda.tachesAsynchrones.GdaDeclencheurTrue" scope="prototype" />

Déclaration de l’Executor<bean id="batchExecutorPurgeAppli" class="fr.eau.rmc.gda.tachesAsynchrones.executors.GdaExecutorPurgeRepAppli" scope="prototype" />

 Cas du FwkBatchExecutor :<!-- Executor pour les batch lancés --><bean id="batchExecutor" class="fr.eau.rmc.framework.tacheAsynchrone.FwkBatchExecutor" scope="prototype">

<!-- Déclaration d'une map de Lanceurs associés au BatchExecutor

Liste des batchs déclenchés par la table CS_BATCH_LANCE--><property name="lanceurs">

<map><entry key="BASLOT" value-ref="lanceur.batchProckStock"></entry><entry key="GARATT" value-ref="lanceur.batchProckStock"></entry><entry key="SLDJUR" value-ref="lanceur.batchProckStock"></entry><entry key="RAZTAB" value-ref="lanceur.batchProckStock"></entry><entry key="SLDCVT" value-ref="lanceur.batchProckStock"></entry><entry key="SLDOPR" value-ref="lanceur.batchProckStock"></entry><entry key="GLINFO" value-

ref="lanceur.batchInterface.GLINFO"></entry><entry key="LOIPA" value-ref="lanceur.batchInterface.LOIPA"></entry><entry key="RELANC" value-

ref="lanceur.batchInterface.RELANCE"></entry><entry key="TOIPA" value-ref="lanceur.batchInterface.TOIPA"></entry><entry key="OPELOT" value-

ref="lanceur.batchInterface.OPELOT"></entry><entry key="NODASI" value-

ref="lanceur.batchInterface.NODASI"></entry><entry key="NODASF" value-

ref="lanceur.batchInterface.NODASF"></entry> <entry key="INFOMB" value-ref="lanceur.batchInterface.INFOMB"></entry>

<entry key="CPP" value-ref="lanceur.batchInterface.CPP"></entry><entry key="EDPLIQ" value-

ref="lanceur.batchInterface.EDPLIQ"></entry><entry key="EMIMDT" value-

ref="lanceur.batchInterface.EMIMDT"></entry><entry key="EMIOR" value-ref="lanceur.batchInterface.EMIOR"></entry><entry key="RETSIR" value-

ref="lanceur.batchInterface.RETSIR"></entry><entry key="RTSIOR" value-

ref="lanceur.batchInterface.RTSIOR"></entry><entry key="RCPFIC" value-

ref="lanceur.recupFichiersConvention"></entry></map>

</property>

</bean>

Page 60:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

Déclaration du déclenchement (avec une expression Cron) :<bean id="cronTrigger.purgeBatchLance" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">

<property name="jobDetail" ref="job.purgeBatchLance" /><property name="cronExpression" value="<cronExpression>" />

</bean>

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"><property name="triggers">

<list><!-- liste des Triggers à exécuter --><ref bean="cronTrigger.purgeRepAppli" />

[…] </list>

</property></bean>

Dans un souci de lisibilité, l’ensemble des batchs définis (ainsi que tous leurs composants) seront déclarés dans un fichier XML distinct du fichier de configuration Spring de l’application.Il suffira de l’importer au besoin dans celui-ci :

<!-- ######################### Batchs ######################### --><import resource="appBatchJobs.xml" />

14.3. Exemples de cas fréquents :

Certains traitements batchs peuvent être génériques dans leur fonctionnement et ainsi être partagés par plusieurs applications.Cela est notamment le cas pour les traitements de fichiers XML (import et export). C’est pour cette raison   que   des   briques   ont   été   mises   en   place   au   niveau   de   la   BAO   afin   de   minimiser   les développements spécifiques par application.

14.3.1. Export (génération) de fichier XML

La génération d’un fichier XML est surtout utilisée dans deux cas pour les besoins de l’Agence de l’Eau : 

à destination de BDOC à des fins d’édition  à destination d’une autre application en tant qu’interface

Le lanceur (cf § 13.1.1) dédié (FwkXmlGeneratorLanceur) permet de : récupérer   les   données   (méthode  getData())   en   fonction   du   batch   courant   (et   de   ses 

paramètres) générer un fichier XML à partir de celle-ci (méthode constructExportXmlFile()) valider le fichier généré avec la grammaire XSD associée (méthode getValidyOfXmlToXsd()) 

Page 61:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

éventuellement le transférer en FTP sur un autre serveur (méthode putFileOnServer()) tout en gérant l’état d’avancement du traitement du batch

14.3.2. Import de fichier XML

L’import   de   fichier   XML   est   principalement   utilisé   dans   le   cadre   d’interface   avec   d’autres applications.

Le lanceur dédié (FwkXmlImportLanceur) permet de : Lister les fichiers à importer à partir d’un répertoire donné (local ou distant via FTP) et d’un 

nom de fichier (ou un pattern) (méthode getListFichierATraiter()) Valider   chaque   fichier   à   l’aide   de   la   grammaire   XSD   associée   (méthode 

getValidyOfXmlToXsd())  Convertit   le  fichier  en  données   JAVA  (avec   JAXB)  pour   la   suite  du   traitement   (méthode 

getDataFromFile()) Traitement des données récupérées (méthode traitementSucess()) Déplacement   du   fichier   dans   le   répertoire   correspondant   à   la   réussite   du   traitement 

(méthode deplacementFichier()) Tout en gérant l’état d’avancement du traitement du batch

15.Bibliothèque logicielle JAVA

Le tableau ci-dessous énumère les principales librairies JAVA utilisées par la BAO v3.1.

Librairie Version FonctionnalitéSpring 4.1.4 ConteneurSpring MVC 4.1.4 PrésentationSpring Security 3.2.5 SécuritéSpring Security Kerberos 1.0.0.RC

1Intégration Spring Security avec Kerberos

Apache Tiles 3.0.1 PrésentationJstl 1.2 Présentation

Spring Data JPA 1.4.1 Accès base de donnéesHibernate 4.2.5 ORMCommons DBCP 1.4 Pool connexions JDBCLdap SDK 4.1 Accès LDAP

Commons Lang 3.4 UtilitairesJoda Time 2.7 Utilitaires de manipulation de dateApache Http Client 4.5.2 Utilitaire appels HTTP

Page 62:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

Librairie Version FonctionnalitéCommons Net 3.3 Client HTTPQuartz 2.2.1 Planification de tâchesJava Mail 1.4 Envoi de mail

Jaxb 2.2.11 Manipulation de XMLJackson 2.1.4 Manipulation de JSON, CSV, …POI 3.10.1 Manipulation de XLSX, DOCX, …jWordConvert V2015R Conversion Word vers PDFOpen CSV 3.8 Manipulation de CSVAxis 2 1.6.2 Support WebService

SLF4J 1.7.5 Gestion des logs

Jasper Reports 5.6.1 Editions JASPERBdoc interactive 5.3 Editions BDOC (partie interactive)

Librairie intégrée, mais non utilisée.Bdoc Web 5.3 Editions BDOC (partie Bdoc Web)

Librairie utilisée pour les éditions directes depuis une application métier)

16.Bibliothèque JavaScript

16.1. Plugins jQuery utilisés

Plusieurs plugins jQuery sont utilisés dans la BAO v3.1 : Jquery UI pour le rendu global à l’écran (version 1.11.2) Jquery Datatables pour l’affichage des tableaux de résultats (version 1.9.4) Jquery multi-select pour « transvaser » les éléments d’une liste à une autre (version 0.9.11) Jquery chosen pour l’affichage des listes de valeurs (version 0.9.11) Jmenu pour l’affichage du menu (version 2.0) Jquery UI timepicker pour la saisie d’une date horodatée (version 1.2) Jquery mask pour créer des masques de saisie sur les champs (version 1.7.7) Jquery   numberMask  pour   créer   des   masques   de   saisie   sur   des   champs   numériques 

(version ???) Jquery treetable pour afficher des tableaux de résultats sous forme d’arbre (version 3.0.1) Jquery uploadfile pour permettre l’upload de fichier vers le serveur (version 3.1.10) TableTools (version 2.0.0) Jquery Elastic pour rendre les zones de saisies de type textearea auto extensible en fonction 

du contenu (version 1.6.3)

Page 63:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

En   dehors   des   plugins   UI,  DataTables,   multi-select   (qui  ont   dû  être   modifiés   pour  des   besoins spécifiques),   tous   les  fichiers   JS   correspondant  ont  été   rassemblés  dans  un  seul :  aermc-jquery-plugins.min.js.

NB : afin de simplifier l’inclusion des différents JS dans les pages JSP, toutes les déclarations ont été regroupés dans un même JSP : importJs.jsp.

16.2. Descriptif du contenu des fichiers JS spécifiques

16.2.1. ajaxForm.js

Ce script contient l’ensemble des méthodes nécessaires à  la validation de formulaire de manière asynchrone. Celles-ci seront principalement utilisées dans les écrans de type ‘fiche’ avec des onglets ; en effet, le contenu de chaque onglet doit être validé avant l’affichage du prochain, afin de ne pas avoir des données incohérentes inter-onglets.

Les méthodes définies dans ce script sont les suivantes :

ajaxSubmitForm :  valide le formulaire passé en paramètre à  l’aide d’une requête AJAX et renvoie les erreurs fournies par le serveur 

clearErrors : efface les erreurs (liées aux champs) dues à une validation précédente displayErrorsInOnglet : affiche l’erreur renvoyée par le serveur à côté du champ concerné getAjaxGetContents : fait appel à une URL en AJAX et renvoie ce contenu au sein d’une balise 

<div> getDivOngletFormLi : renvoie le <div> (jquery tab) correspondant à la balise <li> donnée getDivOnglets : renvoie le <div> correspondant à l’ID passé en paramètre ou par défaut celui 

possédant la classe CSS ‘onglets’ getDivOngletsAffiche : renvoie le <div> correspondant à l’onglet affiché (courant) getDoc : renvoie le document (au sens CSS) contenu dans la frame passé en paramètre isDivDisplay : vérifie si le <div> passé en paramètre est bien celui qui est affiché (le courant) valideOngletsEtSubmitForm : valide l’ensemble des formulaires de chacun des onglets  avant 

de valider le formulaire global (ne comprenant pas les onglets !)

16.2.2. cookies.js

Ce script permet de gérer les différents cookies de l’application en JavaScript.

Les méthodes définies dans ce script sont les suivantes :

ExistSession : vérifie l’existence du cookie correspondant à la session en fonction de son ID passé en paramètre

GetCookie : renvoie la valeur du cookie correspondant au nom passé en paramètre

Page 64:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

GetCurrentSession :   renvoie   la  valeur  correspondant  à   l’ID  de  la  session stockée dans  un cookie

RemoveSession : supprime l’ID de session passé en paramètre de la liste des cookies SetCookie : permet de renseigner un cookie suivant son nom et sa valeur SetSessionId : permet de renseigner dans un cookie l’ID de la session passé en paramètre

16.2.3. datatable.js

Ce script fournit le nécessaire pour afficher un tableau de résultats sous la forme d’un DataTable.

Dans la première partie du fichier sont déclarés un ensemble de types qui peuvent être utilisés dans le DataTable. En effet, le tri s’effectue sur le contenu de chaque cellule qui est considéré en tant que ‘String’ et qui induit des problèmes de tri dans les cas où on affiche des nombres ou des dates.

Par la suite, on retrouve la définition des paramètres de base servant à la création d’un DataTable.

Les méthodes définies dans ce script sont les suivantes :

applyParamsDataTable :   créer   un   DataTable   correspondant   à   l’identifiant   passé   en paramètre  à  partir  des  paramètres  de  configuration  donnés   (c’est  également  dans  cette méthode que l’on définit l’URL à appeler pour les exports Excel génériques)

calculTotalPourFooter : effectue la somme des données de la colonne donnée pour la page courante (NB : ne pas oublier de définir le <tfoot> dans le <table>)

customParamsById : ajuste les paramètres du DataTable suivant son identifiant (définition des types pour les colonnes qui ne correspondent pas à des ‘String’, …)

16.2.4. dialogRecherche.js

Ce script contient l’ensemble des méthodes nécessaire au bon fonctionnement d’une fenêtre modale (jQuery dialog) de recherche.

Les méthodes définies dans ce script sont les suivantes :

closeRechercheDialog : ferme la dialog de recherche openRechercheDialogEvent : définit l’événement qui déclenchera l’ouverture de la dialog et 

son alimentation par une URL de type « GET » postRechercheDialogEvent : définit l’événement qui déclenchera l’alimentation de la dialog 

par une URL de type « POST »

16.2.5. framework.js

Ce script contient diverses méthodes qui peuvent être utiles dans les JSP.

Page 65:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

Les méthodes définies dans ce script sont les suivantes :

afficheErreur : affiche les erreurs globales (en haut au milieu de la page, en rouge) afficheIdEcran :  affiche l’ID de  l’écran sous la  forme d’une  infobulle  à côté du bouton de 

déconnexion afficheInfos : affiche les messages d’information (en haut au milieu de la page, en noir) applyDisabledInput :   applique   des   modifications   sur   les   champs   en   lecture   seule 

(désactivation du clic sur les ‘radio’ ou les ‘checkbox’ par exemple) clone : clone l’objet JavaScript passé en paramètre closeWaitingDialog : ferme la fenêtre modale de mise en attente consoleLog : log les informations dans la console du navigateur (si celle-ci est active) dateValide : vérifie si la date passée en paramètre existe bien doOpen : ouvre l’URL passée en paramètre, dans un nouvel onglet s’il le faut doRetour : exécute une action lors du clic sur le bouton ‘Retour’ : si on se trouve dans un 

nouvel onglet (bouton «  » du navigateur grisé), on ferme l’onglet sinon on retourne à la page précédente (équivalent au bouton «  » du navigateur)

fireChangedEvent :   propage   un   événement   indiquant   au   formulaire   qu’un   champ   a   été modifié (utile pour indiquer à l’utilisateur qu’il a modifié un champ sans avoir enregistré)

formatDDmmYYYY : formate une date en JavaScript formatDoubleWith0JS : formate un nombre en tant que ‘String’ en précisant le nombre de 

décimales attendues getDocHeight : récupère la hauteur du ‘document’ de la page isDivInFicheForm : vérifie que le <div> recherché est bien positionné dans un écran de type 

fiche isMsie : vérifie que le navigateur utilisé est Internet Explorer  mainmenu : applique l’animation du jMenu openAlertDialog : ouvre une fenêtre modale pour afficher le message passé en paramètre openCancelDialog : ouvre une fenêtre modale de confirmation faisant suite à un clic sur le 

bouton retour après avoir modifié la valeur d’au moins un champ openCloseTabDialog : ouvre une fenêtre modale de confirmation de fermeture d’onglet openConfirmDialog : ouvre une fenêtre modale de confirmation (avec le message passé en 

paramètre ainsi que les actions à effectuer lors du clic sur les boutons ‘Oui’ ou ‘Non’) openWaitingDialog : ouvre la fenêtre modale de mise en attente parseISO : crée une date au format ISO à partir d’une ‘String’ removeFromArray : supprime la valeur recherchée dans le tableau donné resizeDiv :   redimensionne   les   différents   composants   de   la   page   (suite   à   un 

redimensionnement de fenêtre par exemple) et ajoute des ‘scroll’ si nécessaire resizeDivSection : redimensionne le composant ‘section’ resizeDivsFiche : redimensionne les composants sur un écran de type ‘fiche’ resizeDivsList : redimensionne les composants sur un écran de type ‘liste’ resizePanelButtonDialog : réajuste les classes CSS dans le cadre de l’affichage d’une fenêtre 

modale avec un unique bouton (centrage de celui-ci)

16.2.6. jq-styled-input.js

Page 66:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

Ce script permet de mettre en forme les boutons avec des icônes.Attention, les styles ci-dessous ne définissent pas le libellé du bouton, ceux-ci sont définis en tant que message Spring.

Exemples de styles CSS à utiliser :

jq-savebutton : 

jq-cancelbutton : 

jq-icon-seek-prev : 

jq-icon-seek-next : 

jq-searchbutton : 

jq-searchbutton-notext : 

jq-icon-triangle-s : 

16.2.7. jqueryWidgetFramework.js

Ce script contient l’ensemble des méthodes nécessaires à la mise en forme des composants jQuery.

Les méthodes définies dans ce script sont les suivantes :

apply_multiselect : permet la mise en forme des éléments de type ‘multiselect’ (basculement des éléments d’une liste à une autre)

apply_togglebutton : permet la mise en forme des éléments pliables/dépliables (par exemple les critères de recherche)

apply_upload : permet la mise en forme d’un composant de type ‘upload’ apply_widgets: permet la mise en forme de divers composants jQuery (‘datepicker’, ‘tabs’, …) 

et l’initialisation des comportements par défaut de ceux-ci applyChosen : permet la mise en forme des composants ‘lovChosen’ (effectif sur les listes de 

valeurs, multiple ou non) applyMask : positionne des masques sur les champs de saisie (date, nombre) autocompletion : positionne un comportement d’auto-complétion sur un champ donné  fireChangeCritereDate :   propage   le   changement   de   date   dans   un   écran   de   critères 

(nécessaire pour la recopie de valeurs dans des champs de saisie de type ‘du’ / ‘au’)

16.2.8. xhrUtils.js

Ce script contient l’ensemble des méthodes nécessaires à l’exécution de requêtes en XHR.

Page 67:   · Web viewAERMC Manuel du développeur. Framework de l’agence de l’eau. Auteur : Rémi BERTHET Vérificateur : Jérôme PAIRE. Mise à jour. Version Date Nature de la modification

Date : 11/09/2023

Manuel du développeur

Les méthodes définies dans ce script sont les suivantes :

afficheCacheChampEtLabel : permet d’afficher ou de masquer un champ ainsi que le libellé qui lui est associé

changeSelectValues :   modifie   les   valeurs   d’une   liste   de   valeurs   à   partir   des   éléments retournés par le serveur

changeValAndColor : modifie la valeur du champ ainsi que la couleur de fond (méthode créée pour générer des exemples, peut être modifiée pour répondre au besoin)

getElement : renvoie l’objet jQuery correspondant au composant cible recherché gotoPage : redirige la page vers l’URL renvoyée par le serveur modifValeurInput :  modifie   la   valeur  d’un   champ à  partir  de   la  donnée   renvoyée  par   le 

serveur refreshElement : rafraichit l’élément avec le contenu HTML renvoyé par le serveur refreshElementAndHidden : rafraichit l’élément cible avec la donnée renvoyée par le serveur 

ainsi que le champ ‘hidden’ associé refreshElementOnglet :   rafraichit   l’onglet   courant   avec   le   contenu   HTML   renvoyé   par   le 

serveur refreshElements : à l’aide d’une Map postée par le serveur, rafraichit les champs indiqués 

avec les données correspondantes refreshDataTable : remplace un DataTable existant par un autre fourni par le serveur (à l’aide 

d’une vue Spring par exemple) xhr :  exécute   l’action XHR (POST)  puis   la  commande JavaScript  donnée avec  les  données 

renvoyées par le serveur en paramètres de celle-ci