Reputation: 7
So this colleague of mine created a simple mapper and I want to add some more features to it. I suspect mapStruct will not be able to automatically generate methods for it, so I believe I will have to write custom mapping logic. I want to map values that are nested inside the input object and saved in a key-value-pair structure to attributes of the output.
Here is an example of the kind of structure at hand. He implemented mapping for members one, two and three, I would like to add mapping for members alpha and beta.
@Mapper()
public interface AMapper {
@Mapping(source = "one", target = "oneX")
@Mapping(source = "two", target = "twoX")
@Mapping(source = "three", target = "threeX")
OutA inAToOutA(InA inA);
}
class InA {
String one;
int two;
long three;
InB b;
}
class InB {
List<InC> listOfC = new ArrayList<>();
public InB() {
listOfC.add(new InC("alpha", "AlphaContent"));
listOfC.add(new InC("beta", "BetaContent"));
}
}
class InC {
String key;
String value;
public InC(String key, String value) {
this.key = key;
this.value = value;
}
}
class OutA {
String oneX;
int twoX;
long threeX;
String alphaX;
String betaX;
}
In my mapStruct rooky mind a solution could look something like this, but I'd rather not have to rewrite all of his stuff, cause it's bigger than this example, that's why I am asking for advice:
@Mapper()
public interface AMapper {
default OutA getA(InA a) {
if (a == null)
return null;
OutA oa = new OutA();
oa.setOneX(a.getOne());
oa.setTwoX(a.getTwo());
oa.setThreeX(a.getThree());
for (InC c : a.getB().getListOfC()) {
switch (c.getKey()) {
case "alpha":
oa.setAlphaX(c.getValue());
break;
case "beta":
oa.setBetaX(c.getValue());
break;
default:
break;
}
}
return oa;
}
}
Upvotes: 0
Views: 2068
Reputation: 2701
You can use mapstruct @AfterMapping
annotation in existing mapper:
@Mapper
public interface AMapper {
@Mapping(source = "one", target = "oneX")
@Mapping(source = "two", target = "twoX")
@Mapping(source = "three", target = "threeX")
@Mapping(target = "alphaX", ignore = true)
@Mapping(target = "betaX", ignore = true)
OutA inAToOutA(InA inA);
@AfterMapping
default void afterMappingInAtoOutA(@MappingTarget OutA outA, InA inA) {
if (inA.getB() == null || inA.getB().getListOfC() == null) { // add some null cheсks
return;
}
for (InC c : inA.getB().getListOfC()) {
switch (c.getKey()) {
case "alpha":
outA.setAlphaX(c.getValue());
break;
case "beta":
outA.setBetaX(c.getValue());
break;
default:
break;
}
}
}
}
Upvotes: 1