Skip to content

ModelMapper: apply rule to all fields of type

I have a DTO with a lot of String fields (some are of other types).
When mapping objects into objects of another similar class, I need to apply a transformation to all fields of type String, in this case – trim().

So, I have:

class MyDTO {
  String name;
  String type;
  String company;
  String status;
  String whatever;
  ... (there are about 80 String fields)
  int someNumber;
  double otherNumber;
}
class DestinationDTO { // has just some fields of MyDTO
  String name;
  String type;
  String company;
  String whatever;
  int somenumber;
}

What I’ve tried:

Converter<String, String> myConverter = c -> c.getSource().trim();
ModelMapper mm = new ModelMapper();
...
mm.typeMap(MyDTO.class, DestinationDTO.class)
  .addMappings(c -> c
      .using(myConverter)
      .map(MyDTO::getName, DestinationDTO::getName)
    ) // this applies to just one field, I need all String fields

Is there a way to specify all String fields of a class at once, instead of having to list them?

Tried searching the modelmapper.org docs, but all I see is configuring fields one by one.

Any ideas?

Answer

You can use converters to specify transformations from one type to another. The source and target type can be the same. Use the addConverter<S,D>() method to add a general converter to the ModelMapper itself (rather than individually to a specific field). You can use it like this:

ModelMapper mm = new ModelMapper();
Converter<String, String> myConverter = new AbstractConverter<String, String>() {
    protected String convert(String source) {
        return source == null ? null : source.trim();
    }
};
mm.addConverter(myConverter);
mm.getConfiguration().setFieldMatchingEnabled(true);
MyDTO source = new MyDTO();
source.name = "   abc    t";
source.company = "nd   e  f  n";

DestinationDTO target = mm.map(source, DestinationDTO.class);
System.out.printf("Target.name: '%s'%n", target.name);
System.out.printf("Target.company: '%s'%n", target.company);

The output will be as expected:

Target.name: 'abc'
Target.company: 'd   e  f'