diff --git a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/StartTimeFinderTest.java b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/DependentStartTimeFinderTest.java similarity index 73% rename from java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/StartTimeFinderTest.java rename to java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/DependentStartTimeFinderTest.java index 5768666dc42..134ab872f56 100644 --- a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/StartTimeFinderTest.java +++ b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/DependentStartTimeFinderTest.java @@ -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> { +public class DependentStartTimeFinderTest extends + PassAwareRaceLogAnalyzerTest { @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.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()); } } diff --git a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/RaceStatusAnalyzerTest.java b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/RaceStatusAnalyzerTest.java index 92165c60f3b..288fa7f2f0f 100644 --- a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/RaceStatusAnalyzerTest.java +++ b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/RaceStatusAnalyzerTest.java @@ -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 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 + "]"; - } -} +} \ No newline at end of file diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/SimpleRaceLogIdentifierImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/SimpleRaceLogIdentifierImpl.java new file mode 100644 index 00000000000..51118395fcc --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/SimpleRaceLogIdentifierImpl.java @@ -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 getIdentifier() { + return new com.sap.sse.common.Util.Triple( + regattaLikeParentName, raceColumnName, fleetName); + } + + @Override + public String getDeprecatedIdentifier() { + return String.format("%s.%s.%s", + regattaLikeParentName, + raceColumnName, + fleetName); + } +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/DependentStartTimeFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/DependentStartTimeFinder.java new file mode 100644 index 00000000000..e4d2d4e1124 --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/DependentStartTimeFinder.java @@ -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 { + + 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; + } +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/DependentStartTimeResolver.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/DependentStartTimeResolver.java new file mode 100644 index 00000000000..c52ff549c5b --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/DependentStartTimeResolver.java @@ -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); + } + +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/RaceLogResolver.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/RaceLogResolver.java new file mode 100644 index 00000000000..c8e89b3ccb9 --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/RaceLogResolver.java @@ -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; +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/RaceStatusAnalyzer.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/RaceStatusAnalyzer.java index 8ebf6472059..38d35db7f2b 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/RaceStatusAnalyzer.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/RaceStatusAnalyzer.java @@ -28,15 +28,18 @@ public class RaceStatusAnalyzer extends RaceLogAnalyzer { } 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 { @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 { @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; + } }; - }; - -} +} \ No newline at end of file diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException.java new file mode 100644 index 00000000000..afbdec12ddd --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException.java @@ -0,0 +1,7 @@ +package com.sap.sailing.domain.abstractlog.race.analyzing.impl; + +public class RegataLikeNameOfIdentifierDoesntMatchActualRegattaLikeNameException extends Exception { + + private static final long serialVersionUID = -139681048270793360L; + +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/RaceStateImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/RaceStateImpl.java index bb0e11b6b90..9a2c87f0b2c 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/RaceStateImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/RaceStateImpl.java @@ -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 configuration) { - return new RaceStateImpl(raceLog, author, + public static RaceState create(RaceLogResolver raceLogResolver, RaceLog raceLog, AbstractLogEventAuthor author, ConfigurationLoader 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; } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java index 7cae3628c06..c0759d1ab28 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java @@ -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 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 true, the race state will be updated whenever the underlying raceLog * 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 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(); } diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTest.java index 47a5558bc36..4baa067182f 100644 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTest.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTest.java @@ -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)); diff --git a/java/com.sap.sailing.domain/META-INF/MANIFEST.MF b/java/com.sap.sailing.domain/META-INF/MANIFEST.MF index a3c31e2a903..a23b1496239 100755 --- a/java/com.sap.sailing.domain/META-INF/MANIFEST.MF +++ b/java/com.sap.sailing.domain/META-INF/MANIFEST.MF @@ -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, diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/FlexibleLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/FlexibleLeaderboardImpl.java index 989e468e8b9..a2185100da8 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/FlexibleLeaderboardImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/FlexibleLeaderboardImpl.java @@ -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); + } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/RegattaLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/RegattaLeaderboardImpl.java index a6df854049f..f40af5b9150 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/RegattaLeaderboardImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/RegattaLeaderboardImpl.java @@ -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); + } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/RaceLogIdentifier.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/RaceLogIdentifier.java index 82d905f27ec..2bf7f9792a2 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/RaceLogIdentifier.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/RaceLogIdentifier.java @@ -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 *

*/ -public interface RaceLogIdentifier extends Serializable { - - String getRaceColumnName(); - - String getFleetName(); +public interface RaceLogIdentifier extends Serializable, SimpleRaceLogIdentifier { RegattaLikeIdentifier getRegattaLikeParent(); - - Util.Triple getIdentifier(); - - String getDeprecatedIdentifier(); } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/analyzing/ServerSideRaceLogResolver.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/analyzing/ServerSideRaceLogResolver.java new file mode 100644 index 00000000000..c739527ba1a --- /dev/null +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/analyzing/ServerSideRaceLogResolver.java @@ -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); + } + +} diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/impl/RaceLogIdentifierImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/impl/RaceLogIdentifierImpl.java index a3c1dd39015..2fd50b4c3e2 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/impl/RaceLogIdentifierImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/impl/RaceLogIdentifierImpl.java @@ -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 getIdentifier() { - return new com.sap.sse.common.Util.Triple( - 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; - } - } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/regattalike/FlexibleLeaderboardAsRegattaLikeIdentifier.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/regattalike/FlexibleLeaderboardAsRegattaLikeIdentifier.java index 78b9c9f5864..1deab01d8ca 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/regattalike/FlexibleLeaderboardAsRegattaLikeIdentifier.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/regattalike/FlexibleLeaderboardAsRegattaLikeIdentifier.java @@ -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(); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/regattalike/HasRegattaLike.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/regattalike/HasRegattaLike.java index 0f16bb5cd18..6aef7e39997 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/regattalike/HasRegattaLike.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/regattalike/HasRegattaLike.java @@ -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; } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java index 74db1ecfa82..439868ba9fa 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java @@ -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 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; diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java index 38b5c4f7e22..9814874f231 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java @@ -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 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); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index 82f30b414be..eaab2ed8d0d 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -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) { diff --git a/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/racelog/impl/RaceLogDependentStartTimeEventDeserializer.java b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/racelog/impl/RaceLogDependentStartTimeEventDeserializer.java index f7730e8ee07..868caae5240 100644 --- a/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/racelog/impl/RaceLogDependentStartTimeEventDeserializer.java +++ b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/racelog/impl/RaceLogDependentStartTimeEventDeserializer.java @@ -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); diff --git a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/EventRaceStatesSerializer.java b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/EventRaceStatesSerializer.java index 7b3e83dc649..aabe500d131 100644 --- a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/EventRaceStatesSerializer.java +++ b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/EventRaceStatesSerializer.java @@ -57,10 +57,10 @@ public class EventRaceStatesSerializer implements JsonSerializer> { + private HasRegattaLike regattaLike = null; + + public RaceStateSerializer(Leaderboard leaderboard) { + if (leaderboard instanceof HasRegattaLike){ + regattaLike = (HasRegattaLike) leaderboard; + } + } + @Override public JSONObject serialize(Pair raceColumnAndFleet) { RaceColumn raceColumn = raceColumnAndFleet.getA(); @@ -37,7 +47,7 @@ public class RaceStateSerializer implements JsonSerializer 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(); diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java index 26625d2a944..3fc11857fa8 100755 --- a/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java +++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java @@ -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 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(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(state.getStartTime(), + raceLog.getCurrentPassId(), state.getRacingProcedure().getType()); + } private Iterable getWindTrackerFactories() { diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/AndroidRaceLogResolver.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/AndroidRaceLogResolver.java new file mode 100644 index 00000000000..639e62b8e21 --- /dev/null +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/AndroidRaceLogResolver.java @@ -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; + } + +} diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OfflineDataManager.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OfflineDataManager.java index 842466c9829..ee872ea0672 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OfflineDataManager.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OfflineDataManager.java @@ -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); diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/parsers/ManagedRacesDataParser.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/parsers/ManagedRacesDataParser.java index 41ad6204c88..e652dafcae0 100755 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/parsers/ManagedRacesDataParser.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/parsers/ManagedRacesDataParser.java @@ -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 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)) {