How can I express the following in ModelMapper: To fill a field in the target, I want to use property A of the source if it is non-null, otherwise use the property B.
Example (Code below if you don't like technical descriptions):
Let's say I want from a source class SourceBigThing
to a target class Target
using ModelMapper. The SourceBigThing
has two properties, one called red
and one called green
. These two properties are of different types RedSmallThing
and GreenSmallThing
. Both of these things have a property called name
. A SourceBigThing
can either have a red or a green, but not both (the other is null). I want to map the names of the Small Things to a property of the target-class.
Example-Code:
class SourceBigThing {
private final SourceSmallThingGreen green;
private final SourceSmallThingRed red;
}
class SourceSmallThingGreen {
private final String name;
}
class SourceSmallThingRed {
private final String name;
}
class Target {
private TargetColorThing thing;
}
class TargetColorThing {
// This property should either be "green.name" or "red.name" depending
// on if red or green are !=null
private String name;
}
I tried to play around with the conditionals, but you cannot have two mappings to the same target because ModelMapper throws an exception for duplicate mappings:
when(Conditions.isNotNull()).map(source.getGreen()).setThing(null);
when(Conditions.isNotNull()).map(source.getRed()).setThing(null);
You can find a failing TestNG-Unit-Test at this gist.
This is a bit of an unusual case, so there's no neat way of doing this. But you can always use a Converter - something like:
using(new Converter<SourceBigThing, TargetColorThing>(){
public TargetColorThing convert(MappingContext<SourceBigThing, TargetColorThing> context) {
TargetColorThing target = new TargetColorThing();
if (context.getSource().getGreen() != null)
target.setName(context.getSource().getGreen().getName());
else if (context.getSource().getRed() != null)
target.setName(context.getSource().getRed().getName());
return target;
}}).map(source).setThing(null);