From ce57e5a808384e24ddeb560f430f717c95f66e3c Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Mon, 16 Sep 2019 18:12:10 +0200 Subject: [PATCH] added ORC PCS explicit scratch boat selection support Change-Id: Ie0bab7789a16476249760b80f3007e010aa48cc4 --- .../impl/DomainObjectFactoryImpl.java | 18 +++-- .../impl/MongoObjectFactoryImpl.java | 18 ++++- .../impl/MongoRaceLogStoreVisitor.java | 7 ++ ...t.java => RaceLogORCScratchBoatEvent.java} | 2 +- .../orc/RaceLogORCScratchBoatFinder.java | 40 +++++++++++ .../impl/RaceLogORCScratchBoatEventImpl.java | 52 ++++++++++++++ .../abstractlog/race/RaceLogEventVisitor.java | 3 + .../impl/AbstractRaceLogChangedVisitor.java | 6 ++ .../race/impl/BaseRaceLogEventVisitor.java | 6 ++ ...CollaborationWithRaceLogAndRegattaLog.java | 2 +- .../impl/RaceColumnRaceLogReplicator.java | 6 ++ .../ORCPerformanceCurveRankingMetric.java | 68 +++++++++++++++---- .../domain/ranking/AbstractRankingMetric.java | 30 ++++++++ .../NonPerformanceCurveRankingMetric.java | 28 +------- .../impl/RaceLogEventDeserializer.java | 9 ++- ...ertificateAssignmentEventDeserializer.java | 4 +- ...aceLogORCScratchBoatEventDeserializer.java | 38 +++++++++++ .../racelog/impl/RaceLogEventSerializer.java | 14 +++- ...CCertificateAssignmentEventSerializer.java | 2 +- .../RaceLogORCScratchBoatEventSerializer.java | 38 +++++++++++ .../racelog/RaceLogEventDeserializerTest.java | 4 +- .../racelog/RaceLogEventSerializerTest.java | 5 +- 22 files changed, 345 insertions(+), 55 deletions(-) rename java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/{ORCScratchBoatEvent.java => RaceLogORCScratchBoatEvent.java} (74%) create mode 100755 java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/RaceLogORCScratchBoatFinder.java create mode 100755 java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/impl/RaceLogORCScratchBoatEventImpl.java create mode 100755 java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/racelog/impl/RaceLogORCScratchBoatEventDeserializer.java create mode 100755 java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/racelog/impl/RaceLogORCScratchBoatEventSerializer.java diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java index 29a6e1a3b2d..920a17052b6 100644 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java @@ -46,9 +46,11 @@ import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCCertificateAssignmentEvent; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCLegDataEvent; +import com.sap.sailing.domain.abstractlog.orc.RaceLogORCScratchBoatEvent; import com.sap.sailing.domain.abstractlog.orc.RegattaLogORCCertificateAssignmentEvent; import com.sap.sailing.domain.abstractlog.orc.impl.RaceLogORCCertificateAssignmentEventImpl; import com.sap.sailing.domain.abstractlog.orc.impl.RaceLogORCLegDataEventImpl; +import com.sap.sailing.domain.abstractlog.orc.impl.RaceLogORCScratchBoatEventImpl; import com.sap.sailing.domain.abstractlog.orc.impl.RegattaLogORCCertificateAssignmentEventImpl; import com.sap.sailing.domain.abstractlog.race.CompetitorResult.MergeState; import com.sap.sailing.domain.abstractlog.race.CompetitorResults; @@ -1632,12 +1634,20 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { resultEvent = loadRaceLogORCLegDataEvent(createdAt, author, logicalTimePoint, id, passId, dbObject); } else if (eventClass.equals(RaceLogORCCertificateAssignmentEvent.class.getSimpleName())) { resultEvent = loadRaceLogORCCertificateAssignmentEvent(createdAt, author, logicalTimePoint, id, passId, dbObject); + } else if (eventClass.equals(RaceLogORCScratchBoatEvent.class.getSimpleName())) { + resultEvent = loadRaceLogORCScratchBoatEvent(createdAt, author, logicalTimePoint, id, passId, dbObject); } else { throw new IllegalStateException(String.format("Unknown RaceLogEvent type %s", eventClass)); } return new Pair<>(resultEvent, dbObjectForUpdate); } + private RaceLogEvent loadRaceLogORCScratchBoatEvent(TimePoint createdAt, AbstractLogEventAuthor author, + TimePoint logicalTimePoint, Serializable id, Integer passId, Document dbObject) { + Serializable competitorId = (Serializable) dbObject.get(FieldNames.COMPETITOR_ID.name()); + return new RaceLogORCScratchBoatEventImpl(createdAt, logicalTimePoint, author, id, passId, competitorId); + } + private RaceLogEvent loadRaceLogUseCompetitorsFromRaceLogEvent(TimePoint createdAt, AbstractLogEventAuthor author, TimePoint logicalTimePoint, Serializable id, Integer passId, List competitors, Document dbObject) { @@ -2038,8 +2048,8 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { final JsonWriterSettings writerSettings = JsonWriterSettings.builder().outputMode(JsonMode.RELAXED).build(); JSONObject json = Helpers.toJSONObjectSafe(new JSONParser().parse(certificateDbObject.toJson(writerSettings))); final ORCCertificate certificate = new ORCCertificateJsonDeserializer().deserialize(json); - Serializable competitorId = (Serializable) dbObject.get(FieldNames.COMPETITOR_ID.name()); - return new RaceLogORCCertificateAssignmentEventImpl(createdAt, logicalTimePoint, author, id, passId, certificate, competitorId); + Serializable boatId = (Serializable) dbObject.get(FieldNames.RACE_LOG_BOAT_ID.name()); + return new RaceLogORCCertificateAssignmentEventImpl(createdAt, logicalTimePoint, author, id, passId, certificate, boatId); } @Override @@ -2240,8 +2250,8 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { final JsonWriterSettings writerSettings = JsonWriterSettings.builder().outputMode(JsonMode.RELAXED).build(); JSONObject json = Helpers.toJSONObjectSafe(new JSONParser().parse(certificateDbObject.toJson(writerSettings))); final ORCCertificate certificate = new ORCCertificateJsonDeserializer().deserialize(json); - Serializable competitorId = (Serializable) dbObject.get(FieldNames.COMPETITOR_ID.name()); - return new RegattaLogORCCertificateAssignmentEventImpl(createdAt, logicalTimePoint, author, id, certificate, competitorId); + Serializable boatId = (Serializable) dbObject.get(FieldNames.RACE_LOG_BOAT_ID.name()); + return new RegattaLogORCCertificateAssignmentEventImpl(createdAt, logicalTimePoint, author, id, certificate, boatId); } /** diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java index 251ffb85238..a2a81d51b59 100644 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java @@ -29,6 +29,7 @@ import com.mongodb.client.result.DeleteResult; import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCCertificateAssignmentEvent; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCLegDataEvent; +import com.sap.sailing.domain.abstractlog.orc.RaceLogORCScratchBoatEvent; import com.sap.sailing.domain.abstractlog.orc.RegattaLogORCCertificateAssignmentEvent; import com.sap.sailing.domain.abstractlog.race.CompetitorResult; import com.sap.sailing.domain.abstractlog.race.CompetitorResults; @@ -1010,11 +1011,26 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { Document result = new Document(); storeRaceLogEventProperties(event, result); result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RaceLogORCCertificateAssignmentEvent.class.getSimpleName()); - result.append(FieldNames.COMPETITOR_ID.name(), event.getBoatId()); + result.append(FieldNames.RACE_LOG_BOAT_ID.name(), event.getBoatId()); result.append(FieldNames.ORC_CERTIFICATE.name(), createORCCertificateObject(event.getCertificate())); return result; } + + public Document storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogORCScratchBoatEvent event) { + Document result = new Document(); + storeRaceLogIdentifier(raceLogIdentifier, result); + result.put(FieldNames.RACE_LOG_EVENT.name(), storeORCScratchBoatEvent(event)); + return result; + } + private Document storeORCScratchBoatEvent(RaceLogORCScratchBoatEvent event) { + Document result = new Document(); + storeRaceLogEventProperties(event, result); + result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RaceLogORCScratchBoatEvent.class.getSimpleName()); + result.append(FieldNames.COMPETITOR_ID.name(), event.getCompetitorId()); + return result; + } + private Document storeORCLegDataEvent(RaceLogORCLegDataEvent event) { Document result = new Document(); storeRaceLogEventProperties(event, result); diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRaceLogStoreVisitor.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRaceLogStoreVisitor.java index 1ea93683c5e..519c3b87bae 100644 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRaceLogStoreVisitor.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRaceLogStoreVisitor.java @@ -6,6 +6,7 @@ import org.bson.Document; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCCertificateAssignmentEvent; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCLegDataEvent; +import com.sap.sailing.domain.abstractlog.orc.RaceLogORCScratchBoatEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseDesignChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogEndOfTrackingEvent; @@ -202,4 +203,10 @@ public class MongoRaceLogStoreVisitor implements RaceLogEventVisitor { Document object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event); mongoObjectFactory.storeRaceLogEventEvent(object); } + + @Override + public void visit(RaceLogORCScratchBoatEvent event) { + Document object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event); + mongoObjectFactory.storeRaceLogEventEvent(object); + } } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/ORCScratchBoatEvent.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/RaceLogORCScratchBoatEvent.java similarity index 74% rename from java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/ORCScratchBoatEvent.java rename to java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/RaceLogORCScratchBoatEvent.java index fb34347ea20..208e6231d36 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/ORCScratchBoatEvent.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/RaceLogORCScratchBoatEvent.java @@ -5,6 +5,6 @@ import java.io.Serializable; import com.sap.sailing.domain.abstractlog.Revokable; import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; -public interface ORCScratchBoatEvent extends RaceLogEvent, Revokable { +public interface RaceLogORCScratchBoatEvent extends RaceLogEvent, Revokable { Serializable getCompetitorId(); } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/RaceLogORCScratchBoatFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/RaceLogORCScratchBoatFinder.java new file mode 100755 index 00000000000..394720b1b40 --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/RaceLogORCScratchBoatFinder.java @@ -0,0 +1,40 @@ +package com.sap.sailing.domain.abstractlog.orc; + +import java.io.Serializable; +import java.util.Map; +import java.util.logging.Logger; + +import com.sap.sailing.domain.abstractlog.BaseLogAnalyzer; +import com.sap.sailing.domain.abstractlog.race.RaceLog; +import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; +import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor; +import com.sap.sailing.domain.base.Competitor; + +public class RaceLogORCScratchBoatFinder extends BaseLogAnalyzer { + private static final Logger logger = Logger.getLogger(RaceLogORCScratchBoatFinder.class.getName()); + private final Map competitorsById; + + public RaceLogORCScratchBoatFinder(RaceLog log, Map competitorsById) { + super(log); + this.competitorsById = competitorsById; + } + + @Override + protected Competitor performAnalysis() { + for (final RaceLogEvent o : getLog().getUnrevokedEventsDescending()) { + if (o instanceof RaceLogORCScratchBoatEvent) { + RaceLogORCScratchBoatEvent event = (RaceLogORCScratchBoatEvent) o; + final Serializable competitorId = event.getCompetitorId(); + final Competitor competitor = competitorsById.get(competitorId); + if (competitor != null) { + return competitor; + } else { + logger.warning("Unable to find competitor with ID " + competitorId + + " as an ORC Performance Curve scratch boat. Race log event is ignored."); + } + } + } + return null; + } + +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/impl/RaceLogORCScratchBoatEventImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/impl/RaceLogORCScratchBoatEventImpl.java new file mode 100755 index 00000000000..f9380495324 --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/impl/RaceLogORCScratchBoatEventImpl.java @@ -0,0 +1,52 @@ +package com.sap.sailing.domain.abstractlog.orc.impl; + +import java.io.Serializable; +import java.util.List; + +import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; +import com.sap.sailing.domain.abstractlog.impl.AbstractLogEventImpl; +import com.sap.sailing.domain.abstractlog.orc.RaceLogORCScratchBoatEvent; +import com.sap.sailing.domain.abstractlog.race.RaceLogEventData; +import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor; +import com.sap.sailing.domain.abstractlog.race.impl.RaceLogEventDataImpl; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sse.common.TimePoint; + +public class RaceLogORCScratchBoatEventImpl extends AbstractLogEventImpl implements RaceLogORCScratchBoatEvent { + private static final long serialVersionUID = 3506411337361892600L; + private final RaceLogEventData raceLogEventData; + private final Serializable competitorId; + + public RaceLogORCScratchBoatEventImpl(TimePoint createdAt, TimePoint logicalTimePoint, + AbstractLogEventAuthor author, Serializable pId, int passId, Competitor competitor) { + this(createdAt, logicalTimePoint, author, pId, passId, competitor.getId()); + } + + public RaceLogORCScratchBoatEventImpl(TimePoint createdAt, TimePoint logicalTimePoint, + AbstractLogEventAuthor author, Serializable pId, int passId, Serializable competitorId) { + super(createdAt, logicalTimePoint, author, pId); + this.raceLogEventData = new RaceLogEventDataImpl(/* involvedBoats */ null, passId); + this.competitorId = competitorId; + + } + + @Override + public void accept(RaceLogEventVisitor visitor) { + visitor.visit(this); + } + + @Override + public int getPassId() { + return raceLogEventData.getPassId(); + } + + @Override + public List getInvolvedCompetitors() { + return raceLogEventData.getInvolvedCompetitors(); + } + + @Override + public Serializable getCompetitorId() { + return competitorId; + } +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEventVisitor.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEventVisitor.java index 1912bbe5697..dd6bb4e9054 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEventVisitor.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEventVisitor.java @@ -1,5 +1,6 @@ package com.sap.sailing.domain.abstractlog.race; +import com.sap.sailing.domain.abstractlog.orc.RaceLogORCScratchBoatEvent; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCCertificateAssignmentEvent; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCLegDataEvent; import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent; @@ -60,4 +61,6 @@ public interface RaceLogEventVisitor { void visit(RaceLogORCLegDataEvent event); void visit(RaceLogORCCertificateAssignmentEvent event); + + void visit(RaceLogORCScratchBoatEvent event); } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/AbstractRaceLogChangedVisitor.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/AbstractRaceLogChangedVisitor.java index dde3cafb49a..fb7268cf1e4 100755 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/AbstractRaceLogChangedVisitor.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/AbstractRaceLogChangedVisitor.java @@ -2,6 +2,7 @@ package com.sap.sailing.domain.abstractlog.race.impl; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCCertificateAssignmentEvent; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCLegDataEvent; +import com.sap.sailing.domain.abstractlog.orc.RaceLogORCScratchBoatEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseDesignChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogEndOfTrackingEvent; @@ -156,4 +157,9 @@ public abstract class AbstractRaceLogChangedVisitor implements RaceLogEventVisit public void visit(RaceLogORCCertificateAssignmentEvent event) { notifyListenerAboutEventAdded(event); } + + @Override + public void visit(RaceLogORCScratchBoatEvent event) { + notifyListenerAboutEventAdded(event); + } } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/BaseRaceLogEventVisitor.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/BaseRaceLogEventVisitor.java index 140b5eb1521..119cf8d4349 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/BaseRaceLogEventVisitor.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/BaseRaceLogEventVisitor.java @@ -2,6 +2,7 @@ package com.sap.sailing.domain.abstractlog.race.impl; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCCertificateAssignmentEvent; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCLegDataEvent; +import com.sap.sailing.domain.abstractlog.orc.RaceLogORCScratchBoatEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseDesignChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogEndOfTrackingEvent; @@ -162,4 +163,9 @@ public abstract class BaseRaceLogEventVisitor implements RaceLogEventVisitor { public void visit(RaceLogORCCertificateAssignmentEvent event) { } + + @Override + public void visit(RaceLogORCScratchBoatEvent event) { + + } } \ No newline at end of file diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/orc/TestORCRankingMetricCollaborationWithRaceLogAndRegattaLog.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/orc/TestORCRankingMetricCollaborationWithRaceLogAndRegattaLog.java index 7528e3d6f48..31ae72e87f5 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/orc/TestORCRankingMetricCollaborationWithRaceLogAndRegattaLog.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/orc/TestORCRankingMetricCollaborationWithRaceLogAndRegattaLog.java @@ -154,7 +154,7 @@ public class TestORCRankingMetricCollaborationWithRaceLogAndRegattaLog { assertTrue(leg instanceof ORCPerformanceCurveLegAdapter); // only adapters, no explicit leg specification anymore } } - + @Test public void testHigherPriorityLegDefinitionInRaceLogWins() throws NotRevokableException { attachRaceLog(); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceColumnRaceLogReplicator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceColumnRaceLogReplicator.java index 04d6ca9fcf4..9a70d014c1f 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceColumnRaceLogReplicator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceColumnRaceLogReplicator.java @@ -4,6 +4,7 @@ import java.io.Serializable; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCCertificateAssignmentEvent; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCLegDataEvent; +import com.sap.sailing.domain.abstractlog.orc.RaceLogORCScratchBoatEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseDesignChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogEndOfTrackingEvent; @@ -180,4 +181,9 @@ public class RaceColumnRaceLogReplicator implements RaceLogEventVisitor, Seriali public void visit(RaceLogORCCertificateAssignmentEvent event) { notifyOnAdd(event); } + + @Override + public void visit(RaceLogORCScratchBoatEvent event) { + notifyOnAdd(event); + } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/orc/impl/ORCPerformanceCurveRankingMetric.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/orc/impl/ORCPerformanceCurveRankingMetric.java index 0c9cb4f1a1a..fed261cf86e 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/orc/impl/ORCPerformanceCurveRankingMetric.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/orc/impl/ORCPerformanceCurveRankingMetric.java @@ -14,16 +14,16 @@ import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MaxIterationsExceededException; import com.sap.sailing.domain.abstractlog.orc.ORCCertificateAssignmentEvent; -import com.sap.sailing.domain.abstractlog.orc.ORCScratchBoatEvent; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCCertificateAssignmentEvent; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCCertificateAssignmentFinder; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCLegDataAnalyzer; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCLegDataEvent; +import com.sap.sailing.domain.abstractlog.orc.RaceLogORCScratchBoatEvent; +import com.sap.sailing.domain.abstractlog.orc.RaceLogORCScratchBoatFinder; import com.sap.sailing.domain.abstractlog.orc.RegattaLogORCCertificateAssignmentEvent; import com.sap.sailing.domain.abstractlog.orc.RegattaLogORCCertificateAssignmentFinder; import com.sap.sailing.domain.abstractlog.orc.impl.RaceLogORCLegDataEventImpl; import com.sap.sailing.domain.abstractlog.race.RaceLog; -import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor; import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent; import com.sap.sailing.domain.abstractlog.race.impl.BaseRaceLogEventVisitor; @@ -69,10 +69,18 @@ public class ORCPerformanceCurveRankingMetric extends AbstractRankingMetric { private final Map boatsById; + private final Map competitorsById; + private final RaceLogEventVisitor certificatesFromRaceLogUpdater; private final RegattaLogEventVisitor certificatesFromRegattaLogUpdater; + /** + * Updated by an observer pattern that watches all {@link RaceLog}s {@link TrackedRace#getAttachedRaceLogs() attached} to the + * {@link #getTrackedRace() tracked race} for occurrence and revocations of {@link RaceLogORCScratchBoatEvent}s. + */ + private Competitor explicitScratchBoat; + /** * TODO maybe it's a good idea to cache the {@link ORCPerformanceCurve} objects and implied wind speeds for all competitors involved in this object which serves as some sort of cache for ranking calculations for a single time point * @@ -86,14 +94,15 @@ public class ORCPerformanceCurveRankingMetric extends AbstractRankingMetric { * Uses the {@link ORCPerformanceCurveRankingMetric#getScratchBoat(TimePoint) scratch boat} as the "boat * farthest ahead." The default scratch boat is defined as such but may be overridden explicitly. */ - public ORCPerformanceCurveRankingInfo(TimePoint timePoint, Map competitorRankingInfo) { - super(timePoint, competitorRankingInfo, getScratchBoat(timePoint)); + public ORCPerformanceCurveRankingInfo(TimePoint timePoint, Map competitorRankingInfo, WindLegTypeAndLegBearingCache cache) { + super(timePoint, competitorRankingInfo, getScratchBoat(timePoint, cache)); } } public ORCPerformanceCurveRankingMetric(TrackedRace trackedRace) { super(trackedRace); boatsById = initBoatsById(); + competitorsById = initCompetitorsById(); updateCertificatesFromLogs(); updateCourseFromRaceLogs(); certificatesFromRaceLogUpdater = createCertificatesFromRaceLogAndCourseUpdater(); @@ -110,12 +119,14 @@ public class ORCPerformanceCurveRankingMetric extends AbstractRankingMetric { public void raceLogAttached(RaceLog raceLog) { raceLog.addListener(certificatesFromRaceLogUpdater); updateCertificatesFromLogs(); + updateScratchBoatFromLogs(); } @Override public void raceLogDetached(RaceLog raceLog) { raceLog.removeListener(certificatesFromRaceLogUpdater); updateCertificatesFromLogs(); + updateScratchBoatFromLogs(); } }); } @@ -135,6 +146,16 @@ public class ORCPerformanceCurveRankingMetric extends AbstractRankingMetric { return result; } + private Map initCompetitorsById() { + final Map result = new HashMap<>(); + if (getTrackedRace() != null) { + for (final Competitor competitor : getTrackedRace().getTrackedRegatta().getRegatta().getAllCompetitors()) { + result.put(competitor.getId(), competitor); + } + } + return result; + } + private RaceLogEventVisitor createCertificatesFromRaceLogAndCourseUpdater() { return new BaseRaceLogEventVisitor() { @Override @@ -165,6 +186,21 @@ public class ORCPerformanceCurveRankingMetric extends AbstractRankingMetric { }; } + /** + * For now, we assume that there is only one scratch boat defined for this race and that it's independent of the + * pass. We pick the last ("greatest") valid event of type {@link RaceLogORCScratchBoatEvent}. + */ + private void updateScratchBoatFromLogs() { + Competitor scratchBoatFromLog = null; + for (final RaceLog raceLog : getTrackedRace().getAttachedRaceLogs()) { + scratchBoatFromLog = new RaceLogORCScratchBoatFinder(raceLog, competitorsById).analyze(); + if (scratchBoatFromLog != null) { + break; + } + } + explicitScratchBoat = scratchBoatFromLog; + } + /** * To be called if the set of logs attached to the {@link #getTrackedRace() tracked race} changes or any of those * logs sees a {@link ORCCertificateAssignmentEvent} being added. As a result, the {@link #certificates} map is @@ -235,15 +271,19 @@ public class ORCPerformanceCurveRankingMetric extends AbstractRankingMetric { * By default, we use the boat farthest ahead ("first ship home" when the race has finished) as the scratch boat, * but other definitions are possible, such as greatest {@link ORCCertificate#getGPH() GPH value} or least * {@link ORCCertificate#getCDL() CDL value}. An explicit selection can be made using the - * {@link ORCScratchBoatEvent} in the {@link RaceLog}. The event's {@link RaceLogEvent#getLogicalTimePoint() logical - * time point} determines starting when the {@link ORCScratchBoatEvent#getCompetitorId() scratch boat identified by - * the competitor ID in the event} shall be used. - * - * TODO really use the logical time point? Can the scratch boat change across the race duration? + * {@link RaceLogORCScratchBoatEvent} in the {@link RaceLog}. The last unrevoked event in the first {@link RaceLog} + * in which one is found is used. Only if none of the attached {@link RaceLog}s contains any unrevoked such event, + * the scratch boat is selected implicitly to be the boat farthest ahead (see + * {@link #getCompetitorFarthestAhead(TimePoint, WindLegTypeAndLegBearingCache)}). */ - private Competitor getScratchBoat(TimePoint timePoint) { - // TODO Implement ORCPerformanceCurveRankingMetric.getScratchBoat(...) - return null; + private Competitor getScratchBoat(TimePoint timePoint, WindLegTypeAndLegBearingCache cache) { + final Competitor result; + if (explicitScratchBoat != null) { + result = explicitScratchBoat; + } else { + result = getCompetitorFarthestAhead(timePoint, cache); + } + return result; } /** @@ -365,7 +405,7 @@ public class ORCPerformanceCurveRankingMetric extends AbstractRankingMetric { @Override public Duration getCorrectedTime(Competitor competitor, TimePoint timePoint, WindLegTypeAndLegBearingCache cache) { Duration result = null; - final Competitor scratchBoat = getScratchBoat(timePoint); + final Competitor scratchBoat = getScratchBoat(timePoint, cache); if (competitor == scratchBoat) { // the scratch boat's corrected time is its own time sailed result = getTrackedRace().getTimeSailedSinceRaceStart(competitor, timePoint); @@ -439,7 +479,7 @@ public class ORCPerformanceCurveRankingMetric extends AbstractRankingMetric { correctedTime)); } } - return new ORCPerformanceCurveRankingInfo(timePoint, competitorRankingInfo); + return new ORCPerformanceCurveRankingInfo(timePoint, competitorRankingInfo, cache); } /** diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/ranking/AbstractRankingMetric.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/ranking/AbstractRankingMetric.java index 15a2dee964c..d1809cd4384 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/ranking/AbstractRankingMetric.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/ranking/AbstractRankingMetric.java @@ -2,6 +2,7 @@ package com.sap.sailing.domain.ranking; import java.util.ArrayList; import java.util.Comparator; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -9,6 +10,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.function.Function; import java.util.function.Supplier; +import java.util.stream.StreamSupport; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Course; @@ -23,6 +25,7 @@ import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingCache; import com.sap.sailing.domain.tracking.WindPositionMode; +import com.sap.sailing.domain.tracking.impl.AbstractRaceRankComparator; import com.sap.sse.common.Distance; import com.sap.sse.common.Duration; import com.sap.sse.common.Speed; @@ -233,6 +236,14 @@ public abstract class AbstractRankingMetric implements RankingMetric { return trackedRace; } + protected Competitor getCompetitorFarthestAhead(TimePoint timePoint, WindLegTypeAndLegBearingCache cache) { + Comparator oneDesignComparator = getWindwardDistanceTraveledComparator(timePoint, cache); + Competitor competitorFarthestAhead = StreamSupport + .stream(getCompetitors().spliterator(), /* parallel */true). + sorted(oneDesignComparator).findFirst().get(); + return competitorFarthestAhead; + } + /** * The time from the {@link TrackedRace#getStartOfRace() race start} until timePoint or until * the point in time when competitor passed the finish mark, whichever comes first. If there is @@ -391,6 +402,25 @@ public abstract class AbstractRankingMetric implements RankingMetric { return getWindwardDistanceTraveled(competitor, getTrackedRace().getRace().getCourse().getFirstWaypoint(), timePoint, cache); } + /** + * Constructs a comparator based on the results of + * {@link #getWindwardDistanceTraveled(Competitor, TimePoint, WindLegTypeAndLegBearingCache)} where competitors are + * "less" than other competitors ("better") if they are in a later leg or, if in the same leg, have a greater + * windward distance traveled. If both competitors have already finished the race, the finishing time is compared. + */ + private Comparator getWindwardDistanceTraveledComparator(final TimePoint timePoint, final WindLegTypeAndLegBearingCache cache) { + final Map windwardDistanceTraveledPerCompetitor = new HashMap<>(); + for (final Competitor competitor : getCompetitors()) { + windwardDistanceTraveledPerCompetitor.put(competitor, getWindwardDistanceTraveled(competitor, timePoint, cache)); + } + return new AbstractRaceRankComparator(getTrackedRace(), timePoint, /* lessIsBetter */ false) { + @Override + protected Distance getComparisonValueForSameLeg(Competitor competitor) { + return windwardDistanceTraveledPerCompetitor.get(competitor); + } + }; + } + /** * How far did competitor sail windwards/along-course since passing the from waypoint? * For each leg the total windward distance sailed is limited to the leg's windward distance at its diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/ranking/NonPerformanceCurveRankingMetric.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/ranking/NonPerformanceCurveRankingMetric.java index 481b0cf697f..7ff1242d5c2 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/ranking/NonPerformanceCurveRankingMetric.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/ranking/NonPerformanceCurveRankingMetric.java @@ -4,7 +4,6 @@ import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.function.Function; -import java.util.stream.StreamSupport; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Leg; @@ -13,7 +12,6 @@ import com.sap.sailing.domain.tracking.MarkPassing; import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingCache; -import com.sap.sailing.domain.tracking.impl.AbstractRaceRankComparator; import com.sap.sse.common.Distance; import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; @@ -59,31 +57,9 @@ public abstract class NonPerformanceCurveRankingMetric extends AbstractRankingMe super(trackedRace); } - /** - * Constructs a comparator based on the results of - * {@link #getWindwardDistanceTraveled(Competitor, TimePoint, WindLegTypeAndLegBearingCache)} where competitors are - * "less" than other competitors ("better") if they are in a later leg or, if in the same leg, have a greater - * windward distance traveled. If both competitors have already finished the race, the finishing time is compared. - */ - private Comparator getWindwardDistanceTraveledComparator(final TimePoint timePoint, final WindLegTypeAndLegBearingCache cache) { - final Map windwardDistanceTraveledPerCompetitor = new HashMap<>(); - for (final Competitor competitor : getCompetitors()) { - windwardDistanceTraveledPerCompetitor.put(competitor, getWindwardDistanceTraveled(competitor, timePoint, cache)); - } - return new AbstractRaceRankComparator(getTrackedRace(), timePoint, /* lessIsBetter */ false) { - @Override - protected Distance getComparisonValueForSameLeg(Competitor competitor) { - return windwardDistanceTraveledPerCompetitor.get(competitor); - } - }; - } - public RankingMetric.RankingInfo getRankingInfo(TimePoint timePoint, WindLegTypeAndLegBearingCache cache) { Map result = new HashMap<>(); - Comparator oneDesignComparator = getWindwardDistanceTraveledComparator(timePoint, cache); - Competitor competitorFarthestAhead = StreamSupport - .stream(getCompetitors().spliterator(), /* parallel */true). - sorted(oneDesignComparator).findFirst().get(); + Competitor competitorFarthestAhead = getCompetitorFarthestAhead(timePoint, cache); final Distance totalWindwardDistanceTraveled = getWindwardDistanceTraveled(competitorFarthestAhead, timePoint, cache); final TimePoint startOfRace = getTrackedRace().getStartOfRace(); if (startOfRace != null) { @@ -115,7 +91,7 @@ public abstract class NonPerformanceCurveRankingMetric extends AbstractRankingMe } return new NonPerformanceCurveRankingInfoImpl(timePoint, result, competitorFarthestAhead); } - + /** * Predicts how long who will take to reach competitor to's position at * timePoint, starting at who's position at timePoint, assuming a continued diff --git a/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/racelog/impl/RaceLogEventDeserializer.java b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/racelog/impl/RaceLogEventDeserializer.java index b1abf0f7107..fdfde5125b7 100755 --- a/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/racelog/impl/RaceLogEventDeserializer.java +++ b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/racelog/impl/RaceLogEventDeserializer.java @@ -89,7 +89,8 @@ public class RaceLogEventDeserializer implements JsonDeserializer new RaceLogUseCompetitorsFromRaceLogEventDeserializer(competitorDeserializer), new RaceLogEndOfTrackingEventDeserializer(competitorDeserializer), new RaceLogTagEventDeserializer(competitorDeserializer), - new RaceLogORCLegDataEventDeserializer(competitorDeserializer)); + new RaceLogORCLegDataEventDeserializer(competitorDeserializer), + new RaceLogORCScratchBoatEventDeserializer(competitorDeserializer)); } protected final JsonDeserializer flagEventDeserializer; @@ -117,6 +118,7 @@ public class RaceLogEventDeserializer implements JsonDeserializer protected final JsonDeserializer endOfTrackingDeserializer; protected final JsonDeserializer tagEventDeserializer; protected final JsonDeserializer orcLegDataEventDeserializer; + protected final JsonDeserializer orcScratchBoatEventDeserializer; public RaceLogEventDeserializer(JsonDeserializer flagEventDeserializer, JsonDeserializer startTimeEventDeserializer, @@ -141,7 +143,9 @@ public class RaceLogEventDeserializer implements JsonDeserializer JsonDeserializer startOfTrackingEventDeserializer, JsonDeserializer useCompetitorsFromRaceLogDeserializer, JsonDeserializer endOfTrackingEventDeserializer, - JsonDeserializer tagEventDeserializer, JsonDeserializer orcLegDataEventDeserializer) { + JsonDeserializer tagEventDeserializer, + JsonDeserializer orcLegDataEventDeserializer, + JsonDeserializer orcScratchBoatEventDeserializer) { this.flagEventDeserializer = flagEventDeserializer; this.startTimeEventDeserializer = startTimeEventDeserializer; this.dependentStartTimeEventDeserializer = dependentStartTimeEventDeserializer; @@ -167,6 +171,7 @@ public class RaceLogEventDeserializer implements JsonDeserializer this.useCompetitorsFromRaceLogDeserializer = useCompetitorsFromRaceLogDeserializer; this.tagEventDeserializer = tagEventDeserializer; this.orcLegDataEventDeserializer = orcLegDataEventDeserializer; + this.orcScratchBoatEventDeserializer = orcScratchBoatEventDeserializer; } protected JsonDeserializer getDeserializer(JSONObject object) throws JsonDeserializationException { diff --git a/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/racelog/impl/RaceLogORCCertificateAssignmentEventDeserializer.java b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/racelog/impl/RaceLogORCCertificateAssignmentEventDeserializer.java index bc6e89b1198..2120beadb4f 100755 --- a/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/racelog/impl/RaceLogORCCertificateAssignmentEventDeserializer.java +++ b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/racelog/impl/RaceLogORCCertificateAssignmentEventDeserializer.java @@ -15,6 +15,7 @@ import com.sap.sailing.server.gateway.deserialization.JsonDeserializationExcepti import com.sap.sailing.server.gateway.deserialization.JsonDeserializer; import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogORCCertificateAssignmentEventSerializer; import com.sap.sse.common.TimePoint; +import com.sap.sse.util.impl.UUIDHelper; /** * Deserializer for {@link com.sap.sailing.domain.abstractlog.orc.RaceLogORCLegDataEvent ORCLegDataEvent}. @@ -33,7 +34,8 @@ public class RaceLogORCCertificateAssignmentEventDeserializer extends BaseRaceLo AbstractLogEventAuthor author, TimePoint timePoint, int passId, List competitors) throws JsonDeserializationException { final ORCCertificate certificate = new ORCCertificateJsonDeserializer().deserialize((JSONObject) object.get(RaceLogORCCertificateAssignmentEventSerializer.ORC_CERTIFICATE)); - final Serializable boatId = (Serializable) object.get(RaceLogORCCertificateAssignmentEventSerializer.ORC_BOAT_ID); + Serializable boatId = (Serializable) object.get(RaceLogORCCertificateAssignmentEventSerializer.ORC_BOAT_ID); + boatId = UUIDHelper.tryUuidConversion(boatId); return new RaceLogORCCertificateAssignmentEventImpl(createdAt, timePoint, author, id, passId, certificate, boatId); } diff --git a/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/racelog/impl/RaceLogORCScratchBoatEventDeserializer.java b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/racelog/impl/RaceLogORCScratchBoatEventDeserializer.java new file mode 100755 index 00000000000..e7bc0caae8c --- /dev/null +++ b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/racelog/impl/RaceLogORCScratchBoatEventDeserializer.java @@ -0,0 +1,38 @@ +package com.sap.sailing.server.gateway.deserialization.racelog.impl; + +import java.io.Serializable; +import java.util.List; + +import org.json.simple.JSONObject; + +import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; +import com.sap.sailing.domain.abstractlog.orc.impl.RaceLogORCScratchBoatEventImpl; +import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.impl.DynamicCompetitor; +import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException; +import com.sap.sailing.server.gateway.deserialization.JsonDeserializer; +import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogORCScratchBoatEventSerializer; +import com.sap.sse.common.TimePoint; +import com.sap.sse.util.impl.UUIDHelper; + +/** + * Deserializer for {@link com.sap.sailing.domain.abstractlog.orc.RaceLogORCLegDataEvent ORCLegDataEvent}. + * + * @author Daniel Lisunkin (I505543) + */ +public class RaceLogORCScratchBoatEventDeserializer extends BaseRaceLogEventDeserializer { + + public RaceLogORCScratchBoatEventDeserializer(JsonDeserializer competitorDeserializer) { + super(competitorDeserializer); + } + + @Override + protected RaceLogEvent deserialize(JSONObject object, Serializable id, TimePoint createdAt, + AbstractLogEventAuthor author, TimePoint timePoint, int passId, List competitors) + throws JsonDeserializationException { + Serializable competitorId = (Serializable) object.get(RaceLogORCScratchBoatEventSerializer.ORC_COMPETITOR_ID); + competitorId = UUIDHelper.tryUuidConversion(competitorId); + return new RaceLogORCScratchBoatEventImpl(createdAt, timePoint, author, id, passId, competitorId); + } +} diff --git a/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/racelog/impl/RaceLogEventSerializer.java b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/racelog/impl/RaceLogEventSerializer.java index b9ce7846236..58befcb4304 100644 --- a/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/racelog/impl/RaceLogEventSerializer.java +++ b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/racelog/impl/RaceLogEventSerializer.java @@ -4,6 +4,7 @@ import org.json.simple.JSONObject; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCCertificateAssignmentEvent; import com.sap.sailing.domain.abstractlog.orc.RaceLogORCLegDataEvent; +import com.sap.sailing.domain.abstractlog.orc.RaceLogORCScratchBoatEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseDesignChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogEndOfTrackingEvent; @@ -86,7 +87,8 @@ public class RaceLogEventSerializer implements JsonSerializer, Rac new RaceLogEndOfTrackingEventSerializer(competitorSerializer), new RaceLogTagEventSerializer(competitorSerializer), new RaceLogORCLegDataEventSerializer(competitorSerializer), - new RaceLogORCCertificateAssignmentEventSerializer(competitorSerializer)); + new RaceLogORCCertificateAssignmentEventSerializer(competitorSerializer), + new RaceLogORCScratchBoatEventSerializer(competitorSerializer)); } private final JsonSerializer flagEventSerializer; @@ -115,6 +117,7 @@ public class RaceLogEventSerializer implements JsonSerializer, Rac private final JsonSerializer tagSerializer; private final JsonSerializer orcLegDataEventSerializer; private final JsonSerializer orcCertificateAssignmentEventSerializer; + private final JsonSerializer orcScratchBoatEventSerializer; private JsonSerializer chosenSerializer; @@ -145,7 +148,8 @@ public class RaceLogEventSerializer implements JsonSerializer, Rac JsonSerializer endOfTrackingEventSerializer, JsonSerializer tagSerializer, JsonSerializer orcLegDataEventSerializer, - JsonSerializer orcCertificateAssignmentEventSerializer) { + JsonSerializer orcCertificateAssignmentEventSerializer, + JsonSerializer orcScratchBoatEventSerializer) { this.flagEventSerializer = flagEventSerializer; this.startTimeSerializer = startTimeSerializer; this.raceStatusSerializer = raceStatusSerializer; @@ -172,6 +176,7 @@ public class RaceLogEventSerializer implements JsonSerializer, Rac this.tagSerializer = tagSerializer; this.orcLegDataEventSerializer = orcLegDataEventSerializer; this.orcCertificateAssignmentEventSerializer = orcCertificateAssignmentEventSerializer; + this.orcScratchBoatEventSerializer = orcScratchBoatEventSerializer; this.chosenSerializer = null; } @@ -318,4 +323,9 @@ public class RaceLogEventSerializer implements JsonSerializer, Rac public void visit(RaceLogORCCertificateAssignmentEvent event) { chosenSerializer = orcCertificateAssignmentEventSerializer; } + + @Override + public void visit(RaceLogORCScratchBoatEvent event) { + chosenSerializer = orcScratchBoatEventSerializer; + } } diff --git a/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/racelog/impl/RaceLogORCCertificateAssignmentEventSerializer.java b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/racelog/impl/RaceLogORCCertificateAssignmentEventSerializer.java index 2cddbec3780..1fddaf29253 100755 --- a/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/racelog/impl/RaceLogORCCertificateAssignmentEventSerializer.java +++ b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/racelog/impl/RaceLogORCCertificateAssignmentEventSerializer.java @@ -28,7 +28,7 @@ public class RaceLogORCCertificateAssignmentEventSerializer extends BaseRaceLogE RaceLogORCCertificateAssignmentEvent certificateAssignmentEvent = (RaceLogORCCertificateAssignmentEvent) object; JSONObject result = super.serialize(certificateAssignmentEvent); result.put(ORC_CERTIFICATE, new ORCCertificateJsonSerializer().serialize(certificateAssignmentEvent.getCertificate())); - result.put(ORC_BOAT_ID, certificateAssignmentEvent.getBoatId()); + result.put(ORC_BOAT_ID, certificateAssignmentEvent.getBoatId().toString()); return result; } diff --git a/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/racelog/impl/RaceLogORCScratchBoatEventSerializer.java b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/racelog/impl/RaceLogORCScratchBoatEventSerializer.java new file mode 100755 index 00000000000..1ac9e742654 --- /dev/null +++ b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/racelog/impl/RaceLogORCScratchBoatEventSerializer.java @@ -0,0 +1,38 @@ +package com.sap.sailing.server.gateway.serialization.racelog.impl; + +import org.json.simple.JSONObject; + +import com.sap.sailing.domain.abstractlog.orc.RaceLogORCScratchBoatEvent; +import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.server.gateway.serialization.JsonSerializer; + +/** + * Serializer for {@link com.sap.sailing.domain.abstractlog.orc.RaceLogORCLegDataEvent ORCLegDataEvent}. + * + * @author Daniel Lisunkin (i505543) + * @author Axel Uhl (d043530) + */ +public class RaceLogORCScratchBoatEventSerializer extends BaseRaceLogEventSerializer { + + public static final String VALUE_CLASS = RaceLogORCScratchBoatEvent.class.getSimpleName(); + public static final String ORC_CERTIFICATE = "certificate"; + public static final String ORC_COMPETITOR_ID = "competitorId"; + + public RaceLogORCScratchBoatEventSerializer(JsonSerializer competitorSerializer) { + super(competitorSerializer); + } + + @Override + public JSONObject serialize(RaceLogEvent object) { + RaceLogORCScratchBoatEvent scratchBoatEvent = (RaceLogORCScratchBoatEvent) object; + JSONObject result = super.serialize(scratchBoatEvent); + result.put(ORC_COMPETITOR_ID, scratchBoatEvent.getCompetitorId().toString()); + return result; + } + + @Override + protected String getClassFieldValue() { + return VALUE_CLASS; + } +} diff --git a/java/com.sap.sailing.server.gateway.serialization.test/src/com/sap/sailing/server/gateway/deserialization/test/racelog/RaceLogEventDeserializerTest.java b/java/com.sap.sailing.server.gateway.serialization.test/src/com/sap/sailing/server/gateway/deserialization/test/racelog/RaceLogEventDeserializerTest.java index c2458609b8d..1c110082d53 100644 --- a/java/com.sap.sailing.server.gateway.serialization.test/src/com/sap/sailing/server/gateway/deserialization/test/racelog/RaceLogEventDeserializerTest.java +++ b/java/com.sap.sailing.server.gateway.serialization.test/src/com/sap/sailing/server/gateway/deserialization/test/racelog/RaceLogEventDeserializerTest.java @@ -48,7 +48,9 @@ public class RaceLogEventDeserializerTest { super(mockitoRaceLogFlagEventDeserializer, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, mockitoRaceLogUseCompetitorsFromRaceLogEventDeserializer, - mockitoRaceLogEndOfTrackingEventDeserializer, mockitoRaceLogTagEventDeserializer, new RaceLogORCLegDataEventDeserializer(competitorDeserializer)); + mockitoRaceLogEndOfTrackingEventDeserializer, mockitoRaceLogTagEventDeserializer, + new RaceLogORCLegDataEventDeserializer(competitorDeserializer), + null); } } diff --git a/java/com.sap.sailing.server.gateway.serialization.test/src/com/sap/sailing/server/gateway/serialization/test/racelog/RaceLogEventSerializerTest.java b/java/com.sap.sailing.server.gateway.serialization.test/src/com/sap/sailing/server/gateway/serialization/test/racelog/RaceLogEventSerializerTest.java index 2715ed03d51..8726ccc9681 100644 --- a/java/com.sap.sailing.server.gateway.serialization.test/src/com/sap/sailing/server/gateway/serialization/test/racelog/RaceLogEventSerializerTest.java +++ b/java/com.sap.sailing.server.gateway.serialization.test/src/com/sap/sailing/server/gateway/serialization/test/racelog/RaceLogEventSerializerTest.java @@ -73,6 +73,7 @@ public class RaceLogEventSerializerTest { private JsonSerializer tagEventSerializer; private JsonSerializer orcLegDataEventSerializer; private JsonSerializer orcCertificateAssignmentEventSerializer; + private JsonSerializer orcScratchBoatEventSerializer; private AbstractLogEventAuthor author = new LogEventAuthorImpl("Test Author", 1); @@ -106,6 +107,8 @@ public class RaceLogEventSerializerTest { tagEventSerializer = mock(JsonSerializer.class); orcLegDataEventSerializer = mock(JsonSerializer.class); orcCertificateAssignmentEventSerializer = mock(JsonSerializer.class); + orcScratchBoatEventSerializer = mock(JsonSerializer.class); + serializer = new RaceLogEventSerializer(flagEventSerializer, startTimeSerializer, raceStatusSerializer, passChangedSerializer, courseDesignChangedEventSerializer, finishPositioningListChangedEventSerializer, finishPositioningConfirmedEventSerializer, @@ -117,7 +120,7 @@ public class RaceLogEventSerializerTest { additionalScoringInformationSerializer, dependentStartTimeEventSerializer, startOfTrackingEventSerializer, useCompetitorsFromRaceLogEventSerializer, endOfTrackingEventSerializer, tagEventSerializer, orcLegDataEventSerializer, - orcCertificateAssignmentEventSerializer); + orcCertificateAssignmentEventSerializer, orcScratchBoatEventSerializer); } @Test