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.RaceLogDependentStartTimeEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent; 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.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderStatus;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util.Pair; import com.sap.sse.common.Util.Pair;
public class StartTimeFinderTest extends public class DependentStartTimeFinderTest extends
PassAwareRaceLogAnalyzerTest<StartTimeFinder, Pair<StartTimeFinderStatus, TimePoint>> { PassAwareRaceLogAnalyzerTest<DependentStartTimeFinder, TimePoint> {
@Override @Override
protected StartTimeFinder createAnalyzer(RaceLog raceLog) { protected DependentStartTimeFinder createAnalyzer(RaceLog raceLog) {
return new StartTimeFinder(raceLog); return new DependentStartTimeFinder(mock(RaceLogResolver.class), raceLog);
} }
@Override @Override
protected TargetPair getTargetEventsAndResultForPassAwareTests(int passId, AbstractLogEventAuthor author) { protected TargetPair getTargetEventsAndResultForPassAwareTests(int passId, AbstractLogEventAuthor author) {
RaceLogStartTimeEvent event = createEvent(RaceLogStartTimeEvent.class, 1, passId, author); RaceLogStartTimeEvent event = createEvent(RaceLogStartTimeEvent.class, 1, passId, author);
when(event.getStartTime()).thenReturn(mock(TimePoint.class)); when(event.getStartTime()).thenReturn(mock(TimePoint.class));
return new TargetPair(Arrays.asList(event), new Pair<StartTimeFinderStatus, TimePoint>( return new TargetPair(Arrays.asList(event), event.getStartTime());
StartTimeFinderStatus.STARTTIME_FOUND, event.getStartTime()));
} }
@Test @Test
@@ -53,8 +53,7 @@ public class StartTimeFinderTest extends
raceLog.add(event1); raceLog.add(event1);
raceLog.add(event2); raceLog.add(event2);
assertEquals(StartTimeFinderStatus.STARTTIME_FOUND, analyzer.analyze().getA()); assertEquals(event2.getStartTime(), analyzer.analyze());
assertEquals(event2.getStartTime(), analyzer.analyze().getB());
} }
@Test @Test
@@ -66,7 +65,6 @@ public class StartTimeFinderTest extends
raceLog.add(event1); raceLog.add(event1);
raceLog.add(event2); raceLog.add(event2);
assertEquals(StartTimeFinderStatus.STARTTIME_DEPENDENT, analyzer.analyze().getA()); assertNull(analyzer.analyze());
assertNull(analyzer.analyze().getB());
} }
} }
@@ -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.RaceLogEventVisitor;
import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent; 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.analyzing.impl.RaceStatusAnalyzer;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedure; import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedure;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus; import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
@@ -31,7 +32,7 @@ public class RaceStatusAnalyzerTest extends PassAwareRaceLogAnalyzerTest<RaceSta
@Override @Override
protected RaceStatusAnalyzer createAnalyzer(RaceLog raceLog) { protected RaceStatusAnalyzer createAnalyzer(RaceLog raceLog) {
return new RaceStatusAnalyzer(raceLog, racingProcedure); return new RaceStatusAnalyzer(mock(RaceLogResolver.class), raceLog, racingProcedure);
} }
@Override @Override
@@ -105,7 +106,7 @@ public class RaceStatusAnalyzerTest extends PassAwareRaceLogAnalyzerTest<RaceSta
@Test @Test
public void testClock() { public void testClock() {
final TimePoint startTime = MillisecondsTimePoint.now(); final TimePoint startTime = MillisecondsTimePoint.now();
analyzer = new RaceStatusAnalyzer(raceLog, new RaceStatusAnalyzer.Clock() { analyzer = new RaceStatusAnalyzer(mock(RaceLogResolver.class), raceLog, new RaceStatusAnalyzer.Clock() {
@Override @Override
public TimePoint now() { public TimePoint now() {
return startTime.minus(1); 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.impl.LogEventAuthorImpl;
import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogEventFactory; 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.RaceLogImpl;
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartProcedureChangedEventImpl; import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartProcedureChangedEventImpl;
import com.sap.sailing.domain.abstractlog.race.state.RaceState; import com.sap.sailing.domain.abstractlog.race.state.RaceState;
@@ -61,7 +62,7 @@ public class RaceStateTest {
listener = mock(RaceStateChangedListener.class); listener = mock(RaceStateChangedListener.class);
nowMock = mock(TimePoint.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 @Test
@@ -91,7 +92,7 @@ public class RaceStateTest {
config.setBasicConfiguration(mock(RacingProcedureConfiguration.class)); config.setBasicConfiguration(mock(RacingProcedureConfiguration.class));
configuration = mock(ConfigurationLoader.class); configuration = mock(ConfigurationLoader.class);
when(configuration.load()).thenReturn(config); 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()); assertEquals(RacingProcedureType.BASIC, state.getRacingProcedure().getType());
} }
@@ -106,7 +107,7 @@ public class RaceStateTest {
configuration = mock(ConfigurationLoader.class); configuration = mock(ConfigurationLoader.class);
when(configuration.load()).thenReturn(config); when(configuration.load()).thenReturn(config);
raceLog.add(new RaceLogStartProcedureChangedEventImpl(nowMock, author, nowMock, "12", null, 0, RacingProcedureType.ESS)); 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()); assertEquals(RacingProcedureType.ESS, state.getRacingProcedure().getType());
} }
@@ -1,33 +1,17 @@
package com.sap.sailing.domain.abstractlog.race; package com.sap.sailing.domain.abstractlog.race;
import com.sap.sse.common.Util.Triple;
public class SimpleRaceLogIdentifier{ public interface SimpleRaceLogIdentifier {
private final String regattaLikeParentName; String getRegattaLikeParentName();
private final String raceColumnName;
private final String fleetName;
public SimpleRaceLogIdentifier(String regattaLikeParentName, String raceColumnName, String fleetName) { String getRaceColumnName();
this.regattaLikeParentName = regattaLikeParentName;
this.raceColumnName = raceColumnName;
this.fleetName = fleetName;
}
public String getRegattaLikeParentName() { String getFleetName();
return regattaLikeParentName;
}
public String getRaceColumnName() { Triple<String, String, String> getIdentifier();
return raceColumnName;
}
public String getFleetName() { String getDeprecatedIdentifier();
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 final EventDispatcher eventDispatcher;
private RaceLogResolver resolver;
public RaceStatusAnalyzer(RaceLog raceLog, ReadonlyRacingProcedure racingProcedure) { public RaceStatusAnalyzer(RaceLogResolver resolver, RaceLog raceLog, ReadonlyRacingProcedure racingProcedure) {
super(raceLog); super(raceLog);
this.eventDispatcher = new EventDispatcher(new StandardClock(), racingProcedure); 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); super(raceLog);
this.eventDispatcher = new EventDispatcher(clock, racingProcedure); this.eventDispatcher = new EventDispatcher(clock, racingProcedure);
this.resolver = resolver;
} }
@Override @Override
@@ -70,10 +73,15 @@ public class RaceStatusAnalyzer extends RaceLogAnalyzer<RaceLogRaceStatus> {
@Override @Override
public void visit(RaceLogStartTimeEvent event) { public void visit(RaceLogStartTimeEvent event) {
TimePoint startTime = event.getStartTime();
setRaceLogStatusBasedOnStartTime(startTime);
}
private void setRaceLogStatusBasedOnStartTime(TimePoint startTime) {
TimePoint now = clock.now(); TimePoint now = clock.now();
if (racingProcedure.isStartphaseActive(event.getStartTime(), now)) { if (racingProcedure.isStartphaseActive(startTime, now)) {
nextStatus = RaceLogRaceStatus.STARTPHASE; nextStatus = RaceLogRaceStatus.STARTPHASE;
} else if (now.before(event.getStartTime())) { } else if (now.before(startTime)) {
nextStatus = RaceLogRaceStatus.SCHEDULED; nextStatus = RaceLogRaceStatus.SCHEDULED;
} else { } else {
nextStatus = RaceLogRaceStatus.RUNNING; nextStatus = RaceLogRaceStatus.RUNNING;
@@ -87,9 +95,13 @@ public class RaceStatusAnalyzer extends RaceLogAnalyzer<RaceLogRaceStatus> {
@Override @Override
public void visit(RaceLogDependentStartTimeEvent event) { 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.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogEventFactory; 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.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.analyzing.impl.RaceStatusAnalyzer;
import com.sap.sailing.domain.abstractlog.race.scoring.AdditionalScoringInformationType; 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.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. * 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) { public static RaceState create(RaceLogResolver raceLogResolver, RaceLog raceLog, AbstractLogEventAuthor author) {
return create(raceLog, author, new EmptyRegattaConfiguration()); return create(raceLogResolver, raceLog, author, new EmptyRegattaConfiguration());
} }
/** /**
* Creates a {@link RaceState}. * Creates a {@link RaceState}.
*/ */
public static RaceState create(RaceLog raceLog, AbstractLogEventAuthor author, ConfigurationLoader<RegattaConfiguration> configuration) { public static RaceState create(RaceLogResolver raceLogResolver, RaceLog raceLog, AbstractLogEventAuthor author, ConfigurationLoader<RegattaConfiguration> configuration) {
return new RaceStateImpl(raceLog, author, return new RaceStateImpl(raceLogResolver, raceLog, author,
RaceLogEventFactory.INSTANCE, RaceLogEventFactory.INSTANCE,
new RacingProcedureFactoryImpl(author, RaceLogEventFactory.INSTANCE, configuration)); 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) { 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) { RacingProcedureFactory procedureFactory) {
super(raceLog, analyzersClock, procedureFactory, /* update */ true); super(raceLogResolver, raceLog, analyzersClock, procedureFactory, /* update */ true);
this.author = author; this.author = author;
this.factory = eventFactory; 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.RaceLogChangedListener;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; 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.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.FinishPositioningListFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.FinishedTimeFinder; 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.FinishingTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.LastPublishedCourseDesignFinder; 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.LastWindFixFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.ProtestStartTimeFinder; 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.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.RaceStatusAnalyzer.Clock;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RacingProcedureTypeAnalyzer; 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.impl.WeakRaceLogChangedVisitor;
import com.sap.sailing.domain.abstractlog.race.state.RaceStateChangedListener; import com.sap.sailing.domain.abstractlog.race.state.RaceStateChangedListener;
import com.sap.sailing.domain.abstractlog.race.state.RaceStateEvent; 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.sailing.domain.common.racelog.RacingProcedureType;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util; 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. * 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}. * Creates a {@link ReadonlyRaceState}.
*/ */
public static ReadonlyRaceState create(RaceLog raceLog, public static ReadonlyRaceState create(RaceLogResolver raceLogResolver, RaceLog raceLog,
ConfigurationLoader<RegattaConfiguration> configurationLoader) { 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} ). * Creates a {@link ReadonlyRaceState} with an empty configuration ( {@link EmptyRegattaConfiguration} ).
*/ */
public static ReadonlyRaceState create(RaceLog raceLog) { public static ReadonlyRaceState create(RaceLogResolver raceLogResolver, RaceLog raceLog) {
return new ReadonlyRaceStateImpl(raceLog, new ReadonlyRacingProcedureFactory(new EmptyRegattaConfiguration())); return new ReadonlyRaceStateImpl(raceLogResolver, raceLog, new ReadonlyRacingProcedureFactory(new EmptyRegattaConfiguration()));
} }
/** /**
@@ -83,7 +82,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
private RaceStatusAnalyzer statusAnalyzer; private RaceStatusAnalyzer statusAnalyzer;
private final RacingProcedureTypeAnalyzer racingProcedureAnalyzer; private final RacingProcedureTypeAnalyzer racingProcedureAnalyzer;
private final StartTimeFinder startTimeAnalyzer; private final DependentStartTimeFinder startTimeAnalyzer;
private final FinishingTimeFinder finishingTimeAnalyzer; private final FinishingTimeFinder finishingTimeAnalyzer;
private final FinishedTimeFinder finishedTimeAnalyzer; private final FinishedTimeFinder finishedTimeAnalyzer;
private final ProtestStartTimeFinder protestTimeAnalyzer; private final ProtestStartTimeFinder protestTimeAnalyzer;
@@ -116,25 +115,28 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
private CompetitorResults cachedConfirmedPositionedCompetitors; private CompetitorResults cachedConfirmedPositionedCompetitors;
private CourseBase cachedCourseDesign; private CourseBase cachedCourseDesign;
private Wind cachedWindFix; private Wind cachedWindFix;
private RaceLogResolver raceLogResolver;
private ReadonlyRaceStateImpl(RaceLog raceLog, RacingProcedureFactory procedureFactory) { private ReadonlyRaceStateImpl(RaceLogResolver raceLogResolver, RaceLog raceLog, RacingProcedureFactory procedureFactory) {
this(raceLog, new RaceStatusAnalyzer.StandardClock(), procedureFactory, /* update */ true); this(raceLogResolver, raceLog, new RaceStatusAnalyzer.StandardClock(), procedureFactory, /* update */ true);
} }
/** /**
* @param raceLogResolver
* @param update * @param update
* if <code>true</code>, the race state will be updated whenever the underlying <code>raceLog</code> * if <code>true</code>, the race state will be updated whenever the underlying <code>raceLog</code>
* changes. * 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.raceLog = raceLog;
this.raceLogResolver = raceLogResolver;
this.procedureFactory = procedureFactory; this.procedureFactory = procedureFactory;
this.changedListeners = new RaceStateChangedListeners(); this.changedListeners = new RaceStateChangedListeners();
this.racingProcedureAnalyzer = new RacingProcedureTypeAnalyzer(raceLog); this.racingProcedureAnalyzer = new RacingProcedureTypeAnalyzer(raceLog);
this.statusAnalyzerClock = analyzersClock; this.statusAnalyzerClock = analyzersClock;
// status analyzer will get initialized when racing procedure is ready // 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.finishingTimeAnalyzer = new FinishingTimeFinder(raceLog);
this.finishedTimeAnalyzer = new FinishedTimeFinder(raceLog); this.finishedTimeAnalyzer = new FinishedTimeFinder(raceLog);
this.protestTimeAnalyzer = new ProtestStartTimeFinder(raceLog); this.protestTimeAnalyzer = new ProtestStartTimeFinder(raceLog);
@@ -315,14 +317,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
cachedRacingProcedureType = null; cachedRacingProcedureType = null;
} }
Pair<StartTimeFinderStatus, TimePoint> startTimeFinderResult = startTimeAnalyzer.analyze(); TimePoint startTime = 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
}
if (!Util.equalsWithNull(cachedStartTime, startTime)) { if (!Util.equalsWithNull(cachedStartTime, startTime)) {
cachedStartTime = startTime; cachedStartTime = startTime;
changedListeners.onStartTimeChanged(this); changedListeners.onStartTimeChanged(this);
@@ -382,7 +377,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
racingProcedure.setStateEventScheduler(scheduler); racingProcedure.setStateEventScheduler(scheduler);
addChangedListener(racingProcedure); 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 // let's do an update because status might have changed with new procedure
update(); update();
} }
@@ -24,6 +24,7 @@ import org.junit.Test;
import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl; import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl;
import com.sap.sailing.domain.abstractlog.race.RaceLog; 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.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.AdditionalScoringInformationType;
import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent; import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent;
import com.sap.sailing.domain.abstractlog.race.scoring.impl.RaceLogAdditionalScoringInformationEventImpl; import com.sap.sailing.domain.abstractlog.race.scoring.impl.RaceLogAdditionalScoringInformationEventImpl;
@@ -859,7 +860,7 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
assert event == null; assert event == null;
assertEquals(new Double(30), leaderboardHighPoint10Or8AndLastBreaksTie.getTotalPoints(competitors[0], later)); assertEquals(new Double(30), leaderboardHighPoint10Or8AndLastBreaksTie.getTotalPoints(competitors[0], later));
assertEquals(new Double(3), leaderboardHighPoint10Or8AndLastBreaksTie.getTotalPoints(competitors[9], 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)); 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); 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)); 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.masterdataimport,
com.sap.sailing.domain.polars, com.sap.sailing.domain.polars,
com.sap.sailing.domain.racelog, com.sap.sailing.domain.racelog,
com.sap.sailing.domain.racelog.analyzing,
com.sap.sailing.domain.racelog.impl, com.sap.sailing.domain.racelog.impl,
com.sap.sailing.domain.racelog.tracking, com.sap.sailing.domain.racelog.tracking,
com.sap.sailing.domain.regattalike, com.sap.sailing.domain.regattalike,
@@ -11,6 +11,9 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.logging.Logger; 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.regatta.RegattaLog;
import com.sap.sailing.domain.abstractlog.shared.analyzing.RegisteredCompetitorsAnalyzer; import com.sap.sailing.domain.abstractlog.shared.analyzing.RegisteredCompetitorsAnalyzer;
import com.sap.sailing.domain.base.Competitor; 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.FlexibleRaceColumn;
import com.sap.sailing.domain.leaderboard.ScoringScheme; import com.sap.sailing.domain.leaderboard.ScoringScheme;
import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule; 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.RaceLogStore;
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore; 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.BaseRegattaLikeImpl;
import com.sap.sailing.domain.regattalike.FlexibleLeaderboardAsRegattaLikeIdentifier; import com.sap.sailing.domain.regattalike.FlexibleLeaderboardAsRegattaLikeIdentifier;
import com.sap.sailing.domain.regattalike.IsRegattaLike; import com.sap.sailing.domain.regattalike.IsRegattaLike;
@@ -291,4 +296,15 @@ public class FlexibleLeaderboardImpl extends AbstractLeaderboardImpl implements
result.addAll(viaLog); result.addAll(viaLog);
return result; 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.ArrayList;
import java.util.List; 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.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseArea; import com.sap.sailing.domain.base.CourseArea;
@@ -114,4 +117,16 @@ public class RegattaLeaderboardImpl extends AbstractLeaderboardImpl implements R
public IsRegattaLike getRegattaLike() { public IsRegattaLike getRegattaLike() {
return regatta; 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 java.io.Serializable;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
import com.sap.sailing.domain.regattalike.RegattaLikeIdentifier; 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: * 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 * {LeaderboardName / RegattaName} + RaceColumnName + FleetName
* <p> * <p>
*/ */
public interface RaceLogIdentifier extends Serializable { public interface RaceLogIdentifier extends Serializable, SimpleRaceLogIdentifier {
String getRaceColumnName();
String getFleetName();
RegattaLikeIdentifier getRegattaLikeParent(); 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; 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.base.Fleet;
import com.sap.sailing.domain.racelog.RaceLogIdentifier; import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.regattalike.RegattaLikeIdentifier; 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 static final long serialVersionUID = -1933109112840405951L;
private final String raceColumnName;
private final String fleetName;
private final RegattaLikeIdentifier regattaLikeParent; private final RegattaLikeIdentifier regattaLikeParent;
public RaceLogIdentifierImpl(RegattaLikeIdentifier regattaLikeParent, String raceColumnName, Fleet fleet) { 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.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 @Override
public RegattaLikeIdentifier getRegattaLikeParent() { public RegattaLikeIdentifier getRegattaLikeParent() {
return regattaLikeParent; return regattaLikeParent;
} }
@Override
public String getRaceColumnName() {
return raceColumnName;
}
@Override
public String getFleetName() {
return fleetName;
}
} }
@@ -1,5 +1,8 @@
package com.sap.sailing.domain.regattalike; 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.base.Regatta;
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard; import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
@@ -12,4 +15,6 @@ import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
*/ */
public interface HasRegattaLike { public interface HasRegattaLike {
IsRegattaLike getRegattaLike(); 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.RaceLogWindFixEvent;
import com.sap.sailing.domain.abstractlog.race.SuppressedMarkPassingsEvent; 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.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.LastPublishedCourseDesignFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.MarkPassingDataFinder; 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.analyzing.impl.WindFixesFinder;
import com.sap.sailing.domain.abstractlog.race.impl.BaseRaceLogEventVisitor; import com.sap.sailing.domain.abstractlog.race.impl.BaseRaceLogEventVisitor;
import com.sap.sailing.domain.base.Competitor; 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.impl.WindSourceImpl;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus; import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.domain.markpassingcalculation.MarkPassingUpdateListener; 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.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.Util.Triple; import com.sap.sse.common.Util.Triple;
/** /**
@@ -50,7 +49,7 @@ public class DynamicTrackedRaceLogListener extends BaseRaceLogEventVisitor {
private final WindSource raceCommitteeWindSource; private final WindSource raceCommitteeWindSource;
private LastPublishedCourseDesignFinder courseDesignFinder; private LastPublishedCourseDesignFinder courseDesignFinder;
private StartTimeFinder startTimeFinder; private DependentStartTimeFinder startTimeFinder;
private AbortingFlagFinder abortingFlagFinder; private AbortingFlagFinder abortingFlagFinder;
private MarkPassingDataFinder markPassingDataFinder; private MarkPassingDataFinder markPassingDataFinder;
@@ -70,7 +69,8 @@ public class DynamicTrackedRaceLogListener extends BaseRaceLogEventVisitor {
trackedRace.invalidateStartTime(); trackedRace.invalidateStartTime();
trackedRace.invalidateEndTime(); trackedRace.invalidateEndTime();
courseDesignFinder = new LastPublishedCourseDesignFinder(raceLog); 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); abortingFlagFinder = new AbortingFlagFinder(raceLog);
initializeWindTrack(raceLog); initializeWindTrack(raceLog);
analyze(); analyze();
@@ -164,17 +164,7 @@ public class DynamicTrackedRaceLogListener extends BaseRaceLogEventVisitor {
/* start time will be set by StartTimeFinder in TrackedRace.getStartTime() */ /* start time will be set by StartTimeFinder in TrackedRace.getStartTime() */
trackedRace.invalidateStartTime(); trackedRace.invalidateStartTime();
TimePoint startTime = startTimeFinder.analyze();
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
}
if (startTime == null) { if (startTime == null) {
startTime = startTimeProvidedByEvent; 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.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogGateLineOpeningTimeEvent; 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.DependentStartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderStatus;
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogGateLineOpeningTimeEventImpl; 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.ReadonlyRaceState;
import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateImpl; 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.markpassingcalculation.MarkPassingCalculator;
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException; import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
import com.sap.sailing.domain.polars.PolarDataService; 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.racelog.tracking.GPSFixStore;
import com.sap.sailing.domain.racelogtracking.DeviceMapping; import com.sap.sailing.domain.racelogtracking.DeviceMapping;
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack; import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
@@ -675,13 +675,8 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
if (startTime == null) { if (startTime == null) {
for (RaceLog raceLog : attachedRaceLogs.values()) { for (RaceLog raceLog : attachedRaceLogs.values()) {
Pair<StartTimeFinderStatus, TimePoint> startTimeFinderResult = new StartTimeFinder(raceLog).analyze(); //FIXME: how to get the HasRegattaLike?
if (startTimeFinderResult.getA().equals(StartTimeFinderStatus.STARTTIME_FOUND)){ startTime = new DependentStartTimeFinder(new ServerSideRaceLogResolver(null), raceLog).analyze();
startTime = startTimeFinderResult.getB();
} else if (startTimeFinderResult.getA().equals(StartTimeFinderStatus.STARTTIME_DEPENDENT)){
//FIXME: fetch start time e.g. via DepedentStartTimeAnalyzer
}
if (startTime != null) { if (startTime != null) {
break; break;
} }
@@ -2991,7 +2986,8 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
synchronized (raceStates) { synchronized (raceStates) {
result = raceStates.get(raceLog); result = raceStates.get(raceLog);
if (result == null) { 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); 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.polars.PolarDataService;
import com.sap.sailing.domain.racelog.RaceLogStore; import com.sap.sailing.domain.racelog.RaceLogStore;
import com.sap.sailing.domain.racelog.RaceStateOfSameDayHelper; 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.DeviceIdentifier;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifierStringSerializationHandler; import com.sap.sailing.domain.racelogtracking.DeviceIdentifierStringSerializationHandler;
import com.sap.sailing.domain.racelogtracking.DeviceMapping; import com.sap.sailing.domain.racelogtracking.DeviceMapping;
@@ -829,13 +830,19 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
return raceColumnDTOs; 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(); RaceInfoDTO raceInfoDTO = new RaceInfoDTO();
RaceLog raceLog = raceColumn.getRaceLog(fleet); RaceLog raceLog = raceColumn.getRaceLog(fleet);
if (raceLog != null) { if (raceLog != null) {
raceInfoDTO.isTracked = raceColumn.getTrackedRace(fleet) != null ? true : false; 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(); TimePoint startTime = state.getStartTime();
if (startTime != null) { if (startTime != null) {
@@ -4137,7 +4144,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
} }
entry.regattaDisplayName = regattaName; entry.regattaDisplayName = regattaName;
entry.regattaName = leaderboard.getName(); entry.regattaName = leaderboard.getName();
entry.raceInfo = createRaceInfoDTO(seriesName, raceColumn, fleet); entry.raceInfo = createRaceInfoDTO(leaderboard, seriesName, raceColumn, fleet);
entry.currentServerTime = new Date(); entry.currentServerTime = new Date();
if (showOnlyRacesOfSameDay) { 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.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier; 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.domain.base.Competitor;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException; import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer; 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); 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(), return factory.createDependentStartTimeEvent(event.getCreatedAt(), author, event.getLogicalTimePoint(), event.getId(), event.getInvolvedBoats(),
event.getPassId(), dependentOnRace, startTimeDifference); event.getPassId(), dependentOnRace, startTimeDifference);
@@ -57,10 +57,10 @@ public class EventRaceStatesSerializer implements JsonSerializer<Pair<Event, Ite
result.put(FIELD_EVENT_ID, event.getId().toString()); result.put(FIELD_EVENT_ID, event.getId().toString());
JSONArray raceStatesLogEntriesJson = new JSONArray(); JSONArray raceStatesLogEntriesJson = new JSONArray();
result.put(FIELD_RACE_STATES, raceStatesLogEntriesJson); result.put(FIELD_RACE_STATES, raceStatesLogEntriesJson);
RaceStateSerializer raceStateSerializer = new RaceStateSerializer();
for (CourseArea courseArea : event.getVenue().getCourseAreas()) { for (CourseArea courseArea : event.getVenue().getCourseAreas()) {
if(filterByCourseArea == null || courseArea.getName().equals(filterByCourseArea)) { if(filterByCourseArea == null || courseArea.getName().equals(filterByCourseArea)) {
for (Leaderboard leaderboard : leaderboards) { for (Leaderboard leaderboard : leaderboards) {
RaceStateSerializer raceStateSerializer = new RaceStateSerializer(leaderboard);
if (filterByLeaderboardName == null || leaderboard.getName().equals(filterByLeaderboardName)) { if (filterByLeaderboardName == null || leaderboard.getName().equals(filterByLeaderboardName)) {
if (leaderboard.getDefaultCourseArea() != null && leaderboard.getDefaultCourseArea().equals(courseArea)) { if (leaderboard.getDefaultCourseArea() != null && leaderboard.getDefaultCourseArea().equals(courseArea)) {
String leaderboardName = leaderboard.getName(); 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.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogFlagEvent; 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.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.FinishedTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.LastFlagsFinder; 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.ReadonlyRaceState;
import com.sap.sailing.domain.abstractlog.race.state.impl.ReadonlyRaceStateImpl; import com.sap.sailing.domain.abstractlog.race.state.impl.ReadonlyRaceStateImpl;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.gate.ReadonlyGateStartRacingProcedure; 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.base.RaceColumn;
import com.sap.sailing.domain.common.RaceIdentifier; import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus; 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.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.sailing.server.gateway.serialization.JsonSerializer;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util.Pair; import com.sap.sse.common.Util.Pair;
public class RaceStateSerializer implements JsonSerializer<Pair<RaceColumn, Fleet>> { public class RaceStateSerializer implements JsonSerializer<Pair<RaceColumn, Fleet>> {
private HasRegattaLike regattaLike = null;
public RaceStateSerializer(Leaderboard leaderboard) {
if (leaderboard instanceof HasRegattaLike){
regattaLike = (HasRegattaLike) leaderboard;
}
}
@Override @Override
public JSONObject serialize(Pair<RaceColumn, Fleet> raceColumnAndFleet) { public JSONObject serialize(Pair<RaceColumn, Fleet> raceColumnAndFleet) {
RaceColumn raceColumn = raceColumnAndFleet.getA(); RaceColumn raceColumn = raceColumnAndFleet.getA();
@@ -37,7 +47,7 @@ public class RaceStateSerializer implements JsonSerializer<Pair<RaceColumn, Flee
result.put("trackedRaceId", raceIdentifier != null ? raceIdentifier.toString() : null); result.put("trackedRaceId", raceIdentifier != null ? raceIdentifier.toString() : null);
RaceLog raceLog = raceColumn.getRaceLog(fleet); RaceLog raceLog = raceColumn.getRaceLog(fleet);
if (raceLog != null && !raceLog.isEmpty()) { if (raceLog != null && !raceLog.isEmpty()) {
ReadonlyRaceState state = ReadonlyRaceStateImpl.create(raceLog); ReadonlyRaceState state = ReadonlyRaceStateImpl.create(new ServerSideRaceLogResolver(regattaLike),raceLog);
RaceLogRaceStatus status = state.getStatus(); RaceLogRaceStatus status = state.getStatus();
TimePoint startTime = state.getStartTime(); TimePoint startTime = state.getStartTime();
TimePoint finishedTime = state.getFinishedTime(); TimePoint finishedTime = state.getFinishedTime();
@@ -79,14 +89,7 @@ public class RaceStateSerializer implements JsonSerializer<Pair<RaceColumn, Flee
boolean result = false; boolean result = false;
RaceLog raceLog = raceColumn.getRaceLog(fleet); RaceLog raceLog = raceColumn.getRaceLog(fleet);
if (raceLog != null && !raceLog.isEmpty()) { if (raceLog != null && !raceLog.isEmpty()) {
Pair<StartTimeFinderStatus, TimePoint> startTimeFinderResult = new StartTimeFinder(raceLog).analyze(); TimePoint startTime = new DependentStartTimeFinder(new ServerSideRaceLogResolver(regattaLike), 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 finishedTime = new FinishedTimeFinder(raceLog).analyze(); TimePoint finishedTime = new FinishedTimeFinder(raceLog).analyze();
RaceLogFlagEvent abortingFlagEvent = new AbortingFlagFinder(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.polars.PolarDataService;
import com.sap.sailing.domain.racelog.RaceLogIdentifier; import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.racelog.RaceLogStore; 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.racelog.tracking.GPSFixStore;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier; 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.IsRegattaLike;
import com.sap.sailing.domain.regattalike.LeaderboardThatHasRegattaLike; import com.sap.sailing.domain.regattalike.LeaderboardThatHasRegattaLike;
import com.sap.sailing.domain.regattalog.RegattaLogStore; 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, String authorName, int authorPriority, int passId, TimePoint logicalTimePoint, TimePoint startTime,
RacingProcedureType racingProcedure) { RacingProcedureType racingProcedure) {
RaceLog raceLog = getRaceLog(leaderboardName, raceColumnName, fleetName); RaceLog raceLog = getRaceLog(leaderboardName, raceColumnName, fleetName);
if (raceLog != null) { Leaderboard leaderboard = getLeaderboardByName(leaderboardName);
RaceState state = RaceStateImpl.create(raceLog, new LogEventAuthorImpl(authorName, authorPriority));
if (passId > raceLog.getCurrentPassId()) { if (!(leaderboard instanceof HasRegattaLike)){
state.setAdvancePass(logicalTimePoint); return null;
}
state.setRacingProcedure(logicalTimePoint, racingProcedure);
state.forceNewStartTime(logicalTimePoint, startTime);
return state.getStartTime();
} }
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) { 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( public com.sap.sse.common.Util.Triple<TimePoint, Integer, RacingProcedureType> getStartTimeAndProcedure(
String leaderboardName, String raceColumnName, String fleetName) { String leaderboardName, String raceColumnName, String fleetName) {
RaceLog raceLog = getRaceLog(leaderboardName, raceColumnName, fleetName); RaceLog raceLog = getRaceLog(leaderboardName, raceColumnName, fleetName);
if (raceLog != null) {
ReadonlyRaceState state = ReadonlyRaceStateImpl.create(raceLog); Leaderboard leaderboard = getLeaderboardByName(leaderboardName);
return new com.sap.sse.common.Util.Triple<TimePoint, Integer, RacingProcedureType>(state.getStartTime(),
raceLog.getCurrentPassId(), state.getRacingProcedure().getType()); 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() { 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( ManagedRace q1 = new ManagedRaceImpl(
new ManagedRaceIdentifierImpl("A.B", new FleetImpl("A"), qualifying, raceGroup), 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()); log = new RaceLogImpl(UUID.randomUUID());
/* /*
@@ -120,7 +120,7 @@ public class OfflineDataManager extends DataManager {
ManagedRace q2 = new ManagedRaceImpl( ManagedRace q2 = new ManagedRaceImpl(
new ManagedRaceIdentifierImpl("B", new FleetImpl("A.A"), qualifying, raceGroup), 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()); log = new RaceLogImpl(UUID.randomUUID());
/* /*
@@ -129,7 +129,7 @@ public class OfflineDataManager extends DataManager {
*/ */
ManagedRace q3 = new ManagedRaceImpl( ManagedRace q3 = new ManagedRaceImpl(
new ManagedRaceIdentifierImpl("Q3", new FleetImpl("Default"), qualifying, raceGroup), 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, * ManagedRace m1 = new ManagedRaceImpl( new ManagedRaceIdentifierImpl( "M1", new FleetImpl("Default"), medal,
* raceGroup), null); * 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.RaceGroup;
import com.sap.sailing.domain.base.racegroup.RaceRow; import com.sap.sailing.domain.base.racegroup.RaceRow;
import com.sap.sailing.domain.base.racegroup.SeriesWithRows; 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.FleetIdentifier;
import com.sap.sailing.racecommittee.app.domain.ManagedRace; import com.sap.sailing.racecommittee.app.domain.ManagedRace;
import com.sap.sailing.racecommittee.app.domain.ManagedRaceIdentifier; 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); FleetIdentifier fleetIdentifier = new FleetIdentifierImpl(fleet, series, raceGroup);
ManagedRaceIdentifier identifier = new ManagedRaceIdentifierImpl(name, fleetIdentifier); 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); return new ManagedRaceImpl(identifier, state);
} }
@@ -11,12 +11,11 @@ import android.widget.Button;
import android.widget.TimePicker; import android.widget.TimePicker;
import android.widget.Toast; import android.widget.Toast;
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.StartTimeFinderStatus;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus; import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.racecommittee.app.R; 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.TimePoint;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.impl.MillisecondsTimePoint; import com.sap.sse.common.impl.MillisecondsTimePoint;
public class RaceFinishingTimeDialog extends RaceDialogFragment { public class RaceFinishingTimeDialog extends RaceDialogFragment {
@@ -34,20 +33,8 @@ public class RaceFinishingTimeDialog extends RaceDialogFragment {
private void setAndAnnounceFinishedTime() { private void setAndAnnounceFinishedTime() {
TimePoint finishingTime = getFinishingTime(); TimePoint finishingTime = getFinishingTime();
StartTimeFinder stf = new StartTimeFinder(getRace().getRaceLog()); DependentStartTimeFinder dependentStartTimeFinder = new DependentStartTimeFinder(new AndroidRaceLogResolver(), getRace().getRaceLog());
TimePoint startTime = dependentStartTimeFinder.analyze();
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();
}
if (getRace().getStatus().equals(RaceLogRaceStatus.RUNNING)) { if (getRace().getStatus().equals(RaceLogRaceStatus.RUNNING)) {
if (startTime.before(finishingTime)) { if (startTime.before(finishingTime)) {