Merge branch 'regatta-log' of sapsailing.com:/home/trac/git into regatta-log

This commit is contained in:
Fredrik Teschke committed 2014-12-05 20:18:42 +01:00
commit 1a4f86e3ad
2 files changed
+263 -55

No files matched your search

@@ -0,0 +1,39 @@
package com.sap.sailing.domain.abstractlog.regatta.impl;
import java.io.Serializable;
import com.sap.sailing.domain.abstractlog.BaseLogAnalyzer;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
/**
* BaseLogAnalyzer used for finding the ID of an open ended @link{DeviceMappingEvent} to a corresponding @link{CloseOpenEndedDeviceMappingEvent}
*
* If no corresponding event has been found, null is returned
*/
public class OpenEndedDeviceMappingFinder extends BaseLogAnalyzer<RegattaLog, RegattaLogEvent, RegattaLogEventVisitor, Serializable> {
private Serializable deviceUuid;
public OpenEndedDeviceMappingFinder(RegattaLog log, Serializable deviceUuid) {
super(log);
this.deviceUuid = deviceUuid;
}
@Override
protected Serializable performAnalysis() {
for (RegattaLogEvent regattaLogEvent : log.getUnrevokedEvents()) {
if (regattaLogEvent instanceof RegattaLogDeviceCompetitorMappingEvent) {
RegattaLogDeviceCompetitorMappingEvent deviceMappingEvent = (RegattaLogDeviceCompetitorMappingEvent) regattaLogEvent;
if (deviceMappingEvent.getDevice().getStringRepresentation().equals(deviceUuid)) {
return deviceMappingEvent.getId();
}
}
}
return null;
}
}
@@ -1,16 +1,21 @@
package com.sap.sailing.server.gateway.jaxrs.api;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.logging.Logger;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@@ -21,8 +26,18 @@ import javax.ws.rs.core.Response.Status;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogCloseOpenEndedDeviceMappingEventImpl;
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorMappingEventImpl;
import com.sap.sailing.domain.abstractlog.regatta.impl.OpenEndedDeviceMappingFinder;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.Nationality;
import com.sap.sailing.domain.base.RaceColumn;
@@ -36,19 +51,27 @@ import com.sap.sailing.domain.common.dto.LeaderboardDTO;
import com.sap.sailing.domain.common.dto.LeaderboardEntryDTO;
import com.sap.sailing.domain.common.dto.LeaderboardRowDTO;
import com.sap.sailing.domain.common.dto.RaceColumnDTO;
import com.sap.sailing.domain.leaderboard.HasRegattaLog;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.SettableScoreCorrection;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.domain.racelogtracking.impl.SmartphoneUUIDIdentifierImpl;
import com.sap.sailing.domain.tracking.MarkPassing;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.impl.Helpers;
import com.sap.sailing.server.gateway.jaxrs.AbstractSailingServerResource;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint;
@Path("/v1/leaderboards")
public class LeaderboardsResource extends AbstractSailingServerResource {
public enum ResultStates { Live, Preliminary, Final };
public class LeaderboardsResource extends AbstractSailingServerResource {
private static final Logger logger = Logger.getLogger(LeaderboardsResource.class.getName());
public enum ResultStates {
Live, Preliminary, Final
};
@GET
@Produces("application/json;charset=UTF-8")
@@ -56,14 +79,14 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
JSONArray jsonLeaderboards = new JSONArray();
Map<String, Leaderboard> leaderboards = getService().getLeaderboards();
for (String leaderboardName : leaderboards.keySet()) {
if(!leaderboardName.equals(LeaderboardNameConstants.DEFAULT_LEADERBOARD_NAME))
if (!leaderboardName.equals(LeaderboardNameConstants.DEFAULT_LEADERBOARD_NAME))
jsonLeaderboards.add(leaderboardName);
}
String json = jsonLeaderboards.toJSONString();
return Response.ok(json, MediaType.APPLICATION_JSON).build();
}
@GET
@Produces("application/json;charset=UTF-8")
@Path("{name}")
@@ -76,16 +99,20 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
TimePoint requestTimePoint = MillisecondsTimePoint.now();
Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
if (leaderboard == null) {
response = Response.status(Status.NOT_FOUND).entity("Could not find a leaderboard with name '" + leaderboardName + "'.").type(MediaType.TEXT_PLAIN).build();
response = Response.status(Status.NOT_FOUND)
.entity("Could not find a leaderboard with name '" + leaderboardName + "'.")
.type(MediaType.TEXT_PLAIN).build();
} else {
try {
TimePoint resultTimePoint = calculateTimePointForResultState(leaderboard, resultState);
JSONObject jsonLeaderboard;
if (resultTimePoint != null) {
Util.Triple<TimePoint, ResultStates, Integer> resultStateAndTimePoint = new Util.Triple<>(resultTimePoint, resultState, maxCompetitorsCount);
Util.Triple<TimePoint, ResultStates, Integer> resultStateAndTimePoint = new Util.Triple<>(
resultTimePoint, resultState, maxCompetitorsCount);
jsonLeaderboard = getLeaderboardJson(leaderboard, resultStateAndTimePoint);
} else {
jsonLeaderboard = createEmptyLeaderboardJson(leaderboard, resultState, requestTimePoint, maxCompetitorsCount);
jsonLeaderboard = createEmptyLeaderboardJson(leaderboard, resultState, requestTimePoint,
maxCompetitorsCount);
}
StringWriter sw = new StringWriter();
@@ -94,24 +121,27 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
String json = sw.getBuffer().toString();
response = Response.ok(json, MediaType.APPLICATION_JSON).build();
} catch (NoWindException | InterruptedException | ExecutionException | IOException e) {
response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build();
response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage())
.type(MediaType.TEXT_PLAIN).build();
}
}
return response;
}
private JSONObject getLeaderboardJson(Leaderboard leaderboard, Util.Triple<TimePoint, ResultStates, Integer> timePointAndResultStateAndMaxCompetitorsCount)
throws NoWindException, InterruptedException, ExecutionException {
LeaderboardDTO leaderboardDTO = leaderboard.getLeaderboardDTO(timePointAndResultStateAndMaxCompetitorsCount.getA(),
Collections.<String> emptyList(), /* addOverallDetails */ false, getService(), getService().getBaseDomainFactory(),
/* fillNetPointsUncorrected */ false);
private JSONObject getLeaderboardJson(Leaderboard leaderboard,
Util.Triple<TimePoint, ResultStates, Integer> timePointAndResultStateAndMaxCompetitorsCount)
throws NoWindException, InterruptedException, ExecutionException {
LeaderboardDTO leaderboardDTO = leaderboard.getLeaderboardDTO(
timePointAndResultStateAndMaxCompetitorsCount.getA(), Collections.<String> emptyList(), /* addOverallDetails */
false, getService(), getService().getBaseDomainFactory(),
/* fillNetPointsUncorrected */false);
TimePoint resultTimePoint = timePointAndResultStateAndMaxCompetitorsCount.getA();
ResultStates resultState = timePointAndResultStateAndMaxCompetitorsCount.getB();
Integer maxCompetitorsCount = timePointAndResultStateAndMaxCompetitorsCount.getC();
JSONObject jsonLeaderboard = new JSONObject();
writeCommonLeaderboardData(jsonLeaderboard, leaderboardDTO, resultState, resultTimePoint, maxCompetitorsCount);
JSONArray jsonCompetitorEntries = new JSONArray();
@@ -119,19 +149,19 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
int counter = 1;
for (CompetitorDTO competitor : leaderboardDTO.competitors) {
LeaderboardRowDTO leaderboardRowDTO = leaderboardDTO.rows.get(competitor);
if(maxCompetitorsCount != null && counter > maxCompetitorsCount) {
if (maxCompetitorsCount != null && counter > maxCompetitorsCount) {
break;
}
JSONObject jsonCompetitor = new JSONObject();
jsonCompetitor.put("name", competitor.getName());
final String displayName = leaderboardDTO.getDisplayName(competitor);
jsonCompetitor.put("displayName", displayName==null?competitor.getName():displayName);
jsonCompetitor.put("displayName", displayName == null ? competitor.getName() : displayName);
jsonCompetitor.put("id", competitor.getIdAsString());
jsonCompetitor.put("sailID", competitor.getSailID());
jsonCompetitor.put("nationality", competitor.getThreeLetterIocCountryCode());
jsonCompetitor.put("countryCode", competitor.getTwoLetterIsoCountryCode());
jsonCompetitor.put("rank", counter);
jsonCompetitor.put("carriedPoints", leaderboardRowDTO.carriedPoints);
jsonCompetitor.put("totalPoints", leaderboardRowDTO.totalPoints);
@@ -139,21 +169,24 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
JSONObject jsonRaceColumns = new JSONObject();
jsonCompetitor.put("raceScores", jsonRaceColumns);
for (RaceColumnDTO raceColumn : leaderboardDTO.getRaceList()) {
List<CompetitorDTO> regattaRankedCompetitorsForColumn = leaderboardDTO.getCompetitorOrderingPerRaceColumnName().get(raceColumn.getName());
List<CompetitorDTO> regattaRankedCompetitorsForColumn = leaderboardDTO
.getCompetitorOrderingPerRaceColumnName().get(raceColumn.getName());
JSONObject jsonEntry = new JSONObject();
jsonRaceColumns.put(raceColumn.getName(), jsonEntry);
LeaderboardEntryDTO leaderboardEntry = leaderboardRowDTO.fieldsByRaceColumnName.get(raceColumn.getName());
LeaderboardEntryDTO leaderboardEntry = leaderboardRowDTO.fieldsByRaceColumnName.get(raceColumn
.getName());
final FleetDTO fleetOfCompetitor = leaderboardEntry.fleet;
jsonEntry.put("fleet", fleetOfCompetitor==null?"":fleetOfCompetitor.getName());
jsonEntry.put("fleet", fleetOfCompetitor == null ? "" : fleetOfCompetitor.getName());
jsonEntry.put("netPoints", leaderboardEntry.netPointsCorrected);
jsonEntry.put("uncorrectedNetPoints", leaderboardEntry.netPoints);
jsonEntry.put("totalPoints", leaderboardEntry.totalPoints);
MaxPointsReason maxPointsReason = leaderboardEntry.reasonForMaxPoints;
jsonEntry.put("maxPointsReason", maxPointsReason != null ? maxPointsReason.toString(): null);
jsonEntry.put("rank", regattaRankedCompetitorsForColumn.indexOf(competitor)+1);
List<CompetitorDTO> raceRankedCompetitorsInColumn = leaderboardDTO.getCompetitorsFromBestToWorst(raceColumn);
jsonEntry.put("raceRank", raceRankedCompetitorsInColumn.indexOf(competitor)+1);
jsonEntry.put("maxPointsReason", maxPointsReason != null ? maxPointsReason.toString() : null);
jsonEntry.put("rank", regattaRankedCompetitorsForColumn.indexOf(competitor) + 1);
List<CompetitorDTO> raceRankedCompetitorsInColumn = leaderboardDTO
.getCompetitorsFromBestToWorst(raceColumn);
jsonEntry.put("raceRank", raceRankedCompetitorsInColumn.indexOf(competitor) + 1);
jsonEntry.put("isDiscarded", leaderboardEntry.discarded);
jsonEntry.put("isCorrected", leaderboardEntry.hasScoreCorrection());
}
@@ -162,10 +195,10 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
return jsonLeaderboard;
}
private JSONObject createEmptyLeaderboardJson(Leaderboard leaderboard,
ResultStates resultState, TimePoint requestTimePoint, Integer maxCompetitorsCount) throws NoWindException {
private JSONObject createEmptyLeaderboardJson(Leaderboard leaderboard, ResultStates resultState,
TimePoint requestTimePoint, Integer maxCompetitorsCount) throws NoWindException {
JSONObject jsonLeaderboard = new JSONObject();
writeCommonLeaderboardData(jsonLeaderboard, leaderboard, resultState, null, maxCompetitorsCount);
JSONArray jsonCompetitorEntries = new JSONArray();
@@ -174,13 +207,14 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
JSONObject jsonCompetitor = new JSONObject();
jsonCompetitor.put("name", competitor.getName());
final String displayName = leaderboard.getDisplayName(competitor);
jsonCompetitor.put("displayName", displayName==null?competitor.getName():displayName);
jsonCompetitor.put("displayName", displayName == null ? competitor.getName() : displayName);
jsonCompetitor.put("id", competitor.getId().toString());
jsonCompetitor.put("sailID", competitor.getBoat().getSailID());
Nationality nationality = competitor.getTeam().getNationality();
jsonCompetitor.put("nationality", nationality != null ? nationality.getThreeLetterIOCAcronym(): null);
jsonCompetitor.put("countryCode", nationality != null ? (nationality.getCountryCode() != null ? nationality.getCountryCode().getTwoLetterISOCode(): null) : null);
jsonCompetitor.put("nationality", nationality != null ? nationality.getThreeLetterIOCAcronym() : null);
jsonCompetitor.put("countryCode", nationality != null ? (nationality.getCountryCode() != null ? nationality
.getCountryCode().getTwoLetterISOCode() : null) : null);
jsonCompetitor.put("rank", 0);
jsonCompetitor.put("carriedPoints", null);
jsonCompetitor.put("totalPoints", null);
@@ -191,7 +225,7 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
JSONObject jsonEntry = new JSONObject();
jsonRaceColumns.put(raceColumn.getName(), jsonEntry);
final Fleet fleetOfCompetitor = raceColumn.getFleetOfCompetitor(competitor);
jsonEntry.put("fleet", fleetOfCompetitor==null?"":fleetOfCompetitor.getName());
jsonEntry.put("fleet", fleetOfCompetitor == null ? "" : fleetOfCompetitor.getName());
jsonEntry.put("netPoints", null);
jsonEntry.put("totalPoints", null);
jsonEntry.put("maxPointsReason", "");
@@ -203,50 +237,51 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
return jsonLeaderboard;
}
private void writeCommonLeaderboardData(JSONObject jsonLeaderboard, LeaderboardDTO leaderboard, ResultStates resultState,
TimePoint resultTimePoint, Integer maxCompetitorsCount) {
private void writeCommonLeaderboardData(JSONObject jsonLeaderboard, LeaderboardDTO leaderboard,
ResultStates resultState, TimePoint resultTimePoint, Integer maxCompetitorsCount) {
jsonLeaderboard.put("name", leaderboard.name);
jsonLeaderboard.put("resultTimepoint", resultTimePoint != null ? resultTimePoint.asMillis() : null);
jsonLeaderboard.put("resultState", resultState.name());
jsonLeaderboard.put("maxCompetitorsCount", maxCompetitorsCount);
jsonLeaderboard.put("higherScoreIsBetter", leaderboard.isHigherScoreBetter());
jsonLeaderboard.put("scoringComment", leaderboard.getComment());
Date lastUpdateTimepoint = leaderboard.getTimePointOfLastCorrectionsValidity();
jsonLeaderboard.put("lastScoringUpdate", lastUpdateTimepoint != null ? lastUpdateTimepoint.getTime(): null);
jsonLeaderboard.put("lastScoringUpdate", lastUpdateTimepoint != null ? lastUpdateTimepoint.getTime() : null);
JSONArray jsonColumnNames = new JSONArray();
jsonLeaderboard.put("columnNames", jsonColumnNames);
for (RaceColumnDTO raceColumn : leaderboard.getRaceList()) {
jsonColumnNames.add(raceColumn.getName());
}
}
private void writeCommonLeaderboardData(JSONObject jsonLeaderboard, Leaderboard leaderboard, ResultStates resultState,
TimePoint resultTimePoint, Integer maxCompetitorsCount) {
private void writeCommonLeaderboardData(JSONObject jsonLeaderboard, Leaderboard leaderboard,
ResultStates resultState, TimePoint resultTimePoint, Integer maxCompetitorsCount) {
jsonLeaderboard.put("name", leaderboard.getName());
jsonLeaderboard.put("resultTimepoint", resultTimePoint != null ? resultTimePoint.asMillis() : null);
jsonLeaderboard.put("resultState", resultState.name());
jsonLeaderboard.put("maxCompetitorsCount", maxCompetitorsCount);
SettableScoreCorrection scoreCorrection = leaderboard.getScoreCorrection();
if (scoreCorrection != null) {
jsonLeaderboard.put("scoringComment", scoreCorrection.getComment());
TimePoint lastUpdateTimepoint = scoreCorrection.getTimePointOfLastCorrectionsValidity();
jsonLeaderboard.put("lastScoringUpdate", lastUpdateTimepoint != null ? lastUpdateTimepoint.asMillis(): null);
jsonLeaderboard.put("lastScoringUpdate", lastUpdateTimepoint != null ? lastUpdateTimepoint.asMillis()
: null);
} else {
jsonLeaderboard.put("scoringComment", null);
jsonLeaderboard.put("lastScoringUpdate", null);
}
JSONArray jsonColumnNames = new JSONArray();
jsonLeaderboard.put("columnNames", jsonColumnNames);
for (RaceColumn raceColumn : leaderboard.getRaceColumns()) {
jsonColumnNames.add(raceColumn.getName());
}
}
private TimePoint calculateTimePointForResultState(Leaderboard leaderboard, ResultStates resultState) {
TimePoint result = null;
switch (resultState) {
@@ -258,10 +293,12 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
break;
case Preliminary:
case Final:
if (leaderboard.getScoreCorrection() != null && leaderboard.getScoreCorrection().getTimePointOfLastCorrectionsValidity() != null) {
if (leaderboard.getScoreCorrection() != null
&& leaderboard.getScoreCorrection().getTimePointOfLastCorrectionsValidity() != null) {
result = leaderboard.getScoreCorrection().getTimePointOfLastCorrectionsValidity();
// As we don't have implemented bug 1246 (Define a clear result state for races and leaderboards) so far
// we need to make sure that the timpoint for the final state is not determined in the middle of a running race,
// we need to make sure that the timpoint for the final state is not determined in the middle of a
// running race,
// because this would deliver not only final results but also some "mixed-in" live results.
// Therefore, if there is a race that hasn't finished yet and whose first start mark passing is before
// the current result, move result to before the start mark passing.
@@ -270,7 +307,8 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
if (endOfRace == null) {
Waypoint firstWaypoint = trackedRace.getRace().getCourse().getFirstWaypoint();
if (firstWaypoint != null) {
Iterable<MarkPassing> markPassingsForFirstWaypoint = trackedRace.getMarkPassingsInOrder(firstWaypoint);
Iterable<MarkPassing> markPassingsForFirstWaypoint = trackedRace
.getMarkPassingsInOrder(firstWaypoint);
if (markPassingsForFirstWaypoint != null) {
trackedRace.lockForRead(markPassingsForFirstWaypoint);
try {
@@ -294,5 +332,136 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
return result;
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Path("{name}/device_mappings/start")
public Response postCheckin(String json, @PathParam("name") String leaderboardName) {
Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
if (!leaderboardIsValid(leaderboard)) {
return Response.status(Status.INTERNAL_SERVER_ERROR)
.entity("Leaderboard does not exist or does not hold a RegattaLog").type(MediaType.TEXT_PLAIN)
.build();
}
;
HasRegattaLog hasRegattaLog = (HasRegattaLog) leaderboard;
DomainFactory domainFactory = getService().getDomainObjectFactory().getBaseDomainFactory();
AbstractLogEventAuthor author = new LogEventAuthorImpl(AbstractLogEventAuthor.NAME_COMPATIBILITY,
AbstractLogEventAuthor.PRIORITY_COMPATIBILITY);
RegattaLogDeviceCompetitorMappingEventImpl event;
JSONObject requestObject;
try {
logger.fine("Post issued to " + this.getClass().getName());
Object requestBody = JSONValue.parseWithException(json);
requestObject = Helpers.toJSONObjectSafe(requestBody);
logger.fine("JSON requestObject is: " + requestObject.toString());
} catch (ParseException | JsonDeserializationException e) {
logger.warning(String.format("Exception while parsing post request:\n%s", e.toString()));
return Response.status(Status.BAD_REQUEST).entity("Invalid JSON body in request")
.type(MediaType.TEXT_PLAIN).build();
}
MillisecondsTimePoint now = MillisecondsTimePoint.now();
String competitorId = (String) requestObject.get("competitorId");
String deviceUuid = (String) requestObject.get("deviceUuid");
Long fromMillis = (Long) requestObject.get("fromMillis");
String deviceType = (String) requestObject.get("deviceType");
String pushDeviceId = (String) requestObject.get("pushDeviceId");
if (competitorId == null || deviceUuid == null || fromMillis == null || deviceType == null
|| pushDeviceId == null) {
return Response.status(Status.BAD_REQUEST).entity("Invalid JSON body in request")
.type(MediaType.TEXT_PLAIN).build();
}
//TODO: use device type and pushDeviceId
Competitor mappedTo = domainFactory.getExistingCompetitorById(competitorId);
DeviceIdentifier device = new SmartphoneUUIDIdentifierImpl(UUID.fromString(deviceUuid));
TimePoint from = new MillisecondsTimePoint(fromMillis);
event = new RegattaLogDeviceCompetitorMappingEventImpl(now, author, now, UUID.randomUUID(), mappedTo, device,
from, null);
hasRegattaLog.getRegattaLog().add(event);
logger.fine("Successfully added regatta log event");
return Response.status(Status.OK).build();
}
private boolean leaderboardIsValid(Leaderboard leaderboard) {
if (leaderboard == null) {
logger.warning("Could not find a leaderboard with the given name");
return false;
}
if (!(leaderboard instanceof HasRegattaLog)) {
logger.warning("Specified Leaderboard has no attached RegattaLog");
return false;
}
return true;
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Path("{name}/device_mappings/end")
public Response postCheckout(String json, @PathParam("name") String leaderboardName) {
Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
if (!leaderboardIsValid(leaderboard)) {
return Response.status(Status.INTERNAL_SERVER_ERROR)
.entity("Leaderboard does not exist or does not hold a RegattaLog").type(MediaType.TEXT_PLAIN)
.build();
}
HasRegattaLog hasRegattaLog = (HasRegattaLog) leaderboard;
AbstractLogEventAuthor author = new LogEventAuthorImpl(AbstractLogEventAuthor.NAME_COMPATIBILITY,
AbstractLogEventAuthor.PRIORITY_COMPATIBILITY);
MillisecondsTimePoint now = MillisecondsTimePoint.now();
logger.fine("Post issued to " + this.getClass().getName());
Object requestBody;
JSONObject requestObject;
try {
requestBody = JSONValue.parseWithException(json);
requestObject = Helpers.toJSONObjectSafe(requestBody);
} catch (ParseException | JsonDeserializationException e) {
logger.warning(String.format("Exception while parsing post request:\n%s", e.toString()));
return Response.status(Status.BAD_REQUEST).entity("Invalid JSON body in request")
.type(MediaType.TEXT_PLAIN).build();
}
logger.fine("JSON requestObject is: " + requestObject.toString());
Long toMillis = (Long) requestObject.get("toMillis");
String deviceUuid = (String) requestObject.get("deviceUuid");
TimePoint closingTimePoint = new MillisecondsTimePoint(toMillis);
if (toMillis == null || deviceUuid == null || closingTimePoint == null){
return Response.status(Status.BAD_REQUEST).entity("Invalid JSON body in request")
.type(MediaType.TEXT_PLAIN).build();
}
OpenEndedDeviceMappingFinder finder = new OpenEndedDeviceMappingFinder(hasRegattaLog.getRegattaLog(), deviceUuid);
Serializable deviceMappingEventId = finder.analyze();
if (deviceMappingEventId == null) {
return Response.status(Status.BAD_REQUEST)
.entity("No corresponding open competitor to device mapping has been found")
.type(MediaType.TEXT_PLAIN).build();
}
RegattaLogCloseOpenEndedDeviceMappingEventImpl event = new RegattaLogCloseOpenEndedDeviceMappingEventImpl(now,
author, now, UUID.randomUUID(), deviceMappingEventId, closingTimePoint);
hasRegattaLog.getRegattaLog().add(event);
return Response.status(Status.GONE).build();
}
}