Introduce RaceLogResolver and RaceLogDependentStartTimeFinder

This commit is contained in:
Jan Broß
2015-05-22 16:00:00 +02:00
parent a6e08031c2
commit 45563b88db
32 changed files with 383 additions and 201 deletions
@@ -14,25 +14,25 @@ import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.DependentStartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderStatus;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util.Pair;
public class StartTimeFinderTest extends
PassAwareRaceLogAnalyzerTest<StartTimeFinder, Pair<StartTimeFinderStatus, TimePoint>> {
public class DependentStartTimeFinderTest extends
PassAwareRaceLogAnalyzerTest<DependentStartTimeFinder, TimePoint> {
@Override
protected StartTimeFinder createAnalyzer(RaceLog raceLog) {
return new StartTimeFinder(raceLog);
protected DependentStartTimeFinder createAnalyzer(RaceLog raceLog) {
return new DependentStartTimeFinder(mock(RaceLogResolver.class), raceLog);
}
@Override
protected TargetPair getTargetEventsAndResultForPassAwareTests(int passId, AbstractLogEventAuthor author) {
RaceLogStartTimeEvent event = createEvent(RaceLogStartTimeEvent.class, 1, passId, author);
when(event.getStartTime()).thenReturn(mock(TimePoint.class));
return new TargetPair(Arrays.asList(event), new Pair<StartTimeFinderStatus, TimePoint>(
StartTimeFinderStatus.STARTTIME_FOUND, event.getStartTime()));
return new TargetPair(Arrays.asList(event), event.getStartTime());
}
@Test
@@ -53,8 +53,7 @@ public class StartTimeFinderTest extends
raceLog.add(event1);
raceLog.add(event2);
assertEquals(StartTimeFinderStatus.STARTTIME_FOUND, analyzer.analyze().getA());
assertEquals(event2.getStartTime(), analyzer.analyze().getB());
assertEquals(event2.getStartTime(), analyzer.analyze());
}
@Test
@@ -66,7 +65,6 @@ public class StartTimeFinderTest extends
raceLog.add(event1);
raceLog.add(event2);
assertEquals(StartTimeFinderStatus.STARTTIME_DEPENDENT, analyzer.analyze().getA());
assertNull(analyzer.analyze().getB());
assertNull(analyzer.analyze());
}
}
@@ -19,6 +19,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor;
import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent;
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.state.racingprocedure.RacingProcedure;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
@@ -31,7 +32,7 @@ public class RaceStatusAnalyzerTest extends PassAwareRaceLogAnalyzerTest<RaceSta
@Override
protected RaceStatusAnalyzer createAnalyzer(RaceLog raceLog) {
return new RaceStatusAnalyzer(raceLog, racingProcedure);
return new RaceStatusAnalyzer(mock(RaceLogResolver.class), raceLog, racingProcedure);
}
@Override
@@ -105,7 +106,7 @@ public class RaceStatusAnalyzerTest extends PassAwareRaceLogAnalyzerTest<RaceSta
@Test
public void testClock() {
final TimePoint startTime = MillisecondsTimePoint.now();
analyzer = new RaceStatusAnalyzer(raceLog, new RaceStatusAnalyzer.Clock() {
analyzer = new RaceStatusAnalyzer(mock(RaceLogResolver.class), raceLog, new RaceStatusAnalyzer.Clock() {
@Override
public TimePoint now() {
return startTime.minus(1);
@@ -17,6 +17,7 @@ import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogEventFactory;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogImpl;
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartProcedureChangedEventImpl;
import com.sap.sailing.domain.abstractlog.race.state.RaceState;
@@ -61,7 +62,7 @@ public class RaceStateTest {
listener = mock(RaceStateChangedListener.class);
nowMock = mock(TimePoint.class);
state = new RaceStateImpl(raceLog, author, factory, new RacingProcedureFactoryImpl(author, factory, configuration));
state = new RaceStateImpl(mock(RaceLogResolver.class), raceLog, author, factory, new RacingProcedureFactoryImpl(author, factory, configuration));
}
@Test
@@ -91,7 +92,7 @@ public class RaceStateTest {
config.setBasicConfiguration(mock(RacingProcedureConfiguration.class));
configuration = mock(ConfigurationLoader.class);
when(configuration.load()).thenReturn(config);
state = new RaceStateImpl(raceLog, author, factory, new RacingProcedureFactoryImpl(author, factory, configuration));
state = new RaceStateImpl(mock(RaceLogResolver.class), raceLog, author, factory, new RacingProcedureFactoryImpl(author, factory, configuration));
assertEquals(RacingProcedureType.BASIC, state.getRacingProcedure().getType());
}
@@ -106,7 +107,7 @@ public class RaceStateTest {
configuration = mock(ConfigurationLoader.class);
when(configuration.load()).thenReturn(config);
raceLog.add(new RaceLogStartProcedureChangedEventImpl(nowMock, author, nowMock, "12", null, 0, RacingProcedureType.ESS));
state = new RaceStateImpl(raceLog, author, factory, new RacingProcedureFactoryImpl(author, factory, configuration));
state = new RaceStateImpl(mock(RaceLogResolver.class), raceLog, author, factory, new RacingProcedureFactoryImpl(author, factory, configuration));
assertEquals(RacingProcedureType.ESS, state.getRacingProcedure().getType());
}
@@ -1,33 +1,17 @@
package com.sap.sailing.domain.abstractlog.race;
import com.sap.sse.common.Util.Triple;
public class SimpleRaceLogIdentifier{
public interface SimpleRaceLogIdentifier {
private final String regattaLikeParentName;
private final String raceColumnName;
private final String fleetName;
String getRegattaLikeParentName();
String getRaceColumnName();
String getFleetName();
public SimpleRaceLogIdentifier(String regattaLikeParentName, String raceColumnName, String fleetName) {
this.regattaLikeParentName = regattaLikeParentName;
this.raceColumnName = raceColumnName;
this.fleetName = fleetName;
}
Triple<String, String, String> getIdentifier();
String getDeprecatedIdentifier();
public String getRegattaLikeParentName() {
return regattaLikeParentName;
}
public String getRaceColumnName() {
return raceColumnName;
}
public String getFleetName() {
return fleetName;
}
@Override
public String toString() {
return "SimpleRaceLogIdentifier [regattaLikeParentName=" + regattaLikeParentName + ", raceCloumnName=" + raceColumnName
+ ", fleetName=" + fleetName + "]";
}
}
}
@@ -0,0 +1,51 @@
package com.sap.sailing.domain.abstractlog.race;
public class SimpleRaceLogIdentifierImpl implements SimpleRaceLogIdentifier {
protected final String regattaLikeParentName;
protected final String raceColumnName;
protected final String fleetName;
public SimpleRaceLogIdentifierImpl(String regattaLikeParentName, String raceColumnName, String fleetName) {
this.regattaLikeParentName = regattaLikeParentName;
this.raceColumnName = raceColumnName;
this.fleetName = fleetName;
}
@Override
public String getRegattaLikeParentName() {
return regattaLikeParentName;
}
@Override
public String getRaceColumnName() {
return raceColumnName;
}
@Override
public String getFleetName() {
return fleetName;
}
@Override
public String toString() {
return "SimpleRaceLogIdentifier [regattaLikeParentName=" + regattaLikeParentName + ", raceCloumnName=" + raceColumnName
+ ", fleetName=" + fleetName + "]";
}
@Override
public com.sap.sse.common.Util.Triple<String, String, String> getIdentifier() {
return new com.sap.sse.common.Util.Triple<String, String, String>(
regattaLikeParentName, raceColumnName, fleetName);
}
@Override
public String getDeprecatedIdentifier() {
return String.format("%s.%s.%s",
regattaLikeParentName,
raceColumnName,
fleetName);
}
}
@@ -0,0 +1,36 @@
package com.sap.sailing.domain.abstractlog.race.analyzing.impl;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent;
import com.sap.sse.common.TimePoint;
public class DependentStartTimeFinder extends RaceLogAnalyzer<TimePoint> {
private final RaceLogResolver resolver;
public DependentStartTimeFinder(RaceLogResolver resolver, RaceLog raceLog) {
super(raceLog);
this.resolver = resolver;
}
@Override
protected TimePoint performAnalysis() {
for (RaceLogEvent event : getPassEventsDescending()) {
if (event instanceof RaceLogStartTimeEvent) {
return ((RaceLogStartTimeEvent) event).getStartTime();
} else if (event instanceof RaceLogDependentStartTimeEvent) {
try {
DependentStartTimeResolver dependentStartTimeResolver = new DependentStartTimeResolver(resolver);
return dependentStartTimeResolver.resolve((RaceLogDependentStartTimeEvent) event);
} catch (RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException e) {
//TODO: Log error
return null;
}
}
}
return null;
}
}
@@ -0,0 +1,28 @@
package com.sap.sailing.domain.abstractlog.race.analyzing.impl;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
public class DependentStartTimeResolver {
private RaceLogResolver raceLogResolver;
public DependentStartTimeResolver(RaceLogResolver raceLogResolver) {
this.raceLogResolver = raceLogResolver;
}
TimePoint resolve(RaceLogDependentStartTimeEvent event) throws RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException {
SimpleRaceLogIdentifier identifier = event.getDependentOnRaceIdentifier();
Duration startTimeDifference = event.getStartTimeDifference();
RaceLog raceLog = raceLogResolver.resolve(identifier);
DependentStartTimeFinder dependentStartTimeFinder = new DependentStartTimeFinder(raceLogResolver, raceLog);
TimePoint startTimeOfDependentRace = dependentStartTimeFinder.analyze();
return startTimeOfDependentRace.plus(startTimeDifference);
}
}
@@ -0,0 +1,8 @@
package com.sap.sailing.domain.abstractlog.race.analyzing.impl;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
public interface RaceLogResolver {
RaceLog resolve(SimpleRaceLogIdentifier identifier) throws RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException;
}
@@ -28,15 +28,18 @@ public class RaceStatusAnalyzer extends RaceLogAnalyzer<RaceLogRaceStatus> {
}
private final EventDispatcher eventDispatcher;
private RaceLogResolver resolver;
public RaceStatusAnalyzer(RaceLog raceLog, ReadonlyRacingProcedure racingProcedure) {
public RaceStatusAnalyzer(RaceLogResolver resolver, RaceLog raceLog, ReadonlyRacingProcedure racingProcedure) {
super(raceLog);
this.eventDispatcher = new EventDispatcher(new StandardClock(), racingProcedure);
this.resolver = resolver;
}
public RaceStatusAnalyzer(RaceLog raceLog, Clock clock, ReadonlyRacingProcedure racingProcedure) {
public RaceStatusAnalyzer(RaceLogResolver resolver, RaceLog raceLog, Clock clock, ReadonlyRacingProcedure racingProcedure) {
super(raceLog);
this.eventDispatcher = new EventDispatcher(clock, racingProcedure);
this.resolver = resolver;
}
@Override
@@ -70,10 +73,15 @@ public class RaceStatusAnalyzer extends RaceLogAnalyzer<RaceLogRaceStatus> {
@Override
public void visit(RaceLogStartTimeEvent event) {
TimePoint startTime = event.getStartTime();
setRaceLogStatusBasedOnStartTime(startTime);
}
private void setRaceLogStatusBasedOnStartTime(TimePoint startTime) {
TimePoint now = clock.now();
if (racingProcedure.isStartphaseActive(event.getStartTime(), now)) {
if (racingProcedure.isStartphaseActive(startTime, now)) {
nextStatus = RaceLogRaceStatus.STARTPHASE;
} else if (now.before(event.getStartTime())) {
} else if (now.before(startTime)) {
nextStatus = RaceLogRaceStatus.SCHEDULED;
} else {
nextStatus = RaceLogRaceStatus.RUNNING;
@@ -87,9 +95,13 @@ public class RaceStatusAnalyzer extends RaceLogAnalyzer<RaceLogRaceStatus> {
@Override
public void visit(RaceLogDependentStartTimeEvent event) {
//FIXME: Calculate RaceStatus based on status of Fleet on which race depends on or use StartTimeFinder
DependentStartTimeResolver startTimeResolver = new DependentStartTimeResolver(resolver);
try {
TimePoint startTime = startTimeResolver.resolve(event);
setRaceLogStatusBasedOnStartTime(startTime);
} catch (RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException e) {
nextStatus = RaceLogRaceStatus.UNKNOWN;
}
};
};
}
}
@@ -0,0 +1,7 @@
package com.sap.sailing.domain.abstractlog.race.analyzing.impl;
public class RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException extends Exception {
private static final long serialVersionUID = -139681048270793360L;
}
@@ -9,6 +9,7 @@ import com.sap.sailing.domain.abstractlog.race.CompetitorResults;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogEventFactory;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.AdditionalScoringInformationFinder;
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.scoring.AdditionalScoringInformationType;
import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent;
@@ -40,27 +41,27 @@ public class RaceStateImpl extends ReadonlyRaceStateImpl implements RaceState {
/**
* Creates a {@link RaceState} with the initial racing procedure type set to a fallback value and an empty configuration.
*/
public static RaceState create(RaceLog raceLog, AbstractLogEventAuthor author) {
return create(raceLog, author, new EmptyRegattaConfiguration());
public static RaceState create(RaceLogResolver raceLogResolver, RaceLog raceLog, AbstractLogEventAuthor author) {
return create(raceLogResolver, raceLog, author, new EmptyRegattaConfiguration());
}
/**
* Creates a {@link RaceState}.
*/
public static RaceState create(RaceLog raceLog, AbstractLogEventAuthor author, ConfigurationLoader<RegattaConfiguration> configuration) {
return new RaceStateImpl(raceLog, author,
public static RaceState create(RaceLogResolver raceLogResolver, RaceLog raceLog, AbstractLogEventAuthor author, ConfigurationLoader<RegattaConfiguration> configuration) {
return new RaceStateImpl(raceLogResolver, raceLog, author,
RaceLogEventFactory.INSTANCE,
new RacingProcedureFactoryImpl(author, RaceLogEventFactory.INSTANCE, configuration));
}
public RaceStateImpl(RaceLog raceLog, AbstractLogEventAuthor author, RaceLogEventFactory eventFactory,
public RaceStateImpl(RaceLogResolver raceLogResolver, RaceLog raceLog, AbstractLogEventAuthor author, RaceLogEventFactory eventFactory,
RacingProcedureFactory procedureFactory) {
this(raceLog, author, eventFactory, new RaceStatusAnalyzer.StandardClock(), procedureFactory);
this(raceLogResolver, raceLog, author, eventFactory, new RaceStatusAnalyzer.StandardClock(), procedureFactory);
}
private RaceStateImpl(RaceLog raceLog, AbstractLogEventAuthor author, RaceLogEventFactory eventFactory, RaceStatusAnalyzer.Clock analyzersClock,
private RaceStateImpl(RaceLogResolver raceLogResolver, RaceLog raceLog, AbstractLogEventAuthor author, RaceLogEventFactory eventFactory, RaceStatusAnalyzer.Clock analyzersClock,
RacingProcedureFactory procedureFactory) {
super(raceLog, analyzersClock, procedureFactory, /* update */ true);
super(raceLogResolver, raceLog, analyzersClock, procedureFactory, /* update */ true);
this.author = author;
this.factory = eventFactory;
}
@@ -5,17 +5,17 @@ import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogChangedListener;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.ConfirmedFinishPositioningListFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.DependentStartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.FinishPositioningListFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.FinishedTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.FinishingTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.LastPublishedCourseDesignFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.LastWindFixFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.ProtestStartTimeFinder;
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.StartTimeFinderStatus;
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.StartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.impl.WeakRaceLogChangedVisitor;
import com.sap.sailing.domain.abstractlog.race.state.RaceStateChangedListener;
import com.sap.sailing.domain.abstractlog.race.state.RaceStateEvent;
@@ -34,7 +34,6 @@ import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
/**
* Implementation of {@link ReadonlyRaceState}. Use the static factory methods to instantiate your race state.
@@ -50,16 +49,16 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
/**
* Creates a {@link ReadonlyRaceState}.
*/
public static ReadonlyRaceState create(RaceLog raceLog,
public static ReadonlyRaceState create(RaceLogResolver raceLogResolver, RaceLog raceLog,
ConfigurationLoader<RegattaConfiguration> configurationLoader) {
return new ReadonlyRaceStateImpl(raceLog, new ReadonlyRacingProcedureFactory(configurationLoader));
return new ReadonlyRaceStateImpl(raceLogResolver, raceLog, new ReadonlyRacingProcedureFactory(configurationLoader));
}
/**
* Creates a {@link ReadonlyRaceState} with an empty configuration ( {@link EmptyRegattaConfiguration} ).
*/
public static ReadonlyRaceState create(RaceLog raceLog) {
return new ReadonlyRaceStateImpl(raceLog, new ReadonlyRacingProcedureFactory(new EmptyRegattaConfiguration()));
public static ReadonlyRaceState create(RaceLogResolver raceLogResolver, RaceLog raceLog) {
return new ReadonlyRaceStateImpl(raceLogResolver, raceLog, new ReadonlyRacingProcedureFactory(new EmptyRegattaConfiguration()));
}
/**
@@ -83,7 +82,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
private RaceStatusAnalyzer statusAnalyzer;
private final RacingProcedureTypeAnalyzer racingProcedureAnalyzer;
private final StartTimeFinder startTimeAnalyzer;
private final DependentStartTimeFinder startTimeAnalyzer;
private final FinishingTimeFinder finishingTimeAnalyzer;
private final FinishedTimeFinder finishedTimeAnalyzer;
private final ProtestStartTimeFinder protestTimeAnalyzer;
@@ -116,25 +115,28 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
private CompetitorResults cachedConfirmedPositionedCompetitors;
private CourseBase cachedCourseDesign;
private Wind cachedWindFix;
private RaceLogResolver raceLogResolver;
private ReadonlyRaceStateImpl(RaceLog raceLog, RacingProcedureFactory procedureFactory) {
this(raceLog, new RaceStatusAnalyzer.StandardClock(), procedureFactory, /* update */ true);
private ReadonlyRaceStateImpl(RaceLogResolver raceLogResolver, RaceLog raceLog, RacingProcedureFactory procedureFactory) {
this(raceLogResolver, raceLog, new RaceStatusAnalyzer.StandardClock(), procedureFactory, /* update */ true);
}
/**
* @param raceLogResolver
* @param update
* if <code>true</code>, the race state will be updated whenever the underlying <code>raceLog</code>
* changes.
*/
protected ReadonlyRaceStateImpl(RaceLog raceLog, Clock analyzersClock, RacingProcedureFactory procedureFactory, boolean update) {
protected ReadonlyRaceStateImpl(RaceLogResolver raceLogResolver, RaceLog raceLog, Clock analyzersClock, RacingProcedureFactory procedureFactory, boolean update) {
this.raceLog = raceLog;
this.raceLogResolver = raceLogResolver;
this.procedureFactory = procedureFactory;
this.changedListeners = new RaceStateChangedListeners();
this.racingProcedureAnalyzer = new RacingProcedureTypeAnalyzer(raceLog);
this.statusAnalyzerClock = analyzersClock;
// status analyzer will get initialized when racing procedure is ready
this.startTimeAnalyzer = new StartTimeFinder(raceLog);
this.startTimeAnalyzer = new DependentStartTimeFinder(raceLogResolver, raceLog);
this.finishingTimeAnalyzer = new FinishingTimeFinder(raceLog);
this.finishedTimeAnalyzer = new FinishedTimeFinder(raceLog);
this.protestTimeAnalyzer = new ProtestStartTimeFinder(raceLog);
@@ -315,14 +317,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
cachedRacingProcedureType = null;
}
Pair<StartTimeFinderStatus, TimePoint> startTimeFinderResult = startTimeAnalyzer.analyze();
TimePoint startTime = null;
if (startTimeFinderResult.getA().equals(StartTimeFinderStatus.STARTTIME_FOUND)){
startTime = startTimeFinderResult.getB();
} else if (startTimeFinderResult.getA().equals(StartTimeFinderStatus.STARTTIME_DEPENDENT)){
//FIXME: fetch start time e.g. via DepedentStartTimeAnalyzer
}
TimePoint startTime = startTimeAnalyzer.analyze();
if (!Util.equalsWithNull(cachedStartTime, startTime)) {
cachedStartTime = startTime;
changedListeners.onStartTimeChanged(this);
@@ -382,7 +377,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
racingProcedure.setStateEventScheduler(scheduler);
addChangedListener(racingProcedure);
statusAnalyzer = new RaceStatusAnalyzer(raceLog, statusAnalyzerClock, racingProcedure);
statusAnalyzer = new RaceStatusAnalyzer(raceLogResolver, raceLog, statusAnalyzerClock, racingProcedure);
// let's do an update because status might have changed with new procedure
update();
}
@@ -24,6 +24,7 @@ import org.junit.Test;
import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.AdditionalScoringInformationFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.abstractlog.race.scoring.AdditionalScoringInformationType;
import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent;
import com.sap.sailing.domain.abstractlog.race.scoring.impl.RaceLogAdditionalScoringInformationEventImpl;
@@ -859,7 +860,7 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
assert event == null;
assertEquals(new Double(30), leaderboardHighPoint10Or8AndLastBreaksTie.getTotalPoints(competitors[0], later));
assertEquals(new Double(3), leaderboardHighPoint10Or8AndLastBreaksTie.getTotalPoints(competitors[9], later));
RaceState raceStateForRace2 = RaceStateImpl.create(raceLogForRace2, new LogEventAuthorImpl("Simon", 1));
RaceState raceStateForRace2 = RaceStateImpl.create(mock(RaceLogResolver.class), raceLogForRace2, new LogEventAuthorImpl("Simon", 1));
assertFalse(raceStateForRace2.isAdditionalScoringInformationEnabled(AdditionalScoringInformationType.MAX_POINTS_DECREASE_MAX_SCORE));
raceStateForRace2.setAdditionalScoringInformationEnabled(later.plus(Duration.ONE_MINUTE).plus(Duration.ONE_SECOND), /*enable*/true, AdditionalScoringInformationType.MAX_POINTS_DECREASE_MAX_SCORE);
assertTrue(raceStateForRace2.isAdditionalScoringInformationEnabled(AdditionalScoringInformationType.MAX_POINTS_DECREASE_MAX_SCORE));
@@ -19,6 +19,7 @@ Export-Package: com.sap.sailing.domain.base,
com.sap.sailing.domain.masterdataimport,
com.sap.sailing.domain.polars,
com.sap.sailing.domain.racelog,
com.sap.sailing.domain.racelog.analyzing,
com.sap.sailing.domain.racelog.impl,
com.sap.sailing.domain.racelog.tracking,
com.sap.sailing.domain.regattalike,
@@ -11,6 +11,9 @@ import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.abstractlog.shared.analyzing.RegisteredCompetitorsAnalyzer;
import com.sap.sailing.domain.base.Competitor;
@@ -22,8 +25,10 @@ import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
import com.sap.sailing.domain.leaderboard.FlexibleRaceColumn;
import com.sap.sailing.domain.leaderboard.ScoringScheme;
import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.racelog.RaceLogStore;
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
import com.sap.sailing.domain.racelog.impl.RaceLogIdentifierImpl;
import com.sap.sailing.domain.regattalike.BaseRegattaLikeImpl;
import com.sap.sailing.domain.regattalike.FlexibleLeaderboardAsRegattaLikeIdentifier;
import com.sap.sailing.domain.regattalike.IsRegattaLike;
@@ -291,4 +296,15 @@ public class FlexibleLeaderboardImpl extends AbstractLeaderboardImpl implements
result.addAll(viaLog);
return result;
}
@Override
public RaceLog getRacelog(SimpleRaceLogIdentifier identifier) throws RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException {
if (!identifier.getRegattaLikeParentName().equals(this.getName())){
throw new RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException();
}
RaceLogIdentifier raceLogIdentifier = new RaceLogIdentifierImpl(regattaLikeHelper.getRegattaLikeIdentifier(), identifier.getRaceColumnName(), identifier.getFleetName());
return raceLogStore.getRaceLog(raceLogIdentifier, true);
}
}
@@ -3,6 +3,9 @@ package com.sap.sailing.domain.leaderboard.impl;
import java.util.ArrayList;
import java.util.List;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseArea;
@@ -114,4 +117,16 @@ public class RegattaLeaderboardImpl extends AbstractLeaderboardImpl implements R
public IsRegattaLike getRegattaLike() {
return regatta;
}
@Override
public RaceLog getRacelog(SimpleRaceLogIdentifier identifier) throws RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException {
if (!identifier.getRegattaLikeParentName().equals(this.getName())){
throw new RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException();
}
RaceColumnInSeries raceColumn = getRaceColumnByName(identifier.getRaceColumnName());
Fleet fleet = raceColumn.getFleetByName(identifier.getFleetName());
return raceColumn.getRaceLog(fleet);
}
}
@@ -2,8 +2,8 @@ package com.sap.sailing.domain.racelog;
import java.io.Serializable;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
import com.sap.sailing.domain.regattalike.RegattaLikeIdentifier;
import com.sap.sse.common.Util;
/**
* This interfaces serves as a template for the actual RaceLogIdentifier that is compound as follows:
@@ -11,15 +11,7 @@ import com.sap.sse.common.Util;
* {LeaderboardName / RegattaName} + RaceColumnName + FleetName
* <p>
*/
public interface RaceLogIdentifier extends Serializable {
String getRaceColumnName();
String getFleetName();
public interface RaceLogIdentifier extends Serializable, SimpleRaceLogIdentifier {
RegattaLikeIdentifier getRegattaLikeParent();
Util.Triple<String, String, String> getIdentifier();
String getDeprecatedIdentifier();
}
@@ -0,0 +1,26 @@
package com.sap.sailing.domain.racelog.analyzing;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException;
import com.sap.sailing.domain.regattalike.HasRegattaLike;
public class ServerSideRaceLogResolver implements RaceLogResolver {
private HasRegattaLike regattaLike;
public ServerSideRaceLogResolver(HasRegattaLike regattaLike) {
this.regattaLike = regattaLike;
}
@Override
public RaceLog resolve(SimpleRaceLogIdentifier identifier) throws RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException {
if (regattaLike == null){
return null;
}
return regattaLike.getRacelog(identifier);
}
}
@@ -1,50 +1,26 @@
package com.sap.sailing.domain.racelog.impl;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifierImpl;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.regattalike.RegattaLikeIdentifier;
public class RaceLogIdentifierImpl implements RaceLogIdentifier {
public class RaceLogIdentifierImpl extends SimpleRaceLogIdentifierImpl implements RaceLogIdentifier {
private static final long serialVersionUID = -1933109112840405951L;
private final String raceColumnName;
private final String fleetName;
private final RegattaLikeIdentifier regattaLikeParent;
public RaceLogIdentifierImpl(RegattaLikeIdentifier regattaLikeParent, String raceColumnName, Fleet fleet) {
this(regattaLikeParent, raceColumnName, fleet.getName());
}
public RaceLogIdentifierImpl(RegattaLikeIdentifier regattaLikeParent, String raceColumnName, String fleetName) {
super(regattaLikeParent.getName(), raceColumnName, fleetName);
this.regattaLikeParent = regattaLikeParent;
this.raceColumnName = raceColumnName;
this.fleetName = fleet.getName();
}
@Override
public com.sap.sse.common.Util.Triple<String, String, String> getIdentifier() {
return new com.sap.sse.common.Util.Triple<String, String, String>(
regattaLikeParent.getName(), raceColumnName, fleetName);
}
@Override
public String getDeprecatedIdentifier() {
return String.format("%s.%s.%s",
regattaLikeParent.getName(),
raceColumnName,
fleetName);
}
@Override
public RegattaLikeIdentifier getRegattaLikeParent() {
return regattaLikeParent;
}
@Override
public String getRaceColumnName() {
return raceColumnName;
}
@Override
public String getFleetName() {
return fleetName;
}
}
@@ -5,7 +5,7 @@ import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
public class FlexibleLeaderboardAsRegattaLikeIdentifier implements RegattaLikeIdentifier {
private static final long serialVersionUID = -2770908733100377885L;
private final String leaderboardName;
public FlexibleLeaderboardAsRegattaLikeIdentifier(FlexibleLeaderboard leaderboard) {
this.leaderboardName = leaderboard.getName();
}
@@ -44,7 +44,7 @@ public class FlexibleLeaderboardAsRegattaLikeIdentifier implements RegattaLikeId
return false;
return true;
}
@Override
public String getIdentifierType() {
return FlexibleLeaderboard.class.getName();
@@ -1,5 +1,8 @@
package com.sap.sailing.domain.regattalike;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
@@ -12,4 +15,6 @@ import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
*/
public interface HasRegattaLike {
IsRegattaLike getRegattaLike();
RaceLog getRacelog(SimpleRaceLogIdentifier identifier) throws RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException;
}
@@ -16,10 +16,9 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogWindFixEvent;
import com.sap.sailing.domain.abstractlog.race.SuppressedMarkPassingsEvent;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.AbortingFlagFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.DependentStartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.LastPublishedCourseDesignFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.MarkPassingDataFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderStatus;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.WindFixesFinder;
import com.sap.sailing.domain.abstractlog.race.impl.BaseRaceLogEventVisitor;
import com.sap.sailing.domain.base.Competitor;
@@ -30,9 +29,9 @@ import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.domain.common.impl.WindSourceImpl;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.domain.markpassingcalculation.MarkPassingUpdateListener;
import com.sap.sailing.domain.racelog.analyzing.ServerSideRaceLogResolver;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.Util.Triple;
/**
@@ -50,7 +49,7 @@ public class DynamicTrackedRaceLogListener extends BaseRaceLogEventVisitor {
private final WindSource raceCommitteeWindSource;
private LastPublishedCourseDesignFinder courseDesignFinder;
private StartTimeFinder startTimeFinder;
private DependentStartTimeFinder startTimeFinder;
private AbortingFlagFinder abortingFlagFinder;
private MarkPassingDataFinder markPassingDataFinder;
@@ -70,7 +69,8 @@ public class DynamicTrackedRaceLogListener extends BaseRaceLogEventVisitor {
trackedRace.invalidateStartTime();
trackedRace.invalidateEndTime();
courseDesignFinder = new LastPublishedCourseDesignFinder(raceLog);
startTimeFinder = new StartTimeFinder(raceLog);
//FIXME: how to get the HasRegattaLike?
startTimeFinder = new DependentStartTimeFinder(new ServerSideRaceLogResolver(null), raceLog);
abortingFlagFinder = new AbortingFlagFinder(raceLog);
initializeWindTrack(raceLog);
analyze();
@@ -163,18 +163,8 @@ public class DynamicTrackedRaceLogListener extends BaseRaceLogEventVisitor {
private void analyzeStartTime(TimePoint startTimeProvidedByEvent) {
/* start time will be set by StartTimeFinder in TrackedRace.getStartTime() */
trackedRace.invalidateStartTime();
Pair<StartTimeFinderStatus, TimePoint> startTimeFinderResult = startTimeFinder.analyze();
TimePoint startTime = null;
if (startTimeFinderResult.getA().equals(StartTimeFinderStatus.STARTTIME_FOUND)) {
startTime = startTimeFinderResult.getB();
} else if (startTimeFinderResult.getA().equals(StartTimeFinderStatus.STARTTIME_DEPENDENT)) {
//FIXME: bug2467: get dependentStartTime e.g. via DependentStartTimeAnalyzer
}
TimePoint startTime = startTimeFinder.analyze();
if (startTime == null) {
startTime = startTimeProvidedByEvent;
@@ -37,8 +37,7 @@ import com.sap.sailing.domain.abstractlog.AbstractLogEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogGateLineOpeningTimeEvent;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderStatus;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.DependentStartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogGateLineOpeningTimeEventImpl;
import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState;
import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateImpl;
@@ -104,6 +103,7 @@ import com.sap.sailing.domain.confidence.ConfidenceFactory;
import com.sap.sailing.domain.markpassingcalculation.MarkPassingCalculator;
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
import com.sap.sailing.domain.polars.PolarDataService;
import com.sap.sailing.domain.racelog.analyzing.ServerSideRaceLogResolver;
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
@@ -675,13 +675,8 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
if (startTime == null) {
for (RaceLog raceLog : attachedRaceLogs.values()) {
Pair<StartTimeFinderStatus, TimePoint> startTimeFinderResult = new StartTimeFinder(raceLog).analyze();
if (startTimeFinderResult.getA().equals(StartTimeFinderStatus.STARTTIME_FOUND)){
startTime = startTimeFinderResult.getB();
} else if (startTimeFinderResult.getA().equals(StartTimeFinderStatus.STARTTIME_DEPENDENT)){
//FIXME: fetch start time e.g. via DepedentStartTimeAnalyzer
}
//FIXME: how to get the HasRegattaLike?
startTime = new DependentStartTimeFinder(new ServerSideRaceLogResolver(null), raceLog).analyze();
if (startTime != null) {
break;
}
@@ -2991,7 +2986,8 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
synchronized (raceStates) {
result = raceStates.get(raceLog);
if (result == null) {
result = RaceStateImpl.create(raceLog);
//FIXME: how to get the corresponding RegattaLike?
result = RaceStateImpl.create(new ServerSideRaceLogResolver(null), raceLog);
raceStates.put(raceLog, result);
}
}
@@ -231,6 +231,7 @@ import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
import com.sap.sailing.domain.polars.PolarDataService;
import com.sap.sailing.domain.racelog.RaceLogStore;
import com.sap.sailing.domain.racelog.RaceStateOfSameDayHelper;
import com.sap.sailing.domain.racelog.analyzing.ServerSideRaceLogResolver;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifierStringSerializationHandler;
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
@@ -829,13 +830,19 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
return raceColumnDTOs;
}
private RaceInfoDTO createRaceInfoDTO(String seriesName, RaceColumn raceColumn, Fleet fleet) {
private RaceInfoDTO createRaceInfoDTO(Leaderboard leaderboard, String seriesName, RaceColumn raceColumn, Fleet fleet) {
RaceInfoDTO raceInfoDTO = new RaceInfoDTO();
RaceLog raceLog = raceColumn.getRaceLog(fleet);
if (raceLog != null) {
raceInfoDTO.isTracked = raceColumn.getTrackedRace(fleet) != null ? true : false;
ReadonlyRaceState state = ReadonlyRaceStateImpl.create(raceLog);
HasRegattaLike regattaLike = null;
if (leaderboard instanceof HasRegattaLike){
regattaLike = (HasRegattaLike) leaderboard;
}
ReadonlyRaceState state = ReadonlyRaceStateImpl.create(new ServerSideRaceLogResolver(regattaLike), raceLog);
TimePoint startTime = state.getStartTime();
if (startTime != null) {
@@ -4137,7 +4144,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
}
entry.regattaDisplayName = regattaName;
entry.regattaName = leaderboard.getName();
entry.raceInfo = createRaceInfoDTO(seriesName, raceColumn, fleet);
entry.raceInfo = createRaceInfoDTO(leaderboard, seriesName, raceColumn, fleet);
entry.currentServerTime = new Date();
if (showOnlyRacesOfSameDay) {
@@ -9,6 +9,7 @@ import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifierImpl;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
@@ -36,7 +37,7 @@ public class RaceLogDependentStartTimeEventDeserializer extends RaceLogRaceStatu
RaceLogRaceStatusEvent event = (RaceLogRaceStatusEvent) super.deserialize(object, id, createdAt, author, timePoint, passId, competitors);
SimpleRaceLogIdentifier dependentOnRace = new SimpleRaceLogIdentifier(regattaLikeParentName, raceColumnName, fleetName);
SimpleRaceLogIdentifier dependentOnRace = new SimpleRaceLogIdentifierImpl(regattaLikeParentName, raceColumnName, fleetName);
return factory.createDependentStartTimeEvent(event.getCreatedAt(), author, event.getLogicalTimePoint(), event.getId(), event.getInvolvedBoats(),
event.getPassId(), dependentOnRace, startTimeDifference);
@@ -57,10 +57,10 @@ public class EventRaceStatesSerializer implements JsonSerializer<Pair<Event, Ite
result.put(FIELD_EVENT_ID, event.getId().toString());
JSONArray raceStatesLogEntriesJson = new JSONArray();
result.put(FIELD_RACE_STATES, raceStatesLogEntriesJson);
RaceStateSerializer raceStateSerializer = new RaceStateSerializer();
for (CourseArea courseArea : event.getVenue().getCourseAreas()) {
if(filterByCourseArea == null || courseArea.getName().equals(filterByCourseArea)) {
for (Leaderboard leaderboard : leaderboards) {
RaceStateSerializer raceStateSerializer = new RaceStateSerializer(leaderboard);
if (filterByLeaderboardName == null || leaderboard.getName().equals(filterByLeaderboardName)) {
if (leaderboard.getDefaultCourseArea() != null && leaderboard.getDefaultCourseArea().equals(courseArea)) {
String leaderboardName = leaderboard.getName();
@@ -7,10 +7,9 @@ import org.json.simple.JSONObject;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogFlagEvent;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.AbortingFlagFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.DependentStartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.FinishedTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.LastFlagsFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderStatus;
import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState;
import com.sap.sailing.domain.abstractlog.race.state.impl.ReadonlyRaceStateImpl;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.gate.ReadonlyGateStartRacingProcedure;
@@ -18,12 +17,23 @@ import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.racelog.RaceStateOfSameDayHelper;
import com.sap.sailing.domain.racelog.analyzing.ServerSideRaceLogResolver;
import com.sap.sailing.domain.regattalike.HasRegattaLike;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util.Pair;
public class RaceStateSerializer implements JsonSerializer<Pair<RaceColumn, Fleet>> {
private HasRegattaLike regattaLike = null;
public RaceStateSerializer(Leaderboard leaderboard) {
if (leaderboard instanceof HasRegattaLike){
regattaLike = (HasRegattaLike) leaderboard;
}
}
@Override
public JSONObject serialize(Pair<RaceColumn, Fleet> raceColumnAndFleet) {
RaceColumn raceColumn = raceColumnAndFleet.getA();
@@ -37,7 +47,7 @@ public class RaceStateSerializer implements JsonSerializer<Pair<RaceColumn, Flee
result.put("trackedRaceId", raceIdentifier != null ? raceIdentifier.toString() : null);
RaceLog raceLog = raceColumn.getRaceLog(fleet);
if (raceLog != null && !raceLog.isEmpty()) {
ReadonlyRaceState state = ReadonlyRaceStateImpl.create(raceLog);
ReadonlyRaceState state = ReadonlyRaceStateImpl.create(new ServerSideRaceLogResolver(regattaLike),raceLog);
RaceLogRaceStatus status = state.getStatus();
TimePoint startTime = state.getStartTime();
TimePoint finishedTime = state.getFinishedTime();
@@ -79,14 +89,7 @@ public class RaceStateSerializer implements JsonSerializer<Pair<RaceColumn, Flee
boolean result = false;
RaceLog raceLog = raceColumn.getRaceLog(fleet);
if (raceLog != null && !raceLog.isEmpty()) {
Pair<StartTimeFinderStatus, TimePoint> startTimeFinderResult = new StartTimeFinder(raceLog).analyze();
TimePoint startTime = null;
if (startTimeFinderResult.getA().equals(StartTimeFinderStatus.STARTTIME_FOUND)){
startTime = startTimeFinderResult.getB();
} else if (startTimeFinderResult.getA().equals(StartTimeFinderStatus.STARTTIME_DEPENDENT)){
//FIXME: fetch start time e.g. via DepedentStartTimeAnalyzer
}
TimePoint startTime = new DependentStartTimeFinder(new ServerSideRaceLogResolver(regattaLike), raceLog).analyze();
TimePoint finishedTime = new FinishedTimeFinder(raceLog).analyze();
RaceLogFlagEvent abortingFlagEvent = new AbortingFlagFinder(raceLog).analyze();
@@ -130,8 +130,10 @@ import com.sap.sailing.domain.persistence.racelog.tracking.MongoGPSFixStoreFacto
import com.sap.sailing.domain.polars.PolarDataService;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.racelog.RaceLogStore;
import com.sap.sailing.domain.racelog.analyzing.ServerSideRaceLogResolver;
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.domain.regattalike.HasRegattaLike;
import com.sap.sailing.domain.regattalike.IsRegattaLike;
import com.sap.sailing.domain.regattalike.LeaderboardThatHasRegattaLike;
import com.sap.sailing.domain.regattalog.RegattaLogStore;
@@ -2884,16 +2886,24 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
String authorName, int authorPriority, int passId, TimePoint logicalTimePoint, TimePoint startTime,
RacingProcedureType racingProcedure) {
RaceLog raceLog = getRaceLog(leaderboardName, raceColumnName, fleetName);
if (raceLog != null) {
RaceState state = RaceStateImpl.create(raceLog, new LogEventAuthorImpl(authorName, authorPriority));
if (passId > raceLog.getCurrentPassId()) {
state.setAdvancePass(logicalTimePoint);
}
state.setRacingProcedure(logicalTimePoint, racingProcedure);
state.forceNewStartTime(logicalTimePoint, startTime);
return state.getStartTime();
Leaderboard leaderboard = getLeaderboardByName(leaderboardName);
if (!(leaderboard instanceof HasRegattaLike)){
return null;
}
return null;
if (raceLog == null) {
return null;
}
RaceState state = RaceStateImpl.create(new ServerSideRaceLogResolver((HasRegattaLike) leaderboard), raceLog,
new LogEventAuthorImpl(authorName, authorPriority));
if (passId > raceLog.getCurrentPassId()) {
state.setAdvancePass(logicalTimePoint);
}
state.setRacingProcedure(logicalTimePoint, racingProcedure);
state.forceNewStartTime(logicalTimePoint, startTime);
return state.getStartTime();
}
public RaceLog getRaceLog(String leaderboardName, String raceColumnName, String fleetName) {
@@ -2912,12 +2922,22 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
public com.sap.sse.common.Util.Triple<TimePoint, Integer, RacingProcedureType> getStartTimeAndProcedure(
String leaderboardName, String raceColumnName, String fleetName) {
RaceLog raceLog = getRaceLog(leaderboardName, raceColumnName, fleetName);
if (raceLog != null) {
ReadonlyRaceState state = ReadonlyRaceStateImpl.create(raceLog);
return new com.sap.sse.common.Util.Triple<TimePoint, Integer, RacingProcedureType>(state.getStartTime(),
raceLog.getCurrentPassId(), state.getRacingProcedure().getType());
Leaderboard leaderboard = getLeaderboardByName(leaderboardName);
if (!(leaderboard instanceof HasRegattaLike)){
return null;
}
return null;
if (raceLog == null) {
return null;
}
ReadonlyRaceState state = ReadonlyRaceStateImpl.create(new ServerSideRaceLogResolver(
(HasRegattaLike) leaderboard), raceLog);
return new com.sap.sse.common.Util.Triple<TimePoint, Integer, RacingProcedureType>(state.getStartTime(),
raceLog.getCurrentPassId(), state.getRacingProcedure().getType());
}
private Iterable<WindTrackerFactory> getWindTrackerFactories() {
@@ -0,0 +1,23 @@
package com.sap.sailing.racecommittee.app.data;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException;
public class AndroidRaceLogResolver implements RaceLogResolver {
@Override
public RaceLog resolve(SimpleRaceLogIdentifier identifier)
throws RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException {
//has to check against local as well as online racelog events
//FIXME: somehow get the ManagedRace belonging to identifier in order to get the RaceLog
//InMemoryDataStore.INSTANCE.(new ManagedRaceIdentifierImpl(identifier.getRaceColumnName(), new FleetIdentifier(
return null;
}
}
@@ -110,7 +110,7 @@ public class OfflineDataManager extends DataManager {
ManagedRace q1 = new ManagedRaceImpl(
new ManagedRaceIdentifierImpl("A.B", new FleetImpl("A"), qualifying, raceGroup),
RaceStateImpl.create(log, AppPreferences.on(context).getAuthor(), configuration));
RaceStateImpl.create(new AndroidRaceLogResolver(), log, AppPreferences.on(context).getAuthor(), configuration));
log = new RaceLogImpl(UUID.randomUUID());
/*
@@ -120,7 +120,7 @@ public class OfflineDataManager extends DataManager {
ManagedRace q2 = new ManagedRaceImpl(
new ManagedRaceIdentifierImpl("B", new FleetImpl("A.A"), qualifying, raceGroup),
RaceStateImpl.create(log, AppPreferences.on(context).getAuthor(), configuration));
RaceStateImpl.create(new AndroidRaceLogResolver(), log, AppPreferences.on(context).getAuthor(), configuration));
log = new RaceLogImpl(UUID.randomUUID());
/*
@@ -129,7 +129,7 @@ public class OfflineDataManager extends DataManager {
*/
ManagedRace q3 = new ManagedRaceImpl(
new ManagedRaceIdentifierImpl("Q3", new FleetImpl("Default"), qualifying, raceGroup),
RaceStateImpl.create(log, AppPreferences.on(context).getAuthor(), configuration));
RaceStateImpl.create(new AndroidRaceLogResolver(), log, AppPreferences.on(context).getAuthor(), configuration));
/*
* ManagedRace m1 = new ManagedRaceImpl( new ManagedRaceIdentifierImpl( "M1", new FleetImpl("Default"), medal,
* raceGroup), null);
@@ -20,6 +20,7 @@ import com.sap.sailing.domain.base.racegroup.RaceCell;
import com.sap.sailing.domain.base.racegroup.RaceGroup;
import com.sap.sailing.domain.base.racegroup.RaceRow;
import com.sap.sailing.domain.base.racegroup.SeriesWithRows;
import com.sap.sailing.racecommittee.app.data.AndroidRaceLogResolver;
import com.sap.sailing.racecommittee.app.domain.FleetIdentifier;
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
import com.sap.sailing.racecommittee.app.domain.ManagedRaceIdentifier;
@@ -79,7 +80,7 @@ public class ManagedRacesDataParser implements DataParser<Collection<ManagedRace
}
FleetIdentifier fleetIdentifier = new FleetIdentifierImpl(fleet, series, raceGroup);
ManagedRaceIdentifier identifier = new ManagedRaceIdentifierImpl(name, fleetIdentifier);
RaceState state = RaceStateImpl.create(raceLog, author, configurationLoader);
RaceState state = RaceStateImpl.create(new AndroidRaceLogResolver(), raceLog, author, configurationLoader);
return new ManagedRaceImpl(identifier, state);
}
@@ -11,12 +11,11 @@ import android.widget.Button;
import android.widget.TimePicker;
import android.widget.Toast;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderStatus;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.DependentStartTimeFinder;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.data.AndroidRaceLogResolver;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.impl.MillisecondsTimePoint;
public class RaceFinishingTimeDialog extends RaceDialogFragment {
@@ -34,20 +33,8 @@ public class RaceFinishingTimeDialog extends RaceDialogFragment {
private void setAndAnnounceFinishedTime() {
TimePoint finishingTime = getFinishingTime();
StartTimeFinder stf = new StartTimeFinder(getRace().getRaceLog());
Pair<StartTimeFinderStatus, TimePoint> startTimeFinderResult = stf.analyze();
if (startTimeFinderResult.getA().equals(StartTimeFinderStatus.STARTTIME_UNKNOWN)){
return;
}
TimePoint startTime;
if (startTimeFinderResult.getA().equals(StartTimeFinderStatus.STARTTIME_FOUND)){
startTime = startTimeFinderResult.getB();
} else { //DependentStartTime
//FIXME: bug2467 fetch dependentStartTime via DependentStartTimeAnalyzer
startTime = MillisecondsTimePoint.now();
}
DependentStartTimeFinder dependentStartTimeFinder = new DependentStartTimeFinder(new AndroidRaceLogResolver(), getRace().getRaceLog());
TimePoint startTime = dependentStartTimeFinder.analyze();
if (getRace().getStatus().equals(RaceLogRaceStatus.RUNNING)) {
if (startTime.before(finishingTime)) {