2017-03-23 1 views
0

Supposons que nous avons 2 DTO:réflexion pour Orika customMap de différentes FIELDNAMES

public class ClassA { 
    private String elementAClassA; 
    private String elementBClassA; 
    private Integer elementCClassA; 
} 

public class ClassB { 
    private String elementAClassB; 
    private String elementBClassB; 
    private Integer elementCClassB; 
} 

Comment cartographier ces DTO en utilisant le code générique (ou réflexion/personnalisé), à savoir sans utiliser simplement:

MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build(); 
     mapperFactory.classMap(ClassA.class, ClassB.class) 
       .field("elementAClassA", "elementAClassB") 
       .field("elementBClassA", "elementBClassB") 
       .field("elementCClassA", "elementCClassB").register(); 

Répondre

0
I found the solution and hope will help others. 
Steps are as below: 

1. Overide newClassMapBuilder of Factory class. 
2. fetch fields of both classes using Field reflection. 
3. map new field to build, if elementName matched. 
4. Then, create factory and pass this overiden class. 

-- Point 1-3 are in below code: 
import java.lang.reflect.Field; 
import ma.glasnost.orika.DefaultFieldMapper; 
import ma.glasnost.orika.MapperFactory; 
import ma.glasnost.orika.metadata.ClassMapBuilder; 
import ma.glasnost.orika.metadata.ClassMapBuilder.Factory; 
import ma.glasnost.orika.metadata.Type; 
import ma.glasnost.orika.property.PropertyResolverStrategy; 

public class PlainElementToStdElementMapper extends Factory { 

    @Override 
    protected <A, B> ClassMapBuilder<A, B> newClassMapBuilder(
      Type<A> aType, Type<B> bType, 
      MapperFactory mapperFactory, 
      PropertyResolverStrategy propertyResolver, 
      DefaultFieldMapper[] defaults) { 
     final ClassMapBuilder<A, B> newBuilder = super.newClassMapBuilder(
       aType, bType, mapperFactory, propertyResolver, defaults); 

     Field[] sourceFields = aType.getRawType().getDeclaredFields(); 
     Field[] destFields = bType.getRawType().getDeclaredFields(); 

     for (int elementA = 0; elementA < sourceFields.length; elementA++) { 
      for (int elementB = 0; elementB < destFields.length; elementB++) { 
       if (sourceFields[elementA].getName().equalsIgnoreCase("Std"+destFields[elementB].getName())) { 
        newBuilder.field(sourceFields[elementA].getName(), destFields[elementB].getName()); 
       } 
      } 
     } 
     return newBuilder; 
    } 
} 


4. Create factory: 

     final MapperFactory factory = new DefaultMapperFactory.Builder(). 
        classMapBuilderFactory(new PlainElementToStdElementMapper()).build(); 

     factory.classMap(ClassA.class, ClassB.class).byDefault().register(); 
       MapperFacade mapperFacade = factory.getMapperFacade(); 
0

Si vous demandez comment mapper des attributs communs d'une représentation (ClassA) à l'autre (ClassB), vous utiliserez le byDefault() comme indiqué dans le documentation.

mapperFactory.classMap(BasicPerson.class, BasicPersonDto.class) 
    .field("name", "fullName") 
    .field("age", "currentAge") 
    .byDefault() 
    .register(); 

Sur la base de votre exemple, il est pas clair si les types sont différents ou les noms sont différents entre vos deux représentations (il est pas lisible comme Java). La réflexion ne serait utile que si les champs étaient nommés identiques, auquel cas vous devriez simplement utiliser byDefault(), ou peut-être si c'était le même type et que vous n'aviez qu'un seul de chaque type dans chaque représentation, vous pourriez faire un mapping autowired ; mais vous feriez toutes sortes d'hypothèses que vous ne voudriez pas faire.

+0

parDefault() peut être utilisé uniquement lorsque fieldName est identique pour les deux classes. quel que soit le type. BTW, j'ai trouvé la solution. Il est possible en surmontant newClassMapBuilder méthode d'usine .. Je posterai la solution bientôt ci-dessous. :) – Shyam

+0

Je me rends compte que, mais (avant votre mise à jour), il n'était pas possible de dire si vous donniez des noms ou des types. – Daedalus