I have two enums with common property – id:
public enum AccessLevel { PUBLIC("public"),PRIVATE("private"); private String id; } public enum Status { SUCCESS("success"),TIMEOUT("timeout"); private String id; }
And I need generic MapStruct mapping of such enums (without need to define mapping of every such enum).
Advertisement
Answer
Yes, it’s possible through @TargetType annotation. You need a common interface for such enums:
public interface IdEnum { String getId(); }
Then you need to be able to create enum of such interface instance by id:
static <T extends Enum<T> & IdEnum> T getById(Class<T> enumClass, String id) { for (T e : enumClass.getEnumConstants()) { if (e.getId().equals(id)) { return e; } } throw new IllegalArgumentException("No enum const " + enumClass.getName() + " for id '" + id + "'"); }
Then the generic Mapper may look like this (@TargetType annotation is the key to success):
public class IdEnumMapper { public <T extends Enum<T> & IdEnum> T mapToEnum(String value, @TargetType Class<T> idEnumClass) { return IdEnum.getById(idEnumClass, value); } public String mapToString(IdEnum idEnum) { return idEnum.getId(); } }
Just use it your mapper that maps a class that contains such enums:
@Mapper(uses = {IdEnumMapper.class}) public interface FilterMapper { ....