package org.iatoki.judgels.uriel.services.impls; import com.google.common.collect.ImmutableMap; import com.google.gson.Gson; import org.iatoki.judgels.FileSystemProvider; import org.iatoki.judgels.uriel.ContestScoreboard; import org.iatoki.judgels.uriel.ContestScoreboardType; import org.iatoki.judgels.uriel.ContestStyle; import org.iatoki.judgels.uriel.adapters.impls.ScoreboardAdapters; import org.iatoki.judgels.uriel.Scoreboard; import org.iatoki.judgels.uriel.UrielProperties; import org.iatoki.judgels.uriel.config.TeamAvatarFile; import org.iatoki.judgels.uriel.models.daos.ContestContestantDao; import org.iatoki.judgels.uriel.models.daos.ContestDao; import org.iatoki.judgels.uriel.models.daos.ContestScoreboardDao; import org.iatoki.judgels.uriel.models.daos.ContestTeamDao; import org.iatoki.judgels.uriel.models.daos.ContestTeamMemberDao; import org.iatoki.judgels.uriel.models.entities.ContestContestantModel; import org.iatoki.judgels.uriel.models.entities.ContestContestantModel_; import org.iatoki.judgels.uriel.models.entities.ContestModel; import org.iatoki.judgels.uriel.models.entities.ContestScoreboardModel; import org.iatoki.judgels.uriel.models.entities.ContestTeamMemberModel; import org.iatoki.judgels.uriel.models.entities.ContestTeamModel; import org.iatoki.judgels.uriel.services.ContestScoreboardService; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import javax.persistence.NoResultException; import java.net.MalformedURLException; import java.net.URL; import java.util.Date; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @Singleton @Named("contestScoreboardService") public final class ContestScoreboardServiceImpl implements ContestScoreboardService { private final ContestDao contestDao; private final ContestContestantDao contestContestantDao; private final ContestTeamDao contestTeamDao; private final ContestTeamMemberDao contestTeamMemberDao; private final ContestScoreboardDao contestScoreboardDao; private final FileSystemProvider teamAvatarFileSystemProvider; @Inject public ContestScoreboardServiceImpl(ContestDao contestDao, ContestContestantDao contestContestantDao, ContestTeamDao contestTeamDao, ContestTeamMemberDao contestTeamMemberDao, ContestScoreboardDao contestScoreboardDao, @TeamAvatarFile FileSystemProvider teamAvatarFileSystemProvider) { this.contestDao = contestDao; this.contestContestantDao = contestContestantDao; this.contestTeamDao = contestTeamDao; this.contestTeamMemberDao = contestTeamMemberDao; this.contestScoreboardDao = contestScoreboardDao; this.teamAvatarFileSystemProvider = teamAvatarFileSystemProvider; } @Override public boolean isContestScoreboardExistByContestJidAndScoreboardType(String contestJid, ContestScoreboardType type) { return contestScoreboardDao.isContestScoreboardExistByContestJidAndScoreboardType(contestJid, type.name()); } @Override public ContestScoreboard findContestScoreboardByContestJidAndScoreboardType(String contestJid, ContestScoreboardType type) { ContestModel contestModel = contestDao.findByJid(contestJid); ContestScoreboardModel contestScoreboardModel = contestScoreboardDao.findContestScoreboardByContestJidAndScoreboardType(contestJid, type.name()); return createContestScoreboardFromModel(contestScoreboardModel, ContestStyle.valueOf(contestModel.style)); } @Override public Map<String, URL> getMapContestantJidToImageUrlInContest(String contestJid) { ImmutableMap.Builder<String, URL> resultBuilder = ImmutableMap.builder(); List<ContestTeamModel> contestTeamModels = contestTeamDao.findContestTeamModelsByContestJid(contestJid); ImmutableMap.Builder<String, ContestTeamModel> contestTeamModelBuilder = ImmutableMap.builder(); for (ContestTeamModel contestTeamModel : contestTeamModels) { contestTeamModelBuilder.put(contestTeamModel.jid, contestTeamModel); } Map<String, ContestTeamModel> contestTeamModelMap = contestTeamModelBuilder.build(); List<String> contestTeamJids = contestTeamModels.stream().map(ct -> ct.jid).collect(Collectors.toList()); List<ContestContestantModel> contestContestantModels = contestContestantDao.findSortedByFilters("id", "asc", "", ImmutableMap.of(ContestContestantModel_.contestJid, contestJid), ImmutableMap.of(), 0, -1); for (ContestContestantModel contestContestantModel : contestContestantModels) { if (contestTeamMemberDao.isUserRegisteredAsMemberInAnyTeam(contestContestantModel.userJid, contestTeamJids)) { ContestTeamMemberModel contestTeamMemberModel = contestTeamMemberDao.findContestTeamMemberByMemberJidInAnyTeam(contestContestantModel.userJid, contestTeamJids); resultBuilder.put(contestContestantModel.userJid, getTeamImageURLFromImageName(contestTeamModelMap.get(contestTeamMemberModel.teamJid).teamImageName)); } else { resultBuilder.put(contestContestantModel.userJid, AvatarCacheServiceImpl.getInstance().getAvatarUrl(contestContestantModel.userJid)); } } return resultBuilder.build(); } @Override public void upsertFrozenScoreboard(long contestScoreboardId) { ContestScoreboardModel contestScoreboardModel = contestScoreboardDao.findById(contestScoreboardId); ContestScoreboardModel frozenContestScoreboardModel; if (contestScoreboardDao.isContestScoreboardExistByContestJidAndScoreboardType(contestScoreboardModel.contestJid, ContestScoreboardType.FROZEN.name())) { frozenContestScoreboardModel = contestScoreboardDao.findContestScoreboardByContestJidAndScoreboardType(contestScoreboardModel.contestJid, ContestScoreboardType.FROZEN.name()); } else { frozenContestScoreboardModel = new ContestScoreboardModel(); } frozenContestScoreboardModel.contestJid = contestScoreboardModel.contestJid; frozenContestScoreboardModel.scoreboard = contestScoreboardModel.scoreboard; frozenContestScoreboardModel.type = ContestScoreboardType.FROZEN.name(); contestScoreboardDao.edit(frozenContestScoreboardModel, "scoreUpdater", "localhost"); } @Override public void updateContestScoreboardByContestJidAndScoreboardType(String contestJid, ContestScoreboardType type, Scoreboard scoreboard) { try { ContestScoreboardModel contestScoreboardModel = contestScoreboardDao.findContestScoreboardByContestJidAndScoreboardType(contestJid, type.name()); contestScoreboardModel.scoreboard = new Gson().toJson(scoreboard); contestScoreboardDao.edit(contestScoreboardModel, "scoreboardUpdater", "localhost"); } catch (NoResultException e) { // just do nothing } } private ContestScoreboard createContestScoreboardFromModel(ContestScoreboardModel contestScoreboardModel, ContestStyle style) { Scoreboard scoreboard = ScoreboardAdapters.fromContestStyle(style).parseScoreboardFromJson(contestScoreboardModel.scoreboard); return new ContestScoreboard(contestScoreboardModel.id, contestScoreboardModel.contestJid, ContestScoreboardType.valueOf(contestScoreboardModel.type), scoreboard, new Date(contestScoreboardModel.timeUpdate)); } private URL getTeamImageURLFromImageName(String imageName) { try { return new URL(UrielProperties.getInstance().getUrielBaseUrl() + org.iatoki.judgels.uriel.controllers.apis.routes.ContestAPIController.renderTeamAvatarImage(imageName)); } catch (MalformedURLException e) { throw new RuntimeException(e); } } }