mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-14 22:43:57 +00:00
Merge branch 'master' into bug4811-with-bug5288
This commit is contained in:
commit
8a87532483
33 files changed
+362
-48
No files matched your search
+10
@@ -72,6 +72,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogPassChangeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogPathfinderEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogProtestStartTimeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogResultsAreOfficialEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogStartProcedureChangedEvent;
|
||||
@@ -95,6 +96,7 @@ import com.sap.sailing.domain.abstractlog.race.impl.RaceLogPassChangeEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogPathfinderEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogProtestStartTimeEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogRaceStatusEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogResultsAreOfficialEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogRevokeEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartOfTrackingEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartProcedureChangedEventImpl;
|
||||
@@ -1661,6 +1663,8 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
resultEvent = loadRaceLogORCScratchBoatEvent(createdAt, author, logicalTimePoint, id, passId, competitors, dbObject);
|
||||
} else if (eventClass.equals(RaceLogORCImpliedWindSourceEvent.class.getSimpleName())) {
|
||||
resultEvent = loadRaceLogORCSetImpliedWindEvent(createdAt, author, logicalTimePoint, id, passId, competitors, dbObject);
|
||||
} else if (eventClass.equals(RaceLogResultsAreOfficialEvent.class.getSimpleName())) {
|
||||
resultEvent = loadRaceLogResultsAreOfficialEvent(createdAt, author, logicalTimePoint, id, passId, competitors, dbObject);
|
||||
} else {
|
||||
throw new IllegalStateException(String.format("Unknown RaceLogEvent type %s", eventClass));
|
||||
}
|
||||
@@ -1686,6 +1690,12 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
}
|
||||
return new RaceLogORCImpliedWindSourceEventImpl(createdAt, logicalTimePoint, author, id, passId, impliedWindSource);
|
||||
}
|
||||
|
||||
private RaceLogEvent loadRaceLogResultsAreOfficialEvent(TimePoint createdAt,
|
||||
AbstractLogEventAuthor author, TimePoint logicalTimePoint, Serializable id, Integer passId,
|
||||
List<Competitor> competitors, Document dbObject) throws JsonDeserializationException, ParseException {
|
||||
return new RaceLogResultsAreOfficialEventImpl(createdAt, logicalTimePoint, author, id, passId);
|
||||
}
|
||||
|
||||
private RaceLogEvent loadRaceLogUseCompetitorsFromRaceLogEvent(TimePoint createdAt, AbstractLogEventAuthor author,
|
||||
TimePoint logicalTimePoint, Serializable id, Integer passId, List<Competitor> competitors,
|
||||
|
||||
+16
@@ -53,6 +53,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogPassChangeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogPathfinderEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogProtestStartTimeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogResultsAreOfficialEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogStartProcedureChangedEvent;
|
||||
@@ -940,6 +941,13 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogWindFix(event));
|
||||
return result;
|
||||
}
|
||||
|
||||
public Document storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogResultsAreOfficialEvent event) {
|
||||
Document result = new Document();
|
||||
storeRaceLogIdentifier(raceLogIdentifier, result);
|
||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogResultsAreOfficialEvent(event));
|
||||
return result;
|
||||
}
|
||||
|
||||
public Document storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogDenoteForTrackingEvent event) {
|
||||
Document result = new Document();
|
||||
@@ -1143,6 +1151,14 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
storeTimePoint(event.getToInclusive(), result, toField);
|
||||
}
|
||||
}
|
||||
|
||||
private Object storeRaceLogResultsAreOfficialEvent(RaceLogResultsAreOfficialEvent event) {
|
||||
Document result = new Document();
|
||||
storeRaceLogEventProperties(event, result);
|
||||
result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RaceLogResultsAreOfficialEvent.class.getSimpleName());
|
||||
// currently there are no further properties; the event speaks for itself
|
||||
return result;
|
||||
}
|
||||
|
||||
private Object storeRaceLogDenoteForTrackingEvent(RaceLogDenoteForTrackingEvent event) {
|
||||
Document result = new Document();
|
||||
|
||||
+7
@@ -21,6 +21,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogPassChangeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogPathfinderEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogProtestStartTimeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogResultsAreOfficialEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogStartProcedureChangedEvent;
|
||||
@@ -216,4 +217,10 @@ public class MongoRaceLogStoreVisitor implements RaceLogEventVisitor {
|
||||
Document object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
|
||||
mongoObjectFactory.storeRaceLogEventEvent(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RaceLogResultsAreOfficialEvent event) {
|
||||
Document object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
|
||||
mongoObjectFactory.storeRaceLogEventEvent(object);
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.sap.sailing.domain.racelog.analyzing.test;
|
||||
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogResultsAreOfficialEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.ResultsAreOfficialFinder;
|
||||
|
||||
public class ResultsAreOfficialFinderTest extends RaceLogAnalyzerTest<ResultsAreOfficialFinder> {
|
||||
@Override
|
||||
protected ResultsAreOfficialFinder createAnalyzer(RaceLog raceLog) {
|
||||
return new ResultsAreOfficialFinder(raceLog);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFalseForNoResultsAreOfficialEvent() {
|
||||
RaceLogEvent event1 = createEvent(RaceLogEvent.class, 1);
|
||||
raceLog.add(event1);
|
||||
assertNull(analyzer.analyze());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleLast() {
|
||||
RaceLogResultsAreOfficialEvent event1 = createEvent(RaceLogResultsAreOfficialEvent.class, 1);
|
||||
RaceLogResultsAreOfficialEvent event2 = createEvent(RaceLogResultsAreOfficialEvent.class, 2);
|
||||
raceLog.add(event1);
|
||||
raceLog.add(event2);
|
||||
RaceLogResultsAreOfficialEvent result = analyzer.analyze();
|
||||
assertSame(event2, result);
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -197,11 +197,15 @@ public class RaceStateTest {
|
||||
|
||||
@Test
|
||||
public void testGetRacingProcedure() throws InterruptedException {
|
||||
|
||||
state.setRacingProcedure(nowMock, RacingProcedureType.RRS26);
|
||||
|
||||
GateStartRacingProcedure procedure = state.getTypedRacingProcedure(GateStartRacingProcedure.class);
|
||||
assertNull(procedure);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResultsAreOfficial() {
|
||||
assertFalse(state.isResultsAreOfficial());
|
||||
state.setResultsAreOfficial(TimePoint.now());
|
||||
assertTrue(state.isResultsAreOfficial());
|
||||
}
|
||||
}
|
||||
+2
@@ -66,4 +66,6 @@ public interface RaceLogEventVisitor {
|
||||
void visit(RaceLogORCScratchBoatEvent event);
|
||||
|
||||
void visit(RaceLogORCImpliedWindSourceEvent event);
|
||||
|
||||
void visit(RaceLogResultsAreOfficialEvent event);
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package com.sap.sailing.domain.abstractlog.race;
|
||||
|
||||
public interface RaceLogResultsAreOfficialEvent extends RaceLogEvent {
|
||||
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.sap.sailing.domain.abstractlog.race.analyzing.impl;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogResultsAreOfficialEvent;
|
||||
|
||||
/**
|
||||
* Analysis returns the most recent {@link RaceLogResultsAreOfficialEvent}.
|
||||
* <p>
|
||||
*
|
||||
* If there is no {@link RaceLogResultsAreOfficialEvent} in log, <code>null</code> is returned. Otherwise a single
|
||||
* {@link RaceLogResultsAreOfficialEvent} is returned.
|
||||
*
|
||||
*/
|
||||
public class ResultsAreOfficialFinder extends RaceLogAnalyzer<RaceLogResultsAreOfficialEvent> {
|
||||
|
||||
public ResultsAreOfficialFinder(RaceLog raceLog) {
|
||||
super(raceLog);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RaceLogResultsAreOfficialEvent performAnalysis() {
|
||||
for (final RaceLogEvent e : getAllEventsDescending()) {
|
||||
if (e instanceof RaceLogResultsAreOfficialEvent) {
|
||||
return (RaceLogResultsAreOfficialEvent) e;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+6
@@ -18,6 +18,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogPassChangeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogPathfinderEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogProtestStartTimeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogResultsAreOfficialEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogStartProcedureChangedEvent;
|
||||
@@ -168,4 +169,9 @@ public abstract class AbstractRaceLogChangedVisitor implements RaceLogEventVisit
|
||||
public void visit(RaceLogORCImpliedWindSourceEvent event) {
|
||||
notifyListenerAboutEventAdded(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RaceLogResultsAreOfficialEvent event) {
|
||||
notifyListenerAboutEventAdded(event);
|
||||
}
|
||||
}
|
||||
+6
@@ -17,6 +17,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogPassChangeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogPathfinderEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogProtestStartTimeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogResultsAreOfficialEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogStartProcedureChangedEvent;
|
||||
@@ -174,4 +175,9 @@ public abstract class BaseRaceLogEventVisitor implements RaceLogEventVisitor {
|
||||
public void visit(RaceLogORCImpliedWindSourceEvent event) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RaceLogResultsAreOfficialEvent event) {
|
||||
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.sap.sailing.domain.abstractlog.race.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogResultsAreOfficialEvent;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
public class RaceLogResultsAreOfficialEventImpl extends RaceLogEventImpl implements RaceLogResultsAreOfficialEvent {
|
||||
private static final long serialVersionUID = -1796278009919318553L;
|
||||
|
||||
public RaceLogResultsAreOfficialEventImpl(TimePoint createdAt, TimePoint logicalTimePoint,
|
||||
AbstractLogEventAuthor author, Serializable pId, int pPassId) {
|
||||
super(createdAt, logicalTimePoint, author, pId, pPassId);
|
||||
}
|
||||
|
||||
public RaceLogResultsAreOfficialEventImpl(TimePoint logicalTimePoint, AbstractLogEventAuthor author, int pPassId) {
|
||||
this(now(), logicalTimePoint, author, randId(), pPassId);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void accept(RaceLogEventVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getShortInfo() {
|
||||
return "Indicates that the results of this race are now official";
|
||||
}
|
||||
}
|
||||
+11
-1
@@ -4,6 +4,7 @@ import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||
import com.sap.sailing.domain.abstractlog.race.CompetitorResults;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogResultsAreOfficialEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
|
||||
import com.sap.sailing.domain.abstractlog.race.scoring.AdditionalScoringInformationType;
|
||||
import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent;
|
||||
@@ -146,7 +147,6 @@ public interface RaceState extends ReadonlyRaceState {
|
||||
|
||||
/**
|
||||
* Enters a new wind fix for this race.
|
||||
* @param isMagnetic TODO
|
||||
*/
|
||||
void setWindFix(TimePoint now, Wind wind, boolean isMagnetic);
|
||||
|
||||
@@ -162,4 +162,14 @@ public interface RaceState extends ReadonlyRaceState {
|
||||
* forces a RaceStateUpdate
|
||||
*/
|
||||
void forceUpdate();
|
||||
|
||||
/**
|
||||
* Marks the results of the race to which this state belongs as official, using a
|
||||
* {@link RaceLogResultsAreOfficialEvent}.
|
||||
*
|
||||
* @param timePoint
|
||||
* the time point at which the results were declared official
|
||||
* @see #isResultsAreOfficial()
|
||||
*/
|
||||
void setResultsAreOfficial(TimePoint timePoint);
|
||||
}
|
||||
+1
-1
@@ -18,5 +18,5 @@ public interface RaceStateChangedListener {
|
||||
void onCourseDesignChanged(ReadonlyRaceState state);
|
||||
void onWindFixChanged(ReadonlyRaceState state);
|
||||
void onTagEventsChanged(ReadonlyRaceState state);
|
||||
|
||||
void onResultsAreOfficialChanged(ReadonlyRaceState state);
|
||||
}
|
||||
+5
@@ -102,6 +102,11 @@ public interface ReadonlyRaceState extends RaceStateEventProcessor {
|
||||
* Gets the races overall status.
|
||||
*/
|
||||
RaceLogRaceStatus getStatus();
|
||||
|
||||
/**
|
||||
* Tells if the results found for this race have been confirmed officially.
|
||||
*/
|
||||
boolean isResultsAreOfficial();
|
||||
|
||||
/**
|
||||
* If there is a start time set for the current pass, returns it. Otherwise <code>null</code>.
|
||||
|
||||
+4
@@ -68,4 +68,8 @@ public abstract class BaseRaceStateChangedListener implements RaceStateChangedLi
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResultsAreOfficialChanged(ReadonlyRaceState state) {
|
||||
|
||||
}
|
||||
}
|
||||
+7
@@ -118,4 +118,11 @@ public class RaceStateChangedListeners extends HashSet<RaceStateChangedListener>
|
||||
listener.onTagEventsChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResultsAreOfficialChanged(ReadonlyRaceState state) {
|
||||
for (RaceStateChangedListener listener : getWorkingCopyOfListeners()) {
|
||||
listener.onResultsAreOfficialChanged(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
@@ -20,6 +20,7 @@ import com.sap.sailing.domain.abstractlog.race.impl.RaceLogFlagEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogPassChangeEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogProtestStartTimeEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogRaceStatusEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogResultsAreOfficialEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartProcedureChangedEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartTimeEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogWindFixEventImpl;
|
||||
@@ -135,6 +136,11 @@ public class RaceStateImpl extends ReadonlyRaceStateImpl implements RaceState {
|
||||
// ensure caches are synched
|
||||
forceUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResultsAreOfficial(TimePoint timePoint) {
|
||||
raceLog.add(new RaceLogResultsAreOfficialEventImpl(timePoint, author, raceLog.getCurrentPassId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProtestTime(TimePoint now, TimeRange protestTime) {
|
||||
|
||||
+16
-2
@@ -13,6 +13,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogChangedListener;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogPassChangeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogResultsAreOfficialEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogTagEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
|
||||
@@ -27,6 +28,7 @@ import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceStatusAnalyzer;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceStatusAnalyzer.Clock;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RacingProcedureTypeAnalyzer;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.ResultsAreOfficialFinder;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderResult;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.TagFinder;
|
||||
@@ -165,6 +167,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
|
||||
private final FinishingTimeFinder finishingTimeAnalyzer;
|
||||
private final FinishedTimeFinder finishedTimeAnalyzer;
|
||||
private final ProtestTimeFinder protestTimeAnalyzer;
|
||||
private final ResultsAreOfficialFinder resultsAreOfficialAnalyzer;
|
||||
|
||||
private final FinishPositioningListFinder finishPositioningListAnalyzer;
|
||||
private final ConfirmedFinishPositioningListFinder confirmedFinishPositioningListAnalyzer;
|
||||
@@ -205,6 +208,8 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
|
||||
|
||||
private Iterable<RaceLogTagEvent> cachedTagEvents;
|
||||
|
||||
private boolean cachedResultsAreOfficial;
|
||||
|
||||
private int cachedPassId;
|
||||
private StartTimeFinderResult cachedStartTimeFinderResult;
|
||||
private TimePoint cachedFinishingTime;
|
||||
@@ -250,19 +255,18 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
|
||||
this.finishingTimeAnalyzer = new FinishingTimeFinder(raceLog);
|
||||
this.finishedTimeAnalyzer = new FinishedTimeFinder(raceLog);
|
||||
this.protestTimeAnalyzer = new ProtestTimeFinder(raceLog);
|
||||
this.resultsAreOfficialAnalyzer = new ResultsAreOfficialFinder(raceLog);
|
||||
this.finishPositioningListAnalyzer = new FinishPositioningListFinder(raceLog);
|
||||
this.confirmedFinishPositioningListAnalyzer = new ConfirmedFinishPositioningListFinder(raceLog);
|
||||
this.courseDesignerAnalyzer = new LastPublishedCourseDesignFinder(raceLog, /* onlyCoursesWithValidWaypointList */ false);
|
||||
this.lastWindFixAnalyzer = new LastWindFixFinder(raceLog);
|
||||
this.tagAnalyzer = new TagFinder(raceLog);
|
||||
|
||||
this.raceStateToObserveListener = new BaseRaceStateChangedListener() {
|
||||
@Override
|
||||
public void onStartTimeChanged(ReadonlyRaceState state) {
|
||||
update();
|
||||
}
|
||||
};
|
||||
|
||||
this.cachedRacingProcedureTypeNoFallback = determineInitialProcedureType();
|
||||
if (this.cachedRacingProcedureTypeNoFallback == null
|
||||
|| this.cachedRacingProcedureTypeNoFallback == RacingProcedureType.UNKNOWN) {
|
||||
@@ -368,6 +372,11 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
|
||||
return cachedRaceStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isResultsAreOfficial() {
|
||||
return cachedResultsAreOfficial;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds out whether any of the time points in {@link #timePointsWhenRaceStatusMayChange} falls into the time range
|
||||
* provided. In this case we assume that a race status update may have happened between the time point when the
|
||||
@@ -581,6 +590,11 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
|
||||
cachedTagEvents = tagEvents;
|
||||
changedListeners.onTagEventsChanged(this);
|
||||
}
|
||||
final RaceLogResultsAreOfficialEvent resultsAreOfficialEvent = resultsAreOfficialAnalyzer.analyze();
|
||||
if ((resultsAreOfficialEvent != null) != cachedResultsAreOfficial) {
|
||||
cachedResultsAreOfficial = resultsAreOfficialEvent != null;
|
||||
changedListeners.onResultsAreOfficialChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-2
@@ -15,8 +15,8 @@ import com.sap.sailing.domain.tractracadapter.impl.TracTracRaceTrackerImpl;
|
||||
* @author Frederik Petersen
|
||||
*
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface LoadingQueueDoneCallBack {
|
||||
|
||||
/**
|
||||
* Callback method
|
||||
* See {@link AbstractReceiverWithQueue} and {@link TracTracRaceTrackerImpl} for example usage.
|
||||
@@ -24,5 +24,4 @@ public interface LoadingQueueDoneCallBack {
|
||||
* @param receiver Receiver that handled the marked event.
|
||||
*/
|
||||
void loadingQueueDone(Receiver receiver);
|
||||
|
||||
}
|
||||
+10
-2
@@ -32,16 +32,19 @@ import com.tractrac.subscription.lib.api.race.IRaceCompetitorListener;
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class CompetitorChangeReceiver extends AbstractReceiverWithQueue<IRaceCompetitor, Void, Void> {
|
||||
public class CompetitorChangeReceiver extends AbstractReceiverWithQueue<IRaceCompetitor, Void, Void>
|
||||
implements OfficialCompetitorUpdateProvider {
|
||||
private static final Logger logger = Logger.getLogger(CompetitorChangeReceiver.class.getName());
|
||||
private final IRaceCompetitorListener listener;
|
||||
private final RaceAndCompetitorStatusWithRaceLogReconciler reconciler;
|
||||
|
||||
public CompetitorChangeReceiver(DynamicTrackedRegatta trackedRegatta, IEvent tractracEvent,
|
||||
IRace tractracRace, Simulator simulator, DomainFactory domainFactory,
|
||||
IEventSubscriber eventSubscriber, IRaceSubscriber raceSubscriber, long timeoutInMilliseconds, RaceAndCompetitorStatusWithRaceLogReconciler raceAndCompetitorStatusWithRaceLogReconciler) {
|
||||
IEventSubscriber eventSubscriber, IRaceSubscriber raceSubscriber, long timeoutInMilliseconds,
|
||||
RaceAndCompetitorStatusWithRaceLogReconciler raceAndCompetitorStatusWithRaceLogReconciler) {
|
||||
super(domainFactory, tractracEvent, trackedRegatta, simulator, eventSubscriber, raceSubscriber, timeoutInMilliseconds);
|
||||
reconciler = raceAndCompetitorStatusWithRaceLogReconciler;
|
||||
reconciler.setOfficialCompetitorUpdateProvider(this);
|
||||
listener = new IRaceCompetitorListener() {
|
||||
@Override
|
||||
public void addRaceCompetitor(IRaceCompetitor raceCompetitor) {
|
||||
@@ -99,4 +102,9 @@ public class CompetitorChangeReceiver extends AbstractReceiverWithQueue<IRaceCom
|
||||
+ ". Dropping competitor change event " + event);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runWhenNoMoreOfficialCompetitorUpdatesPending(Runnable runnable) {
|
||||
callBackWhenLoadingQueueIsDone(receiver->runnable.run());
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -583,7 +583,7 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
tracTracUsername, tracTracPassword, eventSubscriber, raceSubscriber,
|
||||
useInternalMarkPassingAlgorithm, timeoutInMilliseconds, raceTrackingHandler, raceAndCompetitorStatusWithRaceLogReconciler,
|
||||
ReceiverType.RACECOURSE, ReceiverType.MARKPASSINGS, ReceiverType.MARKPOSITIONS, ReceiverType.RACESTARTFINISH,
|
||||
ReceiverType.RAWPOSITIONS, ReceiverType.SENSORDATA);
|
||||
ReceiverType.RAWPOSITIONS, ReceiverType.SENSORDATA, ReceiverType.COMPETITOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.sap.sailing.domain.tractracadapter.impl;
|
||||
|
||||
public interface OfficialCompetitorUpdateProvider {
|
||||
/**
|
||||
* Runs the {@link Runnable} when all competitor update requests enqueued so far have been
|
||||
* processed.
|
||||
*/
|
||||
void runWhenNoMoreOfficialCompetitorUpdatesPending(Runnable runnable);
|
||||
}
|
||||
+24
-2
@@ -28,7 +28,9 @@ import com.sap.sailing.domain.abstractlog.race.impl.CompetitorResultsImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogFinishPositioningConfirmedEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogFlagEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogPassChangeEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.state.RaceState;
|
||||
import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState;
|
||||
import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.state.impl.ReadonlyRaceStateImpl;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
@@ -65,6 +67,7 @@ public class RaceAndCompetitorStatusWithRaceLogReconciler {
|
||||
private final LogEventAuthorImpl raceLogEventAuthor;
|
||||
private final IRace tractracRace;
|
||||
private final Map<Pair<TrackedRace, RaceLog>, RaceLogListener> raceLogListeners;
|
||||
private OfficialCompetitorUpdateProvider officialCompetitorUpdateProvider;
|
||||
private final static Map<RaceStatusType, Flags> flagForRaceStatus;
|
||||
|
||||
static {
|
||||
@@ -209,7 +212,7 @@ public class RaceAndCompetitorStatusWithRaceLogReconciler {
|
||||
*/
|
||||
public void reconcileRaceStatus(IRace tractracRace, TrackedRace trackedRace) {
|
||||
final RaceStatusType raceStatus = tractracRace.getStatus();
|
||||
final MillisecondsTimePoint raceStatusUpdateTime = new MillisecondsTimePoint(tractracRace.getStatusTime());
|
||||
final TimePoint raceStatusUpdateTime = TimePoint.of(tractracRace.getStatusTime());
|
||||
RaceLogFlagEvent abortingFlagEvent = null;
|
||||
for (final RaceLog raceLog : trackedRace.getAttachedRaceLogs()) {
|
||||
if (abortingFlagEvent == null) {
|
||||
@@ -218,6 +221,14 @@ public class RaceAndCompetitorStatusWithRaceLogReconciler {
|
||||
}
|
||||
}
|
||||
final RaceLog defaultRaceLog = getDefaultRaceLog(trackedRace);
|
||||
if (raceStatus == RaceStatusType.OFFICIAL && !ReadonlyRaceStateImpl.getOrCreate(raceLogResolver, defaultRaceLog).isResultsAreOfficial()) {
|
||||
final Runnable setResultsAreOfficial = ()->RaceStateImpl.create(raceLogResolver, defaultRaceLog, raceLogEventAuthor).setResultsAreOfficial(raceStatusUpdateTime);
|
||||
if (officialCompetitorUpdateProvider != null) {
|
||||
officialCompetitorUpdateProvider.runWhenNoMoreOfficialCompetitorUpdatesPending(setResultsAreOfficial);
|
||||
} else {
|
||||
setResultsAreOfficial.run();
|
||||
}
|
||||
}
|
||||
if (abortingFlagEvent != null && !isAbortedState(raceStatus) && raceStatusUpdateTime.after(abortingFlagEvent.getLogicalTimePoint())) {
|
||||
startNewPass(raceStatusUpdateTime, defaultRaceLog);
|
||||
} else if (isAbortedState(raceStatus) &&
|
||||
@@ -229,7 +240,7 @@ public class RaceAndCompetitorStatusWithRaceLogReconciler {
|
||||
}
|
||||
}
|
||||
|
||||
protected void startNewPass(final MillisecondsTimePoint timePointForStartOfNewPass, final RaceLog raceLog) {
|
||||
protected void startNewPass(final TimePoint timePointForStartOfNewPass, final RaceLog raceLog) {
|
||||
raceLog.add(new RaceLogPassChangeEventImpl(timePointForStartOfNewPass, raceLogEventAuthor, raceLog.getCurrentPassId() + 1));
|
||||
}
|
||||
|
||||
@@ -397,4 +408,15 @@ public class RaceAndCompetitorStatusWithRaceLogReconciler {
|
||||
}
|
||||
return resultFromRaceLogAndItsCreationTimePoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called by the object later calling {@link #reconcileCompetitorStatus(IRaceCompetitor, TrackedRace)}. This
|
||||
* way, this object can tell when the race is to be {@link RaceState#setResultsAreOfficial(TimePoint) moved to
|
||||
* OFFICIAL state} whether any updates are pending and defer the race state transition to that moment.
|
||||
*
|
||||
* @see OfficialCompetitorUpdateProvider#runWhenNoMoreOfficialCompetitorUpdatesPending(Runnable)
|
||||
*/
|
||||
public void setOfficialCompetitorUpdateProvider(OfficialCompetitorUpdateProvider officialCompetitorUpdateProvider) {
|
||||
this.officialCompetitorUpdateProvider = officialCompetitorUpdateProvider;
|
||||
}
|
||||
}
|
||||
+35
-31
@@ -58,19 +58,19 @@ import com.sap.sse.common.Util;
|
||||
import com.sap.sse.util.impl.ThreadFactoryWithPriority;
|
||||
import com.tractrac.model.lib.api.event.CreateModelException;
|
||||
import com.tractrac.model.lib.api.event.DataSource;
|
||||
import com.tractrac.model.lib.api.event.ICompetitor;
|
||||
import com.tractrac.model.lib.api.event.IEvent;
|
||||
import com.tractrac.model.lib.api.event.IRace;
|
||||
import com.tractrac.model.lib.api.event.IRaceCompetitor;
|
||||
import com.tractrac.model.lib.api.route.IControl;
|
||||
import com.tractrac.subscription.lib.api.IEventSubscriber;
|
||||
import com.tractrac.subscription.lib.api.IRaceSubscriber;
|
||||
import com.tractrac.subscription.lib.api.ISubscriberFactory;
|
||||
import com.tractrac.subscription.lib.api.SubscriberInitializationException;
|
||||
import com.tractrac.subscription.lib.api.SubscriptionLocator;
|
||||
import com.tractrac.subscription.lib.api.competitor.ICompetitorsListener;
|
||||
import com.tractrac.subscription.lib.api.event.IConnectionStatusListener;
|
||||
import com.tractrac.subscription.lib.api.event.ILiveDataEvent;
|
||||
import com.tractrac.subscription.lib.api.event.IStoredDataEvent;
|
||||
import com.tractrac.subscription.lib.api.race.IRaceCompetitorListener;
|
||||
import com.tractrac.subscription.lib.api.race.IRacesListener;
|
||||
import com.tractrac.util.lib.api.exceptions.TimeOutException;
|
||||
|
||||
@@ -199,7 +199,7 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
|
||||
private final IEventSubscriber eventSubscriber;
|
||||
private final IRaceSubscriber raceSubscriber;
|
||||
private final IRacesListener racesListener;
|
||||
private final ICompetitorsListener competitorsListener;
|
||||
private final IRaceCompetitorListener competitorsListener;
|
||||
private final Set<Receiver> receivers;
|
||||
private final DomainFactory domainFactory;
|
||||
private final WindStore windStore;
|
||||
@@ -351,33 +351,6 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
|
||||
// Initialize data controller using live and stored data sources
|
||||
ISubscriberFactory subscriberFactory = SubscriptionLocator.getSusbcriberFactory();
|
||||
eventSubscriber = subscriberFactory.createEventSubscriber(tractracEvent, liveURI, effectiveStoredURI);
|
||||
competitorsListener = new ICompetitorsListener() {
|
||||
@Override
|
||||
public void updateCompetitor(ICompetitor competitor) {
|
||||
if (!competitor.isNonCompeting()) {
|
||||
TracTracRaceTrackerImpl.this.domainFactory.updateCompetitor(competitor, raceTrackingHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteCompetitor(UUID competitorId) {
|
||||
try {
|
||||
trackedRegattaRegistry.updateRaceCompetitors(getRegatta(), getRace());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCompetitor(ICompetitor competitor) {
|
||||
try {
|
||||
trackedRegattaRegistry.updateRaceCompetitors(getRegatta(), getRace());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
eventSubscriber.subscribeCompetitors(competitorsListener);
|
||||
if (useOfficialEventsToUpdateRaceLog) {
|
||||
reconciler = new RaceAndCompetitorStatusWithRaceLogReconciler(domainFactory, raceLogResolver, tractracRace);
|
||||
} else {
|
||||
@@ -456,6 +429,37 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
|
||||
useInternalMarkPassingAlgorithm, timeoutInMilliseconds, raceTrackingHandler, reconciler)) {
|
||||
receivers.add(receiver);
|
||||
}
|
||||
competitorsListener = new IRaceCompetitorListener() {
|
||||
@Override
|
||||
public void addRaceCompetitor(IRaceCompetitor raceCompetitor) {
|
||||
try {
|
||||
trackedRegattaRegistry.updateRaceCompetitors(getRegatta(), getRace());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRaceCompetitor(IRaceCompetitor raceCompetitor) {
|
||||
if (!raceCompetitor.getCompetitor().isNonCompeting()) {
|
||||
TracTracRaceTrackerImpl.this.domainFactory.updateCompetitor(raceCompetitor.getCompetitor(), raceTrackingHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRaceCompetitor(UUID competitorId) {
|
||||
try {
|
||||
trackedRegattaRegistry.updateRaceCompetitors(getRegatta(), getRace());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeOffsetPositions(UUID competitorId, int offset) {
|
||||
}
|
||||
};
|
||||
raceSubscriber.subscribeRaceCompetitor(competitorsListener);
|
||||
addListenersForStoredDataAndStartController(receivers);
|
||||
}
|
||||
|
||||
@@ -598,7 +602,7 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
|
||||
if (!stopped) {
|
||||
stopped = true;
|
||||
eventSubscriber.unsubscribeRaces(racesListener);
|
||||
eventSubscriber.unsubscribeCompetitors(competitorsListener);
|
||||
raceSubscriber.unsubscribeRaceCompetitor(competitorsListener);
|
||||
raceSubscriber.stop();
|
||||
eventSubscriber.stop();
|
||||
raceSubscriber.unsubscribeConnectionStatus(this);
|
||||
|
||||
+6
@@ -20,6 +20,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogPassChangeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogPathfinderEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogProtestStartTimeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogResultsAreOfficialEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogStartProcedureChangedEvent;
|
||||
@@ -192,4 +193,9 @@ public class RaceColumnRaceLogReplicator implements RaceLogEventVisitor, Seriali
|
||||
public void visit(RaceLogORCImpliedWindSourceEvent event) {
|
||||
notifyOnAdd(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RaceLogResultsAreOfficialEvent event) {
|
||||
notifyOnAdd(event);
|
||||
}
|
||||
}
|
||||
+11
@@ -25,11 +25,13 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogFlagEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogPassChangeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogResultsAreOfficialEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogFlagEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogPassChangeEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogRaceStatusEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogResultsAreOfficialEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogRevokeEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartTimeEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDenoteForTrackingEvent;
|
||||
@@ -121,6 +123,15 @@ public class StoreAndLoadRaceLogEventsTest extends AbstractMongoDBTest {
|
||||
assertEquals(lowerFlag, actualEvent.getLowerFlag());
|
||||
assertEquals(isDisplayed, actualEvent.isDisplayed());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoreAndLoadResultsAreOfficialEvent() {
|
||||
RaceLogResultsAreOfficialEvent expectedEvent = new RaceLogResultsAreOfficialEventImpl(MillisecondsTimePoint.now(), expectedEventTime,
|
||||
author, expectedId, expectedPassId);
|
||||
Document dbObject = mongoFactory.storeRaceLogEntry(logIdentifier, expectedEvent);
|
||||
RaceLogResultsAreOfficialEvent actualEvent = loadEvent(dbObject);
|
||||
assertBaseFields(expectedEvent, actualEvent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoreAndLoadPassChangeEvent() {
|
||||
|
||||
+12
-2
@@ -20,6 +20,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogPassChangeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogPathfinderEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogProtestStartTimeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogResultsAreOfficialEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogStartProcedureChangedEvent;
|
||||
@@ -90,7 +91,8 @@ public class RaceLogEventSerializer implements JsonSerializer<RaceLogEvent>, Rac
|
||||
new RaceLogORCLegDataEventSerializer(competitorSerializer),
|
||||
new RaceLogORCCertificateAssignmentEventSerializer(competitorSerializer),
|
||||
new RaceLogORCScratchBoatEventSerializer(competitorSerializer),
|
||||
new RaceLogORCImpliedWindSourceEventSerializer(competitorSerializer));
|
||||
new RaceLogORCImpliedWindSourceEventSerializer(competitorSerializer),
|
||||
new RaceLogResultsAreOfficialEventSerializer(competitorSerializer));
|
||||
}
|
||||
|
||||
private final JsonSerializer<RaceLogEvent> flagEventSerializer;
|
||||
@@ -121,6 +123,7 @@ public class RaceLogEventSerializer implements JsonSerializer<RaceLogEvent>, Rac
|
||||
private final JsonSerializer<RaceLogEvent> orcCertificateAssignmentEventSerializer;
|
||||
private final JsonSerializer<RaceLogEvent> orcScratchBoatEventSerializer;
|
||||
private final JsonSerializer<RaceLogEvent> orcImpliedWindSourceEventSerializer;
|
||||
private final JsonSerializer<RaceLogEvent> resultsAreOfficialEventSerializer;
|
||||
|
||||
private JsonSerializer<RaceLogEvent> chosenSerializer;
|
||||
|
||||
@@ -153,7 +156,8 @@ public class RaceLogEventSerializer implements JsonSerializer<RaceLogEvent>, Rac
|
||||
JsonSerializer<RaceLogEvent> orcLegDataEventSerializer,
|
||||
JsonSerializer<RaceLogEvent> orcCertificateAssignmentEventSerializer,
|
||||
JsonSerializer<RaceLogEvent> orcScratchBoatEventSerializer,
|
||||
JsonSerializer<RaceLogEvent> orcImpliedWindSourceEventSerializer) {
|
||||
JsonSerializer<RaceLogEvent> orcImpliedWindSourceEventSerializer,
|
||||
JsonSerializer<RaceLogEvent> resultsAreOfficialEventSerializer) {
|
||||
this.flagEventSerializer = flagEventSerializer;
|
||||
this.startTimeSerializer = startTimeSerializer;
|
||||
this.raceStatusSerializer = raceStatusSerializer;
|
||||
@@ -182,6 +186,7 @@ public class RaceLogEventSerializer implements JsonSerializer<RaceLogEvent>, Rac
|
||||
this.orcCertificateAssignmentEventSerializer = orcCertificateAssignmentEventSerializer;
|
||||
this.orcScratchBoatEventSerializer = orcScratchBoatEventSerializer;
|
||||
this.orcImpliedWindSourceEventSerializer = orcImpliedWindSourceEventSerializer;
|
||||
this.resultsAreOfficialEventSerializer = resultsAreOfficialEventSerializer;
|
||||
this.chosenSerializer = null;
|
||||
}
|
||||
|
||||
@@ -338,4 +343,9 @@ public class RaceLogEventSerializer implements JsonSerializer<RaceLogEvent>, Rac
|
||||
public void visit(RaceLogORCImpliedWindSourceEvent event) {
|
||||
chosenSerializer = orcImpliedWindSourceEventSerializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RaceLogResultsAreOfficialEvent event) {
|
||||
chosenSerializer = resultsAreOfficialEventSerializer;
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.sap.sailing.server.gateway.serialization.racelog.impl;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogResultsAreOfficialEvent;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
|
||||
|
||||
/**
|
||||
* Serializer for {@link RaceLogResultsAreOfficialEvent}.
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*/
|
||||
public class RaceLogResultsAreOfficialEventSerializer extends BaseRaceLogEventSerializer {
|
||||
public static final String VALUE_CLASS = RaceLogResultsAreOfficialEvent.class.getSimpleName();
|
||||
|
||||
public RaceLogResultsAreOfficialEventSerializer(JsonSerializer<Competitor> competitorSerializer) {
|
||||
super(competitorSerializer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject serialize(RaceLogEvent object) {
|
||||
final RaceLogResultsAreOfficialEvent resultsAreOfficialEvent = (RaceLogResultsAreOfficialEvent) object;
|
||||
final JSONObject result = super.serialize(resultsAreOfficialEvent);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getClassFieldValue() {
|
||||
return VALUE_CLASS;
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -76,6 +76,7 @@ public class RaceLogEventSerializerTest {
|
||||
private JsonSerializer<RaceLogEvent> orcCertificateAssignmentEventSerializer;
|
||||
private JsonSerializer<RaceLogEvent> orcScratchBoatEventSerializer;
|
||||
private JsonSerializer<RaceLogEvent> orcSetImpliedWindEventSerializer;
|
||||
private JsonSerializer<RaceLogEvent> resultsAreOfficialEventSerializer;
|
||||
|
||||
private AbstractLogEventAuthor author = new LogEventAuthorImpl("Test Author", 1);
|
||||
|
||||
@@ -111,6 +112,7 @@ public class RaceLogEventSerializerTest {
|
||||
orcCertificateAssignmentEventSerializer = mock(JsonSerializer.class);
|
||||
orcScratchBoatEventSerializer = mock(JsonSerializer.class);
|
||||
orcSetImpliedWindEventSerializer = mock(JsonSerializer.class);
|
||||
resultsAreOfficialEventSerializer = mock(JsonSerializer.class);
|
||||
|
||||
serializer = new RaceLogEventSerializer(flagEventSerializer, startTimeSerializer, raceStatusSerializer,
|
||||
passChangedSerializer, courseDesignChangedEventSerializer,
|
||||
@@ -124,7 +126,7 @@ public class RaceLogEventSerializerTest {
|
||||
startOfTrackingEventSerializer, useCompetitorsFromRaceLogEventSerializer,
|
||||
endOfTrackingEventSerializer, tagEventSerializer, orcLegDataEventSerializer,
|
||||
orcCertificateAssignmentEventSerializer, orcScratchBoatEventSerializer,
|
||||
orcSetImpliedWindEventSerializer);
|
||||
orcSetImpliedWindEventSerializer, resultsAreOfficialEventSerializer);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+8
@@ -10,6 +10,8 @@ import org.apache.shiro.SecurityUtils;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.ResultsAreOfficialFinder;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
@@ -178,6 +180,7 @@ public abstract class AbstractLeaderboardsResource extends AbstractSailingServer
|
||||
final JSONObject fleetJson = new JSONObject();
|
||||
fleetsJson.add(fleetJson);
|
||||
fleetJson.put("name", fleet.getName());
|
||||
fleetJson.put("resultsAreOfficial", isResultsAreOfficial(raceColumn, fleet));
|
||||
final TrackedRace trackedRace = raceColumn.getTrackedRace(fleet);
|
||||
final JSONObject trackedRaceInfo;
|
||||
if (trackedRace == null) {
|
||||
@@ -203,6 +206,11 @@ public abstract class AbstractLeaderboardsResource extends AbstractSailingServer
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isResultsAreOfficial(RaceColumn raceColumn, Fleet fleet) {
|
||||
final RaceLog raceLog = raceColumn.getRaceLog(fleet);
|
||||
return new ResultsAreOfficialFinder(raceLog).analyze() != null;
|
||||
}
|
||||
|
||||
protected TimePoint calculateTimePointForResultState(Leaderboard leaderboard, ResultStates resultState) {
|
||||
TimePoint result = null;
|
||||
switch (resultState) {
|
||||
|
||||
Regular → Executable
File mode changed.
Regular → Executable
File mode changed.
+4
-1
@@ -279,7 +279,10 @@ public class RaceSummaryFragment extends BaseFragment {
|
||||
|
||||
@Override
|
||||
public void onTagEventsChanged(ReadonlyRaceState state) {
|
||||
// TODO: add android support for tags
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResultsAreOfficialChanged(ReadonlyRaceState state) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user