Tutorial Dozer : intégration et premiers mappings

Nous allons voir ensemble comment intégrer le framework Dozer au sein d'une application utilisant Maven et Spring et réaliser nos premiers mappings de classe. C'est parti !

Versions utilisées

Voici les versions utilisées dans ce tutorial
Dozer 5.3.1
Spring 3.0.5.RELEASE
Maven 3.0.2

Intégration du framework

Tout d'abord, il vous faut ajouter dans le pom.xml de votre application une dépendance à
Dozer :

<dependency>
	<groupId>net.sf.dozer</groupId>
	<artifactId>dozer</artifactId>
	<version>5.3.1</version>
</dependency>

Dans votre fichier de contexte Spring, déclarer un bean de type org.dozer.DozerBeanMapper :

<bean id="org.dozer.mapper" class="org.dozer.DozerBeanMapper"/>

C'est tout ! Nous voilà déjà prêts à créer nos premier mappings.

Modèle métier

Nous disposons des classes suivantes, créées spécialement pour l'occasion (je vous épargne le détail des accesseurs, interfaces, factories et autres entités périphériques) :

PersonneImpl.java

PersonneImpl.java

PersonneType.java

PersonneType.java

ClientImpl.java

ClientImpl.java

ClientType.java

ClientType.java

Voyons à présent comment mapper deux instances de la classe Personne.

Mapper deux instances d'une même classe

Test Simple Copy

NB : la méthode getBean(String) permet de récupérer une instance chargée dans le contexte Spring.

Notons ici que les lignes 82 à 86 auraient pu être remplacées par les lignes suivantes :

Test Simple Copy Alternative

Mapper des instances de classes différentes

Essayons maintenant de mapper une instance de la classe Personne et une instance de la classe Client :

Test Simple Conversion

Dans ce cas, Dozer va essayer de mapper les attributs homonymes des instances, qui dans notre exemple sont les attributs prenom, age et type. Par ailleurs, Dozer sait convertir automatiquement certains types (dont la liste exhaustive peut être trouvée ici) ainsi que les valeurs d'enum homonymes.
Sans aucun paramétrage supplémentaire, Dozer va donc pouvoir mapper :
1) Les attributs prenom, car homonymes et de même type (String => String)
2) Les attributs age, car homonymes et dont la conversion est supportée (int => String)
3) Les attributs type, car homonymes et dont la conversion est supportée (PersonneType.INDEFINI => ClientType.INDEFINI)
On peut donc voir comme il est simple de mapper des attributs homonymes avec Dozer.
Voyons à présent comment mapper les attributs non-homonymes.

Les fichiers de mapping

Il est possible de spécifier à Dozer des fichiers de mapping lui indiquant comment mapper les attributs non-homonymes. Le fichier suivant permettra de mapper les attributs nom de la classe Personne et patronyme de la classe Client :

dozer-mapping.xml

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://dozer.sourceforge.net
          http://dozer.sourceforge.net/schema/beanmapping.xsd">

   <mapping>
      <class-a>com.netapsys.modele.Personne</class-a>
      <class-b>com.netapsys.modele.Client</class-b>
      <field>
          <a>nom</a>
	  <b>patronyme</b>
      </field>
   </mapping>
</mappings>

Il suffit alors de l'ajouter à la déclaration du Mapper :

<bean id="org.dozer.mapper" class="org.dozer.DozerBeanMapper">
      <property name="mappingFiles">
         <list>
	    <value>mapping/dozer-mapping.xml</value>
	 </list>
      </property>
</bean>

Notons que les mappings ainsi définis sont par défaut bi-directionnels ie qu'ils permettent aussi bien de mapper une instance de class-a vers class-b que l'inverse.
A ce stade, nous avons réussi à exécuter le code de la partie "Mapper deux instances d'une même classe". Mais comment aurions-nous fait si nous avions eu à mapper un PersonneType autre qu'INDEFINI ?

Les convertisseurs

Lorsque Dozer ne peut pas automatiquement convertir un attribut, il faut créer un convertisseur qui sera appelé au RunTime.
Les convertisseurs doivent implémenter l'interface org.dozer.CustomConverter et la méthode Object convert(Object existingDestinationFieldValue, Object sourceFieldValue, Class<?> destinationClass, Class<?> sourceClass).
Voyons les différentes étapes à effectuer à l'aide du convertisseur qui permettra à Dozer de mapper les valeurs des enum PersonneType et ClientType :

1) Création du convertisseur :

TypeConvertisseur.java

Convertisseur

avec sa déclaration Spring :

<bean id="netapsys.modele.convertisseur.type" 
		class="com.netapsys.modele.convertisseur.TypeConvertisseur">
   <property name="mapConversion">
      <bean class="org.apache.commons.collections.bidimap.DualHashBidiMap">
         <constructor-arg>
	    <map>
		<entry key="HOMME" value="INTERLOCUTEUR"/>
	 	<entry key="FEMME" value="INTERLOCUTRICE"/>
	 	<entry key="INDEFINI" value="INDEFINI"/>
	    </map>
	 </constructor-arg>
      </bean>
   </property>
</bean>

2) Affectation du convertisseur aux attributs type dans le fichier dozer-mapping.xml :

<mapping>
      <class-a>com.netapsys.modele.Personne</class-a>
      <class-b>com.netapsys.modele.Client</class-b>
      <field>
          <a>nom</a>
	  <b>patronyme</b>
      </field>
      <field custom-converter-id="typeCustomConverter">
	   <a>type</a>
	   <b>type</b>
      </field>
   </mapping>

3) Ajout du convertisseur à la déclaration du Mapper :

<bean id="org.dozer.mapper" class="org.dozer.DozerBeanMapper">
   <property name="mappingFiles">
      <list>
         <value>mapping/dozer-mapping.xml</value>
       </list>
   </property>
   <property name="customConvertersWithId"> 
      <map> 
         <entry key="typeCustomConverter" 
                             value-ref="netapsys.modele.convertisseur.type"/>
      </map>
   </property>
</bean>

Et voilà nous avons un mapping complet de notre modèle de données !

3 commentaires

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.