MapperHelper.java
package com.mojosoft.demo.mapper;
import com.mojosoft.demo.dto.FootballResultDTO;
import com.mojosoft.demo.dto.FootballResultJsonDTO;
import com.mojosoft.demo.entity.FootballResult;
import com.mojosoft.demo.util.SeasonHelper;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import org.mapstruct.AfterMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
/**
* Mapper interface for converting between FootballResult entity and its DTOs
* (FootballResultDTO and FootballResultJsonDTO). This interface leverages MapStruct for generating
* the mapping implementation at compile time, ensuring efficient and type-safe mappings.
*
* <p>The interface is annotated with @Mapper to be identified by MapStruct for
* implementation generation. The componentModel 'spring' indicates that MapStruct
* should generate a Spring Bean for this mapper, allowing it to be autowired into
* other Spring components.
*
* <p>The default methods isEqual and updateFootballResultEntityFromDto provide custom logic
* for comparing entities and updating them from DTOs.
*/
@SuppressWarnings("checkstyle:LineLength")
@Mapper(componentModel = "spring")
public interface MapperHelper {
/**
* Maps a FootballResult entity to its corresponding FootballResultDTO.
*
* @param footballResult the FootballResult entity to be mapped
* @return the mapped FootballResultDTO
*/
FootballResultDTO footballResultToDto(FootballResult footballResult);
/**
* Maps a FootballResultDTO to its corresponding FootballResult entity.
* The id field is ignored during mapping to prevent overwriting it in the entity.
*
* @param footballResultDTO the FootballResultDTO to be mapped
* @return the mapped FootballResult entity
*/
@SuppressWarnings("checkstyle:AbbreviationAsWordInName")
@Mapping(target = "id", ignore = true)
FootballResult footballResultToEntity(FootballResultDTO footballResultDTO);
/**
* Maps a FootballResultJsonDTO to a FootballResult entity.
* Custom mappings are defined for certain fields, and the season is calculated and set in a separate method.
*
* @param footballResultJsonDto the FootballResultJsonDTO to be mapped
* @return the mapped FootballResult entity
*/
@Mapping(target = "id", ignore = true)
@Mapping(source = "dateUtc", target = "matchDateTime", qualifiedByName = "stringToLocalDateTime")
@Mapping(source = "homeTeam", target = "homeTeam")
@Mapping(source = "awayTeam", target = "awayTeam")
@Mapping(source = "homeTeamScore", target = "homeScore")
@Mapping(source = "awayTeamScore", target = "awayScore")
@Mapping(target = "season", ignore = true)
FootballResult footballMatchJsonToEntity(FootballResultJsonDTO footballResultJsonDto);
/**
* Parses a date-time string into a {@link LocalDateTime} object, supporting two formats:
* - ISO 8601 format: "yyyy-MM-ddTHH:mm:ssZ" (e.g., "2020-09-12T11:30:00Z")
* - Custom format: "yyyy-MM-dd HH:mm:ssZ" (e.g., "2020-09-12 11:30:00Z")
*
* @param dateTimeStr The date-time string to parse.
* @return A {@link LocalDateTime} object representing the parsed date and time.
*/
@org.mapstruct.Named("stringToLocalDateTime")
default LocalDateTime stringToLocalDateTime(String dateTimeStr) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss'Z'");
try {
return LocalDateTime.parse(dateTimeStr, formatter);
} catch (Exception e) {
return LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ISO_DATE_TIME);
}
}
/**
* AfterMapping method to set the season of a FootballResult entity based on its matchDateTime.
* Utilizes SeasonHelper to calculate the season.
*
* @param footballResult the target FootballResult entity whose season is to be set
*/
@AfterMapping
default void setSeason(@MappingTarget FootballResult footballResult) {
if (footballResult.getMatchDateTime() != null) {
footballResult.setSeason(SeasonHelper.calculateSeason(footballResult.getMatchDateTime()));
}
}
/**
* Default method to map a FootballResultJsonDTO to a FootballResultDTO.
* This method serves as a convenient way to transform JSON data to the standard DTO format.
*
* @param footballResultJsonDto the FootballResultJsonDTO to be mapped
* @return the mapped FootballResultDTO
*/
default FootballResultDTO footballMatchJsonToDto(FootballResultJsonDTO footballResultJsonDto) {
return FootballResultDTO.of(
footballResultJsonDto.getLocation(),
footballResultJsonDto.getHomeTeam(),
footballResultJsonDto.getAwayTeam(),
footballResultJsonDto.getHomeTeamScore(),
footballResultJsonDto.getAwayTeamScore(),
stringToLocalDateTime(footballResultJsonDto.getDateUtc()));
}
/**
* Compares a FootballResultDTO with a FootballResult entity to determine if they are equal.
* This comparison considers all the fields in the DTO and entity.
*
* @param dto the FootballResultDTO to compare
* @param entity the FootballResult entity to compare
* @return true if the DTO and entity are equal, false otherwise
*/
default boolean isEqual(FootballResultDTO dto, FootballResult entity) {
if (dto == null && entity == null) {
return true;
}
if (dto == null || entity == null) {
return false;
}
return Objects.equals(dto.season(), entity.getSeason())
&& Objects.equals(dto.location(), entity.getLocation())
&& Objects.equals(dto.homeTeam(), entity.getHomeTeam())
&& Objects.equals(dto.awayTeam(), entity.getAwayTeam())
&& dto.homeScore() == entity.getHomeScore()
&& dto.awayScore() == entity.getAwayScore()
&& Objects.equals(dto.matchDateTime(), entity.getMatchDateTime());
}
/**
* Updates a FootballResult entity with data from a FootballResultDTO.
* This method is used for updating an existing entity with new information from the DTO.
*
* @param dto the FootballResultDTO containing the new data
* @param entity the FootballResult entity to be updated
*/
default void updateFootballResultEntityFromDto(FootballResultDTO dto, FootballResult entity) {
if (dto == null || entity == null) {
return;
}
entity.setSeason(dto.season());
entity.setLocation(dto.location());
entity.setHomeTeam(dto.homeTeam());
entity.setAwayTeam(dto.awayTeam());
entity.setHomeScore(dto.homeScore());
entity.setAwayScore(dto.awayScore());
entity.setMatchDateTime(dto.matchDateTime());
}
}