I am trying to specify the mapping of the member list using a Converter but I would like to also use a PropertyMap to map the remaining fields (in the example below it is just the field 'a' that should be mapped to 'aa').
Is it possible to specify all the mappings in the Converter or just in a PropertyMap? If not, how can I use both in the same model mapper?
Thanks.
P.S. I followed this example http://bit.ly/10dqanw to make my Test class.
package org.me.modelmapper;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.modelmapper.Converter;
import org.modelmapper.ModelMapper;
import org.modelmapper.PropertyMap;
import org.modelmapper.TypeToken;
import org.modelmapper.config.Configuration;
import org.modelmapper.spi.MappingContext;
import static org.testng.Assert.*;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class ModelMapperTest {
private ModelMapper modelMapper;
public static class Foo {
private String a;
private List<Bar> b;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public List<Bar> getB() {
return b;
}
public void setB(List<Bar> b) {
this.b = b;
}
}
public static class Bar {
private String c;
public Bar(String c) {
this.c = c;
}
public String getC() {
return c;
}
public void setC(String c) {
this.c = c;
}
}
public static class FooDTO {
private String aa;
private List<BarDTO> bb;
public String getAa() {
return aa;
}
public void setAa(String aa) {
this.aa = aa;
}
public List<BarDTO> getBb() {
return bb;
}
public void setBb(List<BarDTO> bb) {
this.bb = bb;
}
}
public static class BarDTO {
private String cc;
public String getCc() {
return cc;
}
public void setCc(String cc) {
this.cc = cc;
}
}
public ModelMapperTest() {
}
@Test
public void shouldMapFooToFooDTO() {
Foo foo = new Foo();
foo.setA("aaa");
List<Bar> b = Arrays.asList(new Bar("ccc"), new Bar("ddd"));
foo.setB(b);
modelMapper.createTypeMap(Foo.class, FooDTO.class).setConverter(
new Converter<Foo, FooDTO>() {
@Override
public FooDTO convert(MappingContext<Foo, FooDTO> context) {
List<BarDTO> barDTOs = new ArrayList<BarDTO>();
List<Bar> bars = context.getSource().getB();
TypeToken<List<BarDTO>> token = new TypeToken<List<BarDTO>>() {
};
MappingContext<List<Bar>, List<BarDTO>> c = context.create(bars, token.getType());
barDTOs.addAll(context.getMappingEngine().map(c));
FooDTO fooDTO = new FooDTO();
fooDTO.setBb(barDTOs);
return fooDTO;
}
;
}
);
PropertyMap<Foo, FooDTO> map = new PropertyMap<Foo, FooDTO>() {
@Override
protected void configure() {
map(source.getA(), destination.getAa());
}
};
modelMapper.addMappings(map);
FooDTO fooDTO = modelMapper.map(foo, FooDTO.class);
assertEquals(fooDTO.getAa(), foo.getA());
int i = 0;
for(; i < fooDTO.getBb().size(); i++) {
assertEquals(fooDTO.getBb().get(i), foo.getB().get(i));
}
}
@BeforeMethod
public void setUpMethod() throws Exception {
modelMapper = new ModelMapper();
modelMapper.getConfiguration()
.setFieldMatchingEnabled(true)
.setFieldAccessLevel(Configuration.AccessLevel.PRIVATE);
}
}
Yes it is possible. A Converter
will always take precedence over any property mappings. You can certainly specify both, but the Converter is what will be used.