This can be done in several ways. Below you see 2 options. They do the same thing only one uses qualifiedByName
while the other uses expression
. Depending on your need one might fit better then the other.
Using a custom method found by mapstruct
qualifiedByName
required because otherwise mapstruct does not know which method to use.
@Mapping(source = ".", target = "startTime", qualifiedByName = "startTime")
@Mapping(source = ".", target = "endTime", qualifiedByName = "endTime")
AvailabilityRuleDTO toAvailabilityRuleDTO(AvailabilityRule availabilityRule, @Context Schedule schedule);
@Named("startTime")
protected ZonedDateTime startTime(AvailabilityRule availabilityRule, @Context Schedule schedule) {
return convertTime(availabilityRule.startEpoch, schedule.timezoneId);
}
@Named("endTime")
protected ZonedDateTime endTime(AvailabilityRule availabilityRule, @Context Schedule schedule) {
return convertTime(availabilityRule.endEpoch, schedule.timezoneId);
}
private ZonedDateTime convertTime(long epoch, String timezoneId) {
Instant instant = Instant.ofEpochMilli(epoch);
ZonedDateTime time = LocalDateTime.from(instant).atZone(timezoneId);
return time;
}
Using a custom method configured by an expression
@Named
used here to prevent mapstruct from accidentally using this method for other mapping actions. Without it it will most likely still work.
@Mapping(target = "startTime", expression = "java(convertTime(availabilityRule.startEpoch, schedule.timezoneId))" )
@Mapping(target = "endTime", expression = "java(convertTime(availabilityRule.endEpoch, schedule.timezoneId))" )
AvailabilityRuleDTO toAvailabilityRuleDTO(AvailabilityRule
availabilityRule, Schedule schedule);
@Named("time")
protected ZonedDateTime convertTime(long epoch, String timezoneId) {
Instant instant = Instant.ofEpochMilli(epoch);
ZonedDateTime time = LocalDateTime.from(instant).atZone(timezoneId);
return time;
}
Complete mapper including schedule
@Mapper
public abstract class ScheduleMapper {
@Mapping(target = "timezone", source = "timezoneId")
@Mapping(target = "rules", expression = "java(toAvailabilityRuleDTOs(schedule.getRules(), schedule))")
abstract ScheduleDTO toScheduleDTO(Schedule schedule);
@Named("rules")
abstract List<AvailabilityRuleDTO> toAvailabilityRuleDTOs(List<AvailabilityRule> rules, @Context Schedule schedule);
@Mapping(target = "startTime", expression = "java(convertTime(availabilityRule.startEpoch, schedule.timezoneId))")
@Mapping(target = "endTime", expression = "java(convertTime(availabilityRule.endEpoch, schedule.timezoneId))")
abstract AvailabilityRuleDTO toAvailabilityRuleDTO(AvailabilityRule availabilityRule, @Context Schedule schedule);
@Named("time")
protected ZonedDateTime convertTime(long epoch, ZoneId timezoneId) {
Instant instant = Instant.ofEpochMilli(epoch);
ZonedDateTime time = LocalDateTime.from(instant).atZone(timezoneId);
return time;
}
String map(ZoneId zoneId) {
return zoneId == null ? null : zoneId.getId();
}
}