1
0
Fork 0
mirror of https://codeberg.org/beerbrawl/beerbrawl.git synced 2024-09-23 05:40:51 +02:00

refactor(#24): backend: remove all that ko standing model jazz again

Signed-off-by: Christoph Heiss <e11907069@student.tuwien.ac.at>
This commit is contained in:
Christoph Heiss 2024-06-12 12:12:59 +02:00
parent dbf767fd1d
commit cc8aaa5460
Signed by: c8h4
GPG key ID: 73D5E7FDEE3DE49A
9 changed files with 36 additions and 94 deletions

View file

@ -63,7 +63,7 @@ public class KoStandingsEndpoint {
LOG.info("GET /api/v1/tournaments/{}/ko-standings", tournamentId);
final var standings = koStandingsService.getKoStandingsTree(tournamentId);
return koStandingsMapper.modelToDto(standings);
return koStandingsMapper.entityToDto(standings);
}
@ResponseStatus(HttpStatus.NO_CONTENT)
@ -85,6 +85,6 @@ public class KoStandingsEndpoint {
standingId,
updateStandingDto
);
return this.koStandingsMapper.modelToDto(updated);
return this.koStandingsMapper.entityToDto(updated);
}
}

View file

@ -8,9 +8,6 @@ public record KoStandingDto(
LocalDateTime startTime,
LocalDateTime endTime,
TeamDto team,
List<KoStandingParticipantDto> participants
) {
public List<KoStandingDto> preceedingStandings() {
return this.participants.stream().map(p -> p.precedingStanding()).toList();
}
}
boolean drinksCollected,
List<KoStandingDto> preceedingStandings
) { }

View file

@ -1,7 +0,0 @@
package at.ac.tuwien.sepr.groupphase.backend.endpoint.dto;
public record KoStandingParticipantDto(
KoStandingDto precedingStanding,
boolean drinksCollected
) {
}

View file

@ -1,16 +1,11 @@
package at.ac.tuwien.sepr.groupphase.backend.endpoint.mapper;
import at.ac.tuwien.sepr.groupphase.backend.entity.KoStanding;
import at.ac.tuwien.sepr.groupphase.backend.service.models.KoStandingModel;
import org.mapstruct.Mapper;
import at.ac.tuwien.sepr.groupphase.backend.endpoint.dto.KoStandingDto;
import org.mapstruct.Mapping;
@Mapper
public interface TournamentKoPhaseMapper {
@Mapping(target = "participants", ignore = true)
KoStandingModel entityToModel(KoStanding entity);
KoStandingDto modelToDto(KoStandingModel model);
}
KoStandingDto entityToDto(KoStanding standing);
}

View file

@ -5,9 +5,9 @@ import java.util.List;
import org.springframework.security.access.AccessDeniedException;
import at.ac.tuwien.sepr.groupphase.backend.endpoint.dto.TournamentUpdateKoStandingDto;
import at.ac.tuwien.sepr.groupphase.backend.entity.KoStanding;
import at.ac.tuwien.sepr.groupphase.backend.exception.NotFoundException;
import at.ac.tuwien.sepr.groupphase.backend.exception.PreconditionFailedException;
import at.ac.tuwien.sepr.groupphase.backend.service.models.KoStandingModel;
public interface TournamentKoPhaseService {
/**
@ -26,7 +26,7 @@ public interface TournamentKoPhaseService {
* @param tournamentId to identify target
* @return a tree with all corresponding standings
*/
KoStandingModel getKoStandingsTree(Long tournamentId) throws NotFoundException, PreconditionFailedException;
KoStanding getKoStandingsTree(Long tournamentId) throws NotFoundException, PreconditionFailedException;
/**
* Updates the team of a standing.
@ -38,7 +38,7 @@ public interface TournamentKoPhaseService {
* @param updateDto details to update the standing with
* @return the updated ko standing
*/
KoStandingModel updateKoStanding(
KoStanding updateKoStanding(
String userName,
Long tournamentId,
Long standingId,

View file

@ -15,8 +15,6 @@ import at.ac.tuwien.sepr.groupphase.backend.repository.TournamentRepository;
import at.ac.tuwien.sepr.groupphase.backend.service.TournamentKoPhaseService;
import at.ac.tuwien.sepr.groupphase.backend.service.TournamentQualificationService;
import at.ac.tuwien.sepr.groupphase.backend.service.TournamentTeamService;
import at.ac.tuwien.sepr.groupphase.backend.service.models.KoStandingModel;
import at.ac.tuwien.sepr.groupphase.backend.service.models.KoStandingParticipantModel;
import at.ac.tuwien.sepr.groupphase.backend.service.models.QualificationTeamScoreModel;
import at.ac.tuwien.sepr.groupphase.backend.util.BeerDateTime;
import lombok.AllArgsConstructor;
@ -173,7 +171,7 @@ public class TournamentKoPhaseServiceImpl implements TournamentKoPhaseService {
}
@Override
public KoStandingModel getKoStandingsTree(Long tournamentId) {
public KoStanding getKoStandingsTree(Long tournamentId) {
LOG.debug("Get ko standings for tournament {}.", tournamentId);
var standings = koStandingsRepository.getAllByTournamentId(tournamentId);
@ -200,11 +198,11 @@ public class TournamentKoPhaseServiceImpl implements TournamentKoPhaseService {
stack.addAll(newPrecedingStandings);
}
return this.mapEntityTreeToStandingModel(rootNode);
return rootNode;
}
@Override
public KoStandingModel updateKoStanding(
public KoStanding updateKoStanding(
String userName,
Long tournamentId,
Long standingId,
@ -230,7 +228,6 @@ public class TournamentKoPhaseServiceImpl implements TournamentKoPhaseService {
// Ensure we return an up-to-date object in any case
return this.koStandingsRepository.findById(standingId)
.map(this::mapEntityTreeToStandingModel)
.orElseThrow(() -> new NotFoundException("KO standing not found"));
}
@ -262,12 +259,24 @@ public class TournamentKoPhaseServiceImpl implements TournamentKoPhaseService {
KoStanding standing,
TournamentUpdateKoStandingDto.DrinksPickupDto updateDto
) {
final var preceding = standing.getPreceedingStandings()
.stream().filter(p -> p.getTeam().getId() == updateDto.teamId())
.findFirst()
.orElseThrow(() -> new PreconditionFailedException(
"Team %d is not a participant of KO match %d"
.formatted(updateDto.teamId(), standing.getId())));
KoStanding preceding;
if (!standing.hasPrecedingMatches()) {
if (standing.getTeam().getId() != updateDto.teamId()) {
throw new PreconditionFailedException(
"Team %d is not a participant of KO match %d"
.formatted(updateDto.teamId(), standing.getId())
);
}
preceding = standing;
} else {
preceding = standing.getPreceedingStandings()
.stream().filter(p -> p.getTeam().getId() == updateDto.teamId())
.findFirst()
.orElseThrow(() -> new PreconditionFailedException(
"Team %d is not a participant of KO match %d"
.formatted(updateDto.teamId(), standing.getId())
));
}
if (preceding.isDrinksCollected()) {
throw new TeamMatchDrinksAlreadyPickedUpException(standing.getId(), preceding.getTeam().getId());
@ -313,22 +322,4 @@ public class TournamentKoPhaseServiceImpl implements TournamentKoPhaseService {
standing.setStartTime(BeerDateTime.nowUtc());
this.koStandingsRepository.saveAndFlush(standing);
}
/**
* Maps an entity KO-standing tree to the appropriate model.
* This must be (carefully) hand-written, as Mapstruct cannot reliably deal with graphs/trees.
*
* @param node Root node of the tree to map
* @return the mapped model
*/
private KoStandingModel mapEntityTreeToStandingModel(KoStanding node) {
final var model = this.koPhaseMapper.entityToModel(node);
final var participants = node.getPreceedingStandings()
.stream().map(s -> new KoStandingParticipantModel(this.mapEntityTreeToStandingModel(s), s.isDrinksCollected()))
.toList();
model.setParticipants(participants);
return model;
}
}

View file

@ -1,26 +0,0 @@
package at.ac.tuwien.sepr.groupphase.backend.service.models;
import at.ac.tuwien.sepr.groupphase.backend.entity.Team;
import at.ac.tuwien.sepr.groupphase.backend.entity.Tournament;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.List;
@Getter
@Builder(toBuilder = true)
public class KoStandingModel {
private long id;
private LocalDateTime startTime;
private LocalDateTime endTime;
private Team team;
private KoStandingModel nextStanding;
private Tournament tournament;
@Setter
private List<KoStandingParticipantModel> participants;
public List<KoStandingModel> precedingStandings() {
return this.participants.stream().map(KoStandingParticipantModel::precedingStanding).toList();
}
}

View file

@ -1,7 +0,0 @@
package at.ac.tuwien.sepr.groupphase.backend.service.models;
public record KoStandingParticipantModel(
KoStandingModel precedingStanding,
Boolean drinksCollected
) {
}

View file

@ -18,7 +18,6 @@ import at.ac.tuwien.sepr.groupphase.backend.service.TournamentKoPhaseService;
import at.ac.tuwien.sepr.groupphase.backend.service.TournamentQualificationService;
import at.ac.tuwien.sepr.groupphase.backend.service.TournamentService;
import at.ac.tuwien.sepr.groupphase.backend.service.TournamentTeamService;
import at.ac.tuwien.sepr.groupphase.backend.service.models.KoStandingModel;
import at.ac.tuwien.sepr.groupphase.backend.service.models.QualificationTeamScoreModel;
import at.ac.tuwien.sepr.groupphase.backend.util.BeerDateTime;
@ -197,13 +196,13 @@ public class TournamentKoPhaseServiceTest extends TestData {
var flattenedGeneratedMatches = koStandingsRepository.getAllByTournamentId(tournament.getId());
var fetchedMatches = koService.getKoStandingsTree(tournament.getId());
var flattenedFetchedMatches = new ArrayList<KoStandingModel>();
var fetchedStack = new Stack<KoStandingModel>();
var flattenedFetchedMatches = new ArrayList<KoStanding>();
var fetchedStack = new Stack<KoStanding>();
fetchedStack.push(fetchedMatches);
while (!fetchedStack.isEmpty()) {
var match = fetchedStack.pop();
flattenedFetchedMatches.add(match);
for (var child : match.precedingStandings()) {
for (var child : match.getPreceedingStandings()) {
fetchedStack.push(child);
}
}
@ -229,9 +228,9 @@ public class TournamentKoPhaseServiceTest extends TestData {
() -> assertEquals(generatedMatch.getEndTime(), fetchedMatchUnwrapped.getEndTime()),
() -> {
if (generatedMatch.getPreceedingStandings() != null
&& fetchedMatchUnwrapped.precedingStandings() != null) {
&& fetchedMatchUnwrapped.getPreceedingStandings() != null) {
assertEquals(generatedMatch.getPreceedingStandings().size(),
fetchedMatchUnwrapped.getParticipants().size());
fetchedMatchUnwrapped.getPreceedingStandings().size());
}
},
() -> {