mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-27 07:56:38 +00:00
Merge remote-tracking branch 'origin/master' into bug3719_windstatus
This commit is contained in:
+2
-1
@@ -15,7 +15,8 @@ public enum FleetColors {
|
||||
PURPLE (212, 28, 175, 0),
|
||||
NEON_GREEN (118, 255, 33, 0),
|
||||
ORANGE (255, 174, 23, 0),
|
||||
WHITE (250, 250, 250, 0);
|
||||
WHITE (250, 250, 250, 0),
|
||||
PINK(255,105,180, 0);
|
||||
|
||||
private Color color;
|
||||
|
||||
|
||||
+94
-20
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.domain.racelog.state.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -15,6 +16,7 @@ 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.impl.RaceLogDependentStartTimeEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogPassChangeEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartTimeEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.SimpleRaceLogIdentifierImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.state.RaceState;
|
||||
@@ -22,6 +24,7 @@ import com.sap.sailing.domain.abstractlog.race.state.RaceStateChangedListener;
|
||||
import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState;
|
||||
import com.sap.sailing.domain.abstractlog.race.state.impl.BaseRaceStateChangedListener;
|
||||
import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedureFactory;
|
||||
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.impl.RacingProcedureFactoryImpl;
|
||||
import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
|
||||
import com.sap.sailing.domain.base.configuration.RegattaConfiguration;
|
||||
@@ -32,13 +35,24 @@ import com.sap.sse.common.impl.MillisecondsDurationImpl;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
public class DependentRaceStateTest {
|
||||
private static class RaceStateImplWithPublicRaceStateToObserve extends RaceStateImpl {
|
||||
public RaceStateImplWithPublicRaceStateToObserve(RaceLogResolver raceLogResolver, RaceLog raceLog,
|
||||
AbstractLogEventAuthor author, RacingProcedureFactory procedureFactory) {
|
||||
super(raceLogResolver, raceLog, author, procedureFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadonlyRaceState getRaceStateToObserve() {
|
||||
return super.getRaceStateToObserve();
|
||||
}
|
||||
}
|
||||
|
||||
private RaceLog raceLogA;
|
||||
private RaceLog raceLogB;
|
||||
private RaceLog raceLogC;
|
||||
|
||||
private RaceState stateA;
|
||||
private RaceState stateB;
|
||||
private RaceStateImplWithPublicRaceStateToObserve stateB;
|
||||
private RaceState stateC;
|
||||
|
||||
private RaceStateChangedListener listenerA;
|
||||
@@ -56,17 +70,13 @@ public class DependentRaceStateTest {
|
||||
public void setUp() {
|
||||
author = new LogEventAuthorImpl("Test", 1);
|
||||
configuration = new EmptyRegattaConfiguration();
|
||||
|
||||
raceLogA = new RaceLogImpl("raceLogA");
|
||||
raceLogB = new RaceLogImpl("raceLogB");
|
||||
raceLogC = new RaceLogImpl("raceLogC");
|
||||
|
||||
listenerA = mock(RaceStateChangedListener.class);
|
||||
listenerB = mock(RaceStateChangedListener.class);
|
||||
listenerC = mock(RaceStateChangedListener.class);
|
||||
|
||||
nowMock = mock(TimePoint.class);
|
||||
|
||||
raceLogResolver = new RaceLogResolver() {
|
||||
@Override
|
||||
public RaceLog resolve(SimpleRaceLogIdentifier identifier) {
|
||||
@@ -79,14 +89,9 @@ public class DependentRaceStateTest {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
stateA = new RaceStateImpl(raceLogResolver, raceLogA, author, new RacingProcedureFactoryImpl(author,
|
||||
configuration));
|
||||
stateB = new RaceStateImpl(raceLogResolver, raceLogB, author, new RacingProcedureFactoryImpl(author,
|
||||
configuration));
|
||||
stateC = new RaceStateImpl(raceLogResolver, raceLogC, author, new RacingProcedureFactoryImpl(author,
|
||||
configuration));
|
||||
|
||||
stateA = new RaceStateImpl(raceLogResolver, raceLogA, author, new RacingProcedureFactoryImpl(author, configuration));
|
||||
stateB = new RaceStateImplWithPublicRaceStateToObserve(raceLogResolver, raceLogB, author, new RacingProcedureFactoryImpl(author, configuration));
|
||||
stateC = new RaceStateImpl(raceLogResolver, raceLogC, author, new RacingProcedureFactoryImpl(author, configuration));
|
||||
stateA.addChangedListener(listenerA);
|
||||
stateB.addChangedListener(listenerB);
|
||||
stateC.addChangedListener(listenerC);
|
||||
@@ -96,13 +101,10 @@ public class DependentRaceStateTest {
|
||||
public void testCorrectAmountOfStartTimeChanges() {
|
||||
raceLogC.add(new RaceLogDependentStartTimeEventImpl(nowMock, nowMock, author, "12", 12,
|
||||
new SimpleRaceLogIdentifierImpl("B", "", ""), new MillisecondsDurationImpl(5000), RaceLogRaceStatus.SCHEDULED));
|
||||
|
||||
raceLogB.add(new RaceLogDependentStartTimeEventImpl(nowMock, nowMock, author, "12", 12,
|
||||
new SimpleRaceLogIdentifierImpl("A", "", ""), new MillisecondsDurationImpl(5000), RaceLogRaceStatus.SCHEDULED));
|
||||
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
raceLogA.add(new RaceLogStartTimeEventImpl(now, now, author, "12", 12, new MillisecondsTimePoint(5000), RaceLogRaceStatus.SCHEDULED));
|
||||
|
||||
verify(listenerC, times(3)).onStartTimeChanged(stateC);
|
||||
verify(listenerB, times(2)).onStartTimeChanged(stateB);
|
||||
verify(listenerA, times(1)).onStartTimeChanged(stateA);
|
||||
@@ -131,17 +133,89 @@ public class DependentRaceStateTest {
|
||||
public void testCorrectAmountOfStartTimeChanges2() {
|
||||
raceLogC.add(new RaceLogDependentStartTimeEventImpl(nowMock, nowMock, author, "12", 12,
|
||||
new SimpleRaceLogIdentifierImpl("B", "", ""), new MillisecondsDurationImpl(5000), RaceLogRaceStatus.SCHEDULED));
|
||||
|
||||
raceLogB.add(new RaceLogDependentStartTimeEventImpl(nowMock, nowMock, author, "12", 12,
|
||||
new SimpleRaceLogIdentifierImpl("A", "", ""), new MillisecondsDurationImpl(5000), RaceLogRaceStatus.SCHEDULED));
|
||||
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
raceLogA.add(new RaceLogStartTimeEventImpl(now, now, author, "12", 12, new MillisecondsTimePoint(5000), RaceLogRaceStatus.SCHEDULED));
|
||||
|
||||
raceLogB.add(new RaceLogStartTimeEventImpl(now, now, author, "12", 12, new MillisecondsTimePoint(20000), RaceLogRaceStatus.SCHEDULED));
|
||||
|
||||
verify(listenerA, times(1)).onStartTimeChanged(stateA);
|
||||
verify(listenerB, times(3)).onStartTimeChanged(stateB);
|
||||
verify(listenerC, times(4)).onStartTimeChanged(stateC);
|
||||
}
|
||||
|
||||
/**
|
||||
* See bug 3740; when the current pass has an absolute start time, adding a relative start time
|
||||
* to a prior pass late must not lead to the race state observing the race state of the race that
|
||||
* the no longer valid dependent start time specification depended upon.
|
||||
*/
|
||||
@Test
|
||||
public void testLateDeliveryOfDependentStartTimeForPriorPass() {
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
raceLogA.add(new RaceLogStartTimeEventImpl(now, now, author, /* ID */ "1", /* pass */ 0, new MillisecondsTimePoint( 5000), RaceLogRaceStatus.SCHEDULED));
|
||||
raceLogB.add(new RaceLogStartTimeEventImpl(now, now, author, /* ID */ "2", /* pass */ 0, new MillisecondsTimePoint(10000), RaceLogRaceStatus.SCHEDULED));
|
||||
// now B enters a new pass:
|
||||
raceLogB.add(new RaceLogPassChangeEventImpl(now.plus(1000), author, /* pass */ 1));
|
||||
// this is expected to reset B's start time:
|
||||
assertNull(stateB.getStartTime());
|
||||
// now B receives an absolute start time definition for pass 1 (the second pass):
|
||||
raceLogB.add(new RaceLogStartTimeEventImpl(now.plus(1000), now.plus(1000), author, /* ID */ "3", /* pass */ 1, new MillisecondsTimePoint(20000), RaceLogRaceStatus.SCHEDULED));
|
||||
assertEquals(new MillisecondsTimePoint( 5000), stateA.getStartTime());
|
||||
assertEquals(new MillisecondsTimePoint(20000), stateB.getStartTime());
|
||||
// here comes a late event for B's pass 0, setting a relative start time; it is expected to not
|
||||
// have any effect on B's current start time because B is already in pass 1; furthermore, it is
|
||||
// expected to not have an effect on the observing relationship. No observer relationship is to
|
||||
// be established from B to A; in particular, updating A's start time is expected to leave B's
|
||||
// start time unmodified.
|
||||
raceLogB.add(new RaceLogDependentStartTimeEventImpl(now.plus(500), now.plus(500), author, /* ID */ "4", /* pass */ 0,
|
||||
new SimpleRaceLogIdentifierImpl("A", "", ""), new MillisecondsDurationImpl(5000), RaceLogRaceStatus.SCHEDULED));
|
||||
|
||||
// verify that B's race state is *not* observing A's race state
|
||||
assertNull(stateB.getRaceStateToObserve());
|
||||
|
||||
// B's absolute start time in pass 1 is expected to remain unchanged
|
||||
assertEquals(new MillisecondsTimePoint(20000), stateB.getStartTime());
|
||||
// moving A's start time is expected to NOT move B's start time:
|
||||
raceLogA.add(new RaceLogStartTimeEventImpl(now.plus(10000), now.plus(10000), author, /* ID */ "5", /* pass */ 0,
|
||||
/* new start time */ new MillisecondsTimePoint(20000), RaceLogRaceStatus.SCHEDULED));
|
||||
assertEquals(new MillisecondsTimePoint(20000), stateA.getStartTime());
|
||||
assertEquals(new MillisecondsTimePoint(20000), stateB.getStartTime()); // no update to B's start time expected
|
||||
}
|
||||
|
||||
/**
|
||||
* See bug 3740; the current pass is set up such that it has a relative start time; then we assume
|
||||
* that an absolute start time for a prior pass is delivered late. Now it's important that this does
|
||||
* not lead to the dependent race state stopping to observe the race state it depends upon.
|
||||
*/
|
||||
@Test
|
||||
public void testLateDeliveryOfAbsoluteStartTimeForPrioPass() {
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
raceLogA.add(new RaceLogStartTimeEventImpl(now, now, author, /* ID */ "1", /* pass */ 0, new MillisecondsTimePoint( 5000), RaceLogRaceStatus.SCHEDULED));
|
||||
raceLogB.add(new RaceLogStartTimeEventImpl(now, now, author, /* ID */ "2", /* pass */ 0, new MillisecondsTimePoint(10000), RaceLogRaceStatus.SCHEDULED));
|
||||
// now B enters a new pass:
|
||||
raceLogB.add(new RaceLogPassChangeEventImpl(now.plus(1000), author, /* pass */ 1));
|
||||
// this is expected to reset B's start time:
|
||||
assertNull(stateB.getStartTime());
|
||||
// now B receives a start time definition relative to that of A:
|
||||
raceLogB.add(new RaceLogDependentStartTimeEventImpl(now.plus(2000), now.plus(2000), author, /* ID */ "3", /* pass */ 1,
|
||||
new SimpleRaceLogIdentifierImpl("A", "", ""), new MillisecondsDurationImpl(5000), RaceLogRaceStatus.SCHEDULED));
|
||||
assertEquals(new MillisecondsTimePoint( 5000), stateA.getStartTime());
|
||||
assertEquals(stateA.getStartTime().plus(5000), stateB.getStartTime()); // B is expected to have a start time 5s after that of A due to its relative start time
|
||||
// moving A's start time is expected to move B's start time:
|
||||
raceLogA.add(new RaceLogStartTimeEventImpl(now.plus(10000), now.plus(10000), author, /* ID */ "4", /* pass */ 0,
|
||||
/* new start time */ new MillisecondsTimePoint(20000), RaceLogRaceStatus.SCHEDULED));
|
||||
assertEquals(new MillisecondsTimePoint(20000), stateA.getStartTime());
|
||||
assertEquals(stateA.getStartTime().plus(5000), stateB.getStartTime()); // B is expected to have a start time 5s after that of A due to its relative start time
|
||||
// here comes a late event for B's pass 0, updating the absolute start time; it is expected to not
|
||||
// have any effect on B's current start time because B is already in pass 1; furthermore, it is
|
||||
// expected to not have an effect on the observing relationship: when updating A's start time
|
||||
// later, B's relative start time is expected to still update.
|
||||
raceLogB.add(new RaceLogStartTimeEventImpl(now.plus(10), now.plus(10), author, /* ID */ "5", /* pass */ 0, new MillisecondsTimePoint(11000), RaceLogRaceStatus.SCHEDULED));
|
||||
assertEquals(stateA.getStartTime().plus(5000), stateB.getStartTime()); // B is expected to still have a start time 5s after that of A due to its relative start time
|
||||
// move A's start time to then check that B's still relative start time has moved as well, testing the
|
||||
// continued existence of the observer relationship:
|
||||
raceLogA.add(new RaceLogStartTimeEventImpl(now.plus(11000), now.plus(11000), author, /* ID */ "6", /* pass */ 0,
|
||||
/* new start time */ new MillisecondsTimePoint(30000), RaceLogRaceStatus.SCHEDULED));
|
||||
assertEquals(new MillisecondsTimePoint(30000), stateA.getStartTime());
|
||||
assertEquals(stateA.getStartTime().plus(5000), stateB.getStartTime()); // B is expected to still have a start time 5s after that of A due to its relative start time
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -7,6 +7,14 @@ import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
/**
|
||||
* The result of a {@link StartTimeFinder} that tells about the dependencies through which the start time
|
||||
* may be resolved from other races, reasons for the failure to resolve a start time and the actual start
|
||||
* time as obtained immediately or transitively through a chain of dependencies.
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public class StartTimeFinderResult {
|
||||
public static enum ResolutionFailed { RACE_LOG_UNRESOLVED, CYCLIC_DEPENDENCY, NO_START_TIME_SET };
|
||||
|
||||
@@ -40,6 +48,9 @@ public class StartTimeFinderResult {
|
||||
this(/* racesDependingOn */ Collections.<SimpleRaceLogIdentifier>emptyList(), startTime, startTimeDiff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code null} if the start time was resolved; a reason for failure to resolve otherwise
|
||||
*/
|
||||
public ResolutionFailed getResolutionFailed() {
|
||||
return resolutionFailed;
|
||||
}
|
||||
|
||||
-1
@@ -239,7 +239,6 @@ public class RaceStateImpl extends ReadonlyRaceStateImpl implements RaceState {
|
||||
@Override
|
||||
public void forceUpdate() {
|
||||
super.update();
|
||||
registerListenerOnDependentRaceIfDependentStartTime(Collections.<SimpleRaceLogIdentifier, ReadonlyRaceState>emptyMap());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+39
-31
@@ -9,6 +9,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogChangedListener;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogPassChangeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.ConfirmedFinishPositioningListFinder;
|
||||
@@ -218,32 +219,24 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
|
||||
} else {
|
||||
dependentRaceStatesAndMe = dependentRaceStates;
|
||||
}
|
||||
registerListenerOnDependentRaceIfDependentStartTime(dependentRaceStatesAndMe);
|
||||
}
|
||||
|
||||
protected void registerListenerOnDependentRaceIfDependentStartTime(Map<SimpleRaceLogIdentifier, ReadonlyRaceState> dependentRaceStates) {
|
||||
// Check whether the latest known StartTimeEvent is a non-dependent or dependent start time in case of a
|
||||
// dependent startTime setup listeners
|
||||
this.raceLog.lockForRead();
|
||||
try {
|
||||
for (RaceLogEvent event : this.raceLog.getFixesDescending()) {
|
||||
if (event instanceof RaceLogStartTimeEvent) {
|
||||
break;
|
||||
} else if (event instanceof RaceLogDependentStartTimeEvent) {
|
||||
setupListenersOnDependentRace(event, dependentRaceStates);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
this.raceLog.unlockAfterRead();
|
||||
}
|
||||
adjustObserverForRelativeStartTime();
|
||||
}
|
||||
|
||||
protected ReadonlyRaceState getRaceStateToObserve() {
|
||||
return raceStateToObserve;
|
||||
}
|
||||
|
||||
protected RacingProcedureType determineInitialProcedureType() {
|
||||
// Let's ensure there is a valid RacingProcedureType set, since a RaceState cannot live without a
|
||||
// RacingProcedure we need to have a fallback
|
||||
RegattaConfiguration configuration = getConfiguration();
|
||||
RacingProcedureType inRaceLogType = racingProcedureAnalyzer.analyze();
|
||||
return determineInitialProcedureType(inRaceLogType);
|
||||
}
|
||||
|
||||
private RacingProcedureType determineInitialProcedureType(RacingProcedureType inRaceLogType) {
|
||||
RegattaConfiguration configuration = getConfiguration();
|
||||
if (inRaceLogType != RacingProcedureType.UNKNOWN) {
|
||||
return inRaceLogType;
|
||||
} else {
|
||||
@@ -366,28 +359,40 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
|
||||
|
||||
@Override
|
||||
public void eventAdded(RaceLogEvent event) {
|
||||
// FIXME the start time analyzer should be used to find out about the new start time dependency situation
|
||||
if (event instanceof RaceLogDependentStartTimeEvent) {
|
||||
// FIXME add the listener only if the dependent start time event belongs to the current pass
|
||||
setupListenersOnDependentRace(event, Collections.<SimpleRaceLogIdentifier, ReadonlyRaceState>emptyMap());
|
||||
} else if (event instanceof RaceLogStartTimeEvent) {
|
||||
// FIXME only remove the change listener if the RaceLogStartTimeEvent belongs to the current pass
|
||||
if (raceStateToObserve != null) {
|
||||
raceStateToObserve.removeChangedListener(raceStateToObserveListener);
|
||||
raceStateToObserve = null;
|
||||
}
|
||||
// if a pass change or a start time-setting event, the observer relation to a race state of a
|
||||
// race on which this race state's race's start time has depended or now depends needs to be
|
||||
// re-assessed, and the observer relation needs to be established or canceled, respectively.
|
||||
if (event instanceof RaceLogDependentStartTimeEvent ||
|
||||
event instanceof RaceLogStartTimeEvent ||
|
||||
event instanceof RaceLogPassChangeEvent) {
|
||||
adjustObserverForRelativeStartTime();
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
private void setupListenersOnDependentRace(RaceLogEvent event, Map<SimpleRaceLogIdentifier, ReadonlyRaceState> dependentRaceStates) {
|
||||
private void adjustObserverForRelativeStartTime() {
|
||||
final StartTimeFinderResult startTimeAnalysisResult = startTimeAnalyzer.analyze();
|
||||
adjustObserverForRelativeStartTime(startTimeAnalysisResult);
|
||||
}
|
||||
|
||||
private void adjustObserverForRelativeStartTime(final StartTimeFinderResult startTimeAnalysisResult) {
|
||||
if (startTimeAnalysisResult.isDependentStartTime()) {
|
||||
setupListenersOnDependentRace(startTimeAnalysisResult, Collections.<SimpleRaceLogIdentifier, ReadonlyRaceState>emptyMap());
|
||||
} else if (raceStateToObserve != null) {
|
||||
raceStateToObserve.removeChangedListener(raceStateToObserveListener);
|
||||
raceStateToObserve = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void setupListenersOnDependentRace(StartTimeFinderResult startTimeAnalysisResult, Map<SimpleRaceLogIdentifier, ReadonlyRaceState> dependentRaceStates) {
|
||||
assert startTimeAnalysisResult.isDependentStartTime();
|
||||
assert !Util.isEmpty(startTimeAnalysisResult.getDependingOnRaces());
|
||||
if (raceStateToObserve != null) {
|
||||
// Remove previous listeners
|
||||
raceStateToObserve.removeChangedListener(raceStateToObserveListener);
|
||||
raceStateToObserve = null;
|
||||
}
|
||||
RaceLogDependentStartTimeEvent dependentStartTimeEvent = (RaceLogDependentStartTimeEvent) event;
|
||||
final SimpleRaceLogIdentifier dependentOnRaceIdentifier = dependentStartTimeEvent.getDependentOnRaceIdentifier();
|
||||
final SimpleRaceLogIdentifier dependentOnRaceIdentifier = startTimeAnalysisResult.getDependingOnRaces().iterator().next();
|
||||
if (dependentRaceStates.containsKey(dependentOnRaceIdentifier)) {
|
||||
raceStateToObserve = dependentRaceStates.get(dependentOnRaceIdentifier);
|
||||
raceStateToObserve.addChangedListener(raceStateToObserveListener);
|
||||
@@ -415,6 +420,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
|
||||
RacingProcedureType type = racingProcedureAnalyzer.analyze();
|
||||
if (!Util.equalsWithNull(cachedRacingProcedureType, type) && type != RacingProcedureType.UNKNOWN) {
|
||||
cachedRacingProcedureType = type;
|
||||
cachedRacingProcedureTypeNoFallback = determineInitialProcedureType(type);
|
||||
recreateRacingProcedure();
|
||||
changedListeners.onRacingProcedureChanged(this);
|
||||
}
|
||||
@@ -431,6 +437,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
|
||||
changedListeners.onAdvancePass(this);
|
||||
// reset racing procedure to force recreate on next event!
|
||||
cachedRacingProcedureType = null;
|
||||
cachedRacingProcedureTypeNoFallback = null;
|
||||
}
|
||||
|
||||
StartTimeFinderResult startTimeFinderResult = startTimeAnalyzer.analyze();
|
||||
@@ -438,6 +445,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
|
||||
cachedStartTimeFinderResult = startTimeFinderResult;
|
||||
changedListeners.onStartTimeChanged(this);
|
||||
}
|
||||
adjustObserverForRelativeStartTime(startTimeFinderResult);
|
||||
|
||||
TimePoint finishingTime = finishingTimeAnalyzer.analyze();
|
||||
if (!Util.equalsWithNull(cachedFinishingTime, finishingTime)) {
|
||||
|
||||
+3
-3
@@ -6,7 +6,7 @@ import com.sap.sailing.domain.abstractlog.BaseLogAnalyzer;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
||||
import com.sap.sse.common.WithID;
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@ public class OpenEndedDeviceMappingFinder extends BaseLogAnalyzer<RegattaLog, Re
|
||||
@Override
|
||||
protected Serializable performAnalysis() {
|
||||
for (RegattaLogEvent regattaLogEvent : log.getUnrevokedEvents()) {
|
||||
if (regattaLogEvent instanceof RegattaLogDeviceCompetitorMappingEvent) {
|
||||
RegattaLogDeviceCompetitorMappingEvent deviceMappingEvent = (RegattaLogDeviceCompetitorMappingEvent) regattaLogEvent;
|
||||
if (regattaLogEvent instanceof RegattaLogDeviceMappingEvent<?>) {
|
||||
RegattaLogDeviceMappingEvent<?> deviceMappingEvent = (RegattaLogDeviceMappingEvent<?>) regattaLogEvent;
|
||||
if (deviceMappingEvent.getMappedTo().equals(mappedTo) &&
|
||||
deviceMappingEvent.getDevice().getStringRepresentation().equals(deviceUuid)) {
|
||||
return deviceMappingEvent.getId();
|
||||
|
||||
+2
-3
@@ -6,11 +6,10 @@ import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sse.common.Color;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.IsManagedByCache;
|
||||
import com.sap.sse.common.Named;
|
||||
import com.sap.sse.common.WithID;
|
||||
import com.sap.sse.common.NamedWithID;
|
||||
import com.sap.sse.datamining.annotations.Connector;
|
||||
|
||||
public interface Competitor extends Named, WithID, IsManagedByCache<SharedDomainFactory> {
|
||||
public interface Competitor extends NamedWithID, IsManagedByCache<SharedDomainFactory> {
|
||||
@Connector(messageKey="Team", ordinal=9)
|
||||
Team getTeam();
|
||||
|
||||
|
||||
+2
-3
@@ -1,8 +1,7 @@
|
||||
package com.sap.sailing.domain.base;
|
||||
|
||||
import com.sap.sse.common.Named;
|
||||
import com.sap.sse.common.WithID;
|
||||
import com.sap.sse.common.NamedWithID;
|
||||
|
||||
public interface ControlPoint extends WithID, Named {
|
||||
public interface ControlPoint extends NamedWithID {
|
||||
Iterable<Mark> getMarks();
|
||||
}
|
||||
|
||||
+3
-4
@@ -3,16 +3,15 @@ package com.sap.sailing.domain.base;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.sap.sse.common.IsManagedByCache;
|
||||
import com.sap.sse.common.Named;
|
||||
import com.sap.sse.common.WithID;
|
||||
import com.sap.sse.common.NamedWithID;
|
||||
|
||||
/**
|
||||
* A named area in a sailing {@link Venue} where races take place. Usually, the areas carry names according to the NATO
|
||||
* alphabet, such as "Alpha", "Bravo" or "Charlie".
|
||||
* alphabet, such as "Alpha", "Bravo" or "Charly".
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public interface CourseArea extends Named, WithID, IsManagedByCache<SharedDomainFactory> {
|
||||
public interface CourseArea extends NamedWithID, IsManagedByCache<SharedDomainFactory> {
|
||||
UUID getId();
|
||||
}
|
||||
|
||||
+2
-3
@@ -5,9 +5,8 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.common.Renamable;
|
||||
import com.sap.sse.common.Named;
|
||||
import com.sap.sse.common.NamedWithID;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.WithID;
|
||||
import com.sap.sse.common.media.ImageSize;
|
||||
import com.sap.sse.shared.media.WithMedia;
|
||||
|
||||
@@ -15,7 +14,7 @@ import com.sap.sse.shared.media.WithMedia;
|
||||
* Base interface for an Event consisting of all static information, which might be shared
|
||||
* by the server and an Android application.
|
||||
*/
|
||||
public interface EventBase extends Named, WithDescription, Renamable, WithID, WithMedia {
|
||||
public interface EventBase extends NamedWithID, WithDescription, Renamable, WithMedia {
|
||||
|
||||
void setDescription(String description);
|
||||
|
||||
|
||||
+2
-2
@@ -3,9 +3,9 @@ package com.sap.sailing.domain.base;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.sap.sailing.domain.common.Renamable;
|
||||
import com.sap.sse.common.WithID;
|
||||
import com.sap.sse.common.NamedWithID;
|
||||
|
||||
public interface LeaderboardGroupBase extends Renamable, WithID {
|
||||
public interface LeaderboardGroupBase extends Renamable, NamedWithID {
|
||||
UUID getId();
|
||||
String getDescription();
|
||||
void setDescriptiom(String description);
|
||||
|
||||
+1
-2
@@ -2,7 +2,6 @@ package com.sap.sailing.domain.base;
|
||||
|
||||
import com.sap.sailing.domain.common.MarkType;
|
||||
import com.sap.sse.common.IsManagedByCache;
|
||||
import com.sap.sse.common.WithID;
|
||||
|
||||
|
||||
/**
|
||||
@@ -12,7 +11,7 @@ import com.sap.sse.common.WithID;
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public interface Mark extends WithID, ControlPoint, IsManagedByCache<SharedDomainFactory> {
|
||||
public interface Mark extends ControlPoint, IsManagedByCache<SharedDomainFactory> {
|
||||
public String getColor();
|
||||
public String getShape();
|
||||
public String getPattern();
|
||||
|
||||
+4
-4
@@ -1,13 +1,13 @@
|
||||
package com.sap.sailing.domain.base;
|
||||
|
||||
import com.sap.sse.common.Named;
|
||||
import com.sap.sse.common.WithID;
|
||||
import com.sap.sse.common.NamedWithID;
|
||||
|
||||
/**
|
||||
* A side line in a race course
|
||||
* @author Frank (C5163874)
|
||||
*
|
||||
* @author Frank Mittag (C5163874)
|
||||
*
|
||||
*/
|
||||
public interface Sideline extends Named, WithID {
|
||||
public interface Sideline extends NamedWithID {
|
||||
Iterable<Mark> getMarks();
|
||||
}
|
||||
|
||||
+2
-3
@@ -3,8 +3,7 @@ package com.sap.sailing.domain.base;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.PassingInstruction;
|
||||
import com.sap.sse.common.IsManagedByCache;
|
||||
import com.sap.sse.common.Named;
|
||||
import com.sap.sse.common.WithID;
|
||||
import com.sap.sse.common.NamedWithID;
|
||||
|
||||
/**
|
||||
* Waypoints constitute {@link Course}s and demarcate their {@link Leg}s. A waypoint's position is defined by a
|
||||
@@ -14,7 +13,7 @@ import com.sap.sse.common.WithID;
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public interface Waypoint extends Named, WithID, IsManagedByCache<SharedDomainFactory> {
|
||||
public interface Waypoint extends NamedWithID, IsManagedByCache<SharedDomainFactory> {
|
||||
ControlPoint getControlPoint();
|
||||
|
||||
Iterable<Mark> getMarks();
|
||||
|
||||
+2
-4
@@ -2,7 +2,7 @@ package com.sap.sailing.domain.tractracadapter;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.sap.sse.common.WithID;
|
||||
import com.sap.sse.common.NamedWithID;
|
||||
import com.tractrac.model.lib.api.event.IEvent;
|
||||
import com.tractrac.model.lib.api.route.IControlPoint;
|
||||
|
||||
@@ -14,14 +14,12 @@ import com.tractrac.model.lib.api.route.IControlPoint;
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public interface TracTracControlPoint extends WithID {
|
||||
public interface TracTracControlPoint extends NamedWithID {
|
||||
/**
|
||||
* Refining the return type helps in looking up a control point by its UUID in {@link IEvent}.
|
||||
*/
|
||||
UUID getId();
|
||||
|
||||
String getName();
|
||||
|
||||
String getMetadata();
|
||||
|
||||
String getShortName();
|
||||
|
||||
+1
@@ -6,6 +6,7 @@ import com.sap.sailing.domain.tractracadapter.TracTracControlPoint;
|
||||
import com.tractrac.model.lib.api.route.IControl;
|
||||
|
||||
public class ControlPointAdapter extends AbstractWithID implements TracTracControlPoint {
|
||||
private static final long serialVersionUID = 1012632574166553433L;
|
||||
private final IControl controlPoint;
|
||||
|
||||
public ControlPointAdapter(IControl controlPoint) {
|
||||
|
||||
@@ -3,8 +3,7 @@ package com.sap.sailing.domain.base;
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.sap.sailing.domain.common.RaceCompetitorIdsAsStringWithMD5Hash;
|
||||
import com.sap.sse.common.Named;
|
||||
import com.sap.sse.common.WithID;
|
||||
import com.sap.sse.common.NamedWithID;
|
||||
|
||||
/**
|
||||
* Tells the {@link BoatClass boat class} and the {@link Course course} for a single race that is usually part of a
|
||||
@@ -18,7 +17,7 @@ import com.sap.sse.common.WithID;
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public interface RaceDefinition extends Named, WithID {
|
||||
public interface RaceDefinition extends NamedWithID {
|
||||
BoatClass getBoatClass();
|
||||
|
||||
Course getCourse();
|
||||
|
||||
@@ -12,9 +12,8 @@ import com.sap.sailing.domain.regattalike.IsRegattaLike;
|
||||
import com.sap.sailing.domain.tracking.RaceExecutionOrderProvider;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.TrackedRegatta;
|
||||
import com.sap.sse.common.Named;
|
||||
import com.sap.sse.common.NamedWithID;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.WithID;
|
||||
|
||||
/**
|
||||
* The name shall be unique across all regattas tracked concurrently. In particular, if you want to keep apart regattas
|
||||
@@ -23,7 +22,7 @@ import com.sap.sse.common.WithID;
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public interface Regatta extends Named, WithID, IsRegattaLike, HasRaceColumnsAndRegattaLike {
|
||||
public interface Regatta extends NamedWithID, IsRegattaLike, HasRaceColumnsAndRegattaLike {
|
||||
ScoringScheme getScoringScheme();
|
||||
|
||||
/**
|
||||
|
||||
+5
@@ -140,6 +140,11 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
|
||||
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
|
||||
ois.defaultReadObject();
|
||||
raceStateBasedStartTimeChangedListener = createRaceStateStartTimeChangeListener();
|
||||
// the race states are transient, therefore not serialized; they are re-constructed here when asked for;
|
||||
// the transient raceStateBasedStartTimeChangedListener is re-added here, like it was in attachRaceLog(...)
|
||||
for (final RaceLog raceLog : attachedRaceLogs.values()) {
|
||||
getRaceState(raceLog).addChangedListener(raceStateBasedStartTimeChangedListener);
|
||||
}
|
||||
listeners = new HashSet<RaceChangeListener>();
|
||||
logListener = new DynamicTrackedRaceLogListener(this);
|
||||
courseDesignChangedListeners = new HashSet<>();
|
||||
|
||||
+1
-1
@@ -905,7 +905,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
* and not {@link Object}.
|
||||
*/
|
||||
private final String updateStartOfRaceCacheFieldsMonitor = "";
|
||||
protected void updateStartOfRaceCacheFields() {
|
||||
protected void updateStartOfRaceCacheFields() {
|
||||
synchronized (updateStartOfRaceCacheFieldsMonitor) {
|
||||
TimePoint newStartTime = null;
|
||||
TimePoint newStartTimeWithoutInferenceFromStartMarkPassings = null;
|
||||
|
||||
+1
@@ -262,6 +262,7 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
|
||||
while (table.getColumnCount() > 0) {
|
||||
table.removeColumn(0);
|
||||
}
|
||||
regattaOverviewDataProvider.removeDataDisplay(table);
|
||||
} else {
|
||||
sortInfos.add(new ColumnSortInfo(lastUpdateColumn, false));
|
||||
}
|
||||
|
||||
+4
-4
@@ -544,10 +544,10 @@ gapChangeSinceLegStartInSeconds=Gap Change
|
||||
gapChangeSinceLegStartInSecondsTooltip=The change of the gap to the leader since the last leg start.\nA negative number means that the gap was decreased;\na positive number means that it was increased.
|
||||
sideToWhichMarkAtLegStartWasRounded=Mark rounded to
|
||||
sideToWhichMarkAtLegStartWasRoundedTooltip=Side to which the mark at leg start was rounded.
|
||||
raceIsLive=Race {0} is live
|
||||
racesAreLive=Races {0} are live
|
||||
regattaIsLive=Regatta {0} is live
|
||||
regattasAreLive=Regattas {0} are live
|
||||
raceIsLive=Live race: {0}
|
||||
racesAreLive=Live races: {0}
|
||||
regattaIsLive=Live regatta: {0}
|
||||
regattasAreLive=Live regattas: {0}
|
||||
knotsUnit=kts
|
||||
knotsValue={0,number,#0.0} kts
|
||||
knotsRange={0,number,#0.0} - {1,number,#0.0} kts
|
||||
|
||||
+4
-4
@@ -538,10 +538,10 @@ gapChangeSinceLegStartInSeconds=Änderung Abstand zum Führenden
|
||||
gapChangeSinceLegStartInSecondsTooltip=Die Änderung des Abstands zum Führenden seit dem letzten Schenkelstart.\nEine negative Zahl bedeutet,\ndass sich der Abstand verringert hat; eine positive Zahl bedeutet, dass er sich vergrößert hat.
|
||||
sideToWhichMarkAtLegStartWasRounded=Tonne gerundet an
|
||||
sideToWhichMarkAtLegStartWasRoundedTooltip=Seite, an der die Bahnmarke am Schenkelstart gerundet wurde
|
||||
raceIsLive=Rennen {0} ist live
|
||||
racesAreLive=Rennen {0} sind live
|
||||
regattaIsLive=Regatta {0} ist live
|
||||
regattasAreLive=Regatten {0} sind live
|
||||
raceIsLive=Live-Rennen: {0}
|
||||
racesAreLive=Live-Rennen: {0}
|
||||
regattaIsLive=Live Regatta: {0}
|
||||
regattasAreLive=Live-Regatten: {0}
|
||||
scoringSchemeHighPointFirstGetsOne=High Point System, Gewinner erhält 1 Punkt
|
||||
scoringSchemeHighPointFirstGetsTen=High Point System, Gewinner erhält 10 Punkte
|
||||
knotsUnit=kn
|
||||
|
||||
+12
-5
@@ -59,6 +59,7 @@ import com.google.gwt.view.client.SelectionChangeEvent;
|
||||
import com.google.gwt.view.client.SelectionChangeEvent.Handler;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.InvertibleComparator;
|
||||
import com.sap.sailing.domain.common.LeaderboardNameConstants;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.common.Mile;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
@@ -97,6 +98,7 @@ import com.sap.sailing.gwt.ui.leaderboard.DetailTypeColumn.LegDetailField;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings.RaceColumnSelectionStrategies;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceTimesInfoDTO;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.common.filter.BinaryOperator;
|
||||
import com.sap.sse.common.filter.Filter;
|
||||
import com.sap.sse.common.filter.FilterSet;
|
||||
@@ -3258,17 +3260,16 @@ public class LeaderboardPanel extends SimplePanel implements Component<Leaderboa
|
||||
|
||||
public String getLiveRacesText() {
|
||||
String result = "";
|
||||
List<com.sap.sse.common.Util.Pair<RaceColumnDTO, FleetDTO>> liveRaces = leaderboard.getLiveRaces(timer.getLiveTimePointInMillis());
|
||||
List<Pair<RaceColumnDTO, FleetDTO>> liveRaces = leaderboard.getLiveRaces(timer.getLiveTimePointInMillis());
|
||||
boolean isMeta = leaderboard.type.isMetaLeaderboard();
|
||||
if (!liveRaces.isEmpty()) {
|
||||
if (liveRaces.size() == 1) {
|
||||
com.sap.sse.common.Util.Pair<RaceColumnDTO, FleetDTO> liveRace = liveRaces.get(0);
|
||||
String text = "'" + liveRace.getA().getRaceColumnName() + "'";
|
||||
String text = getLiveRaceText(liveRaces.get(0), isMeta);
|
||||
result = isMeta ? stringMessages.regattaIsLive(text) : stringMessages.raceIsLive(text);
|
||||
} else {
|
||||
String names = "";
|
||||
for (com.sap.sse.common.Util.Pair<RaceColumnDTO, FleetDTO> liveRace : liveRaces) {
|
||||
names += "'" + liveRace.getA().getRaceColumnName() + "', ";
|
||||
for (Pair<RaceColumnDTO, FleetDTO> liveRace : liveRaces) {
|
||||
names += getLiveRaceText(liveRace, isMeta) + ", ";
|
||||
}
|
||||
// remove last ", "
|
||||
names = names.substring(0, names.length() - 2);
|
||||
@@ -3278,6 +3279,12 @@ public class LeaderboardPanel extends SimplePanel implements Component<Leaderboa
|
||||
return result;
|
||||
}
|
||||
|
||||
private String getLiveRaceText(Pair<RaceColumnDTO, FleetDTO> liveRace, boolean isMeta) {
|
||||
String raceName = liveRace.getA().getRaceColumnName(), fleetName = liveRace.getB().getName();
|
||||
boolean isDefaultFleet = LeaderboardNameConstants.DEFAULT_FLEET_NAME.equals(fleetName);
|
||||
return raceName + ((isDefaultFleet || isMeta) ? "" : (" (" + liveRace.getB().getName() + ")"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDependentCssClassName() {
|
||||
return "leaderboard";
|
||||
|
||||
+66
-30
@@ -38,8 +38,10 @@ import org.json.simple.parser.ParseException;
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||
import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogCloseOpenEndedDeviceMappingEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorMappingEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceMarkMappingEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.impl.OpenEndedDeviceMappingFinder;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
@@ -82,6 +84,8 @@ import com.sap.sailing.server.gateway.jaxrs.AbstractSailingServerResource;
|
||||
import com.sap.sailing.server.gateway.serialization.coursedata.impl.MarkJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.FlatGPSFixJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.MarkJsonSerializerWithPosition;
|
||||
import com.sap.sse.common.Named;
|
||||
import com.sap.sse.common.NamedWithID;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
@@ -366,7 +370,7 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
|
||||
DomainFactory domainFactory = getService().getDomainObjectFactory().getBaseDomainFactory();
|
||||
AbstractLogEventAuthor author = new LogEventAuthorImpl(AbstractLogEventAuthor.NAME_COMPATIBILITY,
|
||||
AbstractLogEventAuthor.PRIORITY_COMPATIBILITY);
|
||||
RegattaLogDeviceCompetitorMappingEventImpl event;
|
||||
RegattaLogDeviceMappingEventImpl<? extends Named> event;
|
||||
JSONObject requestObject;
|
||||
try {
|
||||
logger.fine("Post issued to " + this.getClass().getName());
|
||||
@@ -380,7 +384,7 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
|
||||
}
|
||||
final TimePoint now = MillisecondsTimePoint.now();
|
||||
String competitorId = (String) requestObject.get(DeviceMappingConstants.JSON_COMPETITOR_ID_AS_STRING);
|
||||
// TODO alternatively, check for a markId here and then produce a RegattaLogDeviceMarkMappingEventImpl
|
||||
String markId = (String) requestObject.get(DeviceMappingConstants.JSON_MARK_ID_AS_STRING);
|
||||
String deviceUuid = (String) requestObject.get(DeviceMappingConstants.JSON_DEVICE_UUID);
|
||||
Long fromMillis = (Long) requestObject.get(DeviceMappingConstants.JSON_FROM_MILLIS);
|
||||
|
||||
@@ -388,33 +392,48 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
|
||||
// String deviceType = (String) requestObject.get(DeviceMappingConstants.JSON_DEVICE_TYPE);
|
||||
// String pushDeviceId = (String) requestObject.get(DeviceMappingConstants.JSON_PUSH_DEVICE_ID);
|
||||
|
||||
if (competitorId == null || deviceUuid == null || fromMillis == null) {
|
||||
if ((competitorId == null && markId == null) || deviceUuid == null || fromMillis == null) {
|
||||
// || deviceType == null
|
||||
logger.warning("Invalid JSON body in request");
|
||||
return Response.status(Status.BAD_REQUEST).entity("Invalid JSON body in request")
|
||||
.type(MediaType.TEXT_PLAIN).build();
|
||||
}
|
||||
// TODO: use device type and pushDeviceId
|
||||
Competitor mappedTo = domainFactory.getCompetitorStore().getExistingCompetitorByIdAsString(competitorId);
|
||||
if (mappedTo == null) {
|
||||
logger.warning("No competitor found for id " + competitorId);
|
||||
return Response.status(Status.BAD_REQUEST).entity("No competitor found for id " + StringEscapeUtils.escapeHtml(competitorId))
|
||||
.type(MediaType.TEXT_PLAIN).build();
|
||||
}
|
||||
|
||||
Set<Competitor> registered = (Set<Competitor>) hasRegattaLike.getAllCompetitors();
|
||||
if (!registered.contains(mappedTo)) {
|
||||
logger.warning("Competitor found but not registered on a race of " + leaderboardName);
|
||||
return Response.status(Status.BAD_REQUEST)
|
||||
.entity("Competitor found but not registered on a race of " + StringEscapeUtils.escapeHtml(leaderboardName))
|
||||
.type(MediaType.TEXT_PLAIN).build();
|
||||
}
|
||||
DeviceIdentifier device = new SmartphoneUUIDIdentifierImpl(UUID.fromString(deviceUuid));
|
||||
TimePoint from = new MillisecondsTimePoint(fromMillis);
|
||||
event = new RegattaLogDeviceCompetitorMappingEventImpl(now, now, author, UUID.randomUUID(), mappedTo, device,
|
||||
from, /* to */ null);
|
||||
// TODO: use device type and pushDeviceId
|
||||
final Named mappedTo;
|
||||
if (competitorId != null) {
|
||||
// map to a competitor
|
||||
final Competitor mappedToCompetitor = domainFactory.getCompetitorStore().getExistingCompetitorByIdAsString(competitorId);
|
||||
mappedTo = mappedToCompetitor;
|
||||
if (mappedToCompetitor == null) {
|
||||
logger.warning("No competitor found for id " + competitorId);
|
||||
return Response.status(Status.BAD_REQUEST).entity("No competitor found for id " + StringEscapeUtils.escapeHtml(competitorId))
|
||||
.type(MediaType.TEXT_PLAIN).build();
|
||||
}
|
||||
Set<Competitor> registered = (Set<Competitor>) hasRegattaLike.getAllCompetitors();
|
||||
if (!registered.contains(mappedToCompetitor)) {
|
||||
logger.warning("Competitor found but not registered on a race of " + leaderboardName);
|
||||
return Response.status(Status.BAD_REQUEST)
|
||||
.entity("Competitor found but not registered on a race of " + StringEscapeUtils.escapeHtml(leaderboardName))
|
||||
.type(MediaType.TEXT_PLAIN).build();
|
||||
}
|
||||
event = new RegattaLogDeviceCompetitorMappingEventImpl(now, now, author, UUID.randomUUID(), mappedToCompetitor, device,
|
||||
from, /* to */ null);
|
||||
} else {
|
||||
// map to a mark
|
||||
final Mark mappedToMark = domainFactory.getExistingMarkById(Helpers.tryUuidConversion(markId));
|
||||
mappedTo = mappedToMark;
|
||||
if (mappedToMark == null) {
|
||||
logger.warning("No mark found for id " + markId);
|
||||
return Response.status(Status.BAD_REQUEST).entity("No mark found for id " + StringEscapeUtils.escapeHtml(markId))
|
||||
.type(MediaType.TEXT_PLAIN).build();
|
||||
}
|
||||
event = new RegattaLogDeviceMarkMappingEventImpl(now, now, author, UUID.randomUUID(), mappedToMark, device,
|
||||
from, /* to */ null);
|
||||
}
|
||||
hasRegattaLike.getRegattaLike().getRegattaLog().add(event);
|
||||
logger.fine("Successfully checked in competitor " + mappedTo.getName());
|
||||
logger.fine("Successfully checked in "+((markId!=null)?"mark ":"competitor ") + mappedTo.getName());
|
||||
return Response.status(Status.OK).build();
|
||||
}
|
||||
|
||||
@@ -461,31 +480,48 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
|
||||
logger.fine("JSON requestObject is: " + requestObject.toString());
|
||||
Long toMillis = (Long) requestObject.get(DeviceMappingConstants.JSON_TO_MILLIS);
|
||||
String competitorId = (String) requestObject.get(DeviceMappingConstants.JSON_COMPETITOR_ID_AS_STRING);
|
||||
String markId = (String) requestObject.get(DeviceMappingConstants.JSON_MARK_ID_AS_STRING);
|
||||
String deviceUuid = (String) requestObject.get(DeviceMappingConstants.JSON_DEVICE_UUID);
|
||||
TimePoint closingTimePoint = new MillisecondsTimePoint(toMillis);
|
||||
if (toMillis == null || deviceUuid == null || closingTimePoint == null) {
|
||||
if (toMillis == null || deviceUuid == null || closingTimePoint == null ||
|
||||
(competitorId == null && markId == null)) {
|
||||
logger.warning("Invalid JSON body in request");
|
||||
return Response.status(Status.BAD_REQUEST).entity("Invalid JSON body in request")
|
||||
.type(MediaType.TEXT_PLAIN).build();
|
||||
}
|
||||
Competitor mappedTo = getService().getCompetitorStore().getExistingCompetitorByIdAsString(competitorId);
|
||||
if (mappedTo == null) {
|
||||
logger.warning("No competitor found for id " + competitorId);
|
||||
return Response.status(Status.BAD_REQUEST).entity("No competitor found for id " + competitorId)
|
||||
.type(MediaType.TEXT_PLAIN).build();
|
||||
final NamedWithID mappedTo;
|
||||
if (competitorId != null) {
|
||||
final Competitor mappedToCompetitor = getService().getCompetitorStore().getExistingCompetitorByIdAsString(competitorId);
|
||||
mappedTo = mappedToCompetitor;
|
||||
if (mappedToCompetitor == null) {
|
||||
logger.warning("No competitor found for id " + competitorId);
|
||||
return Response.status(Status.BAD_REQUEST).entity("No competitor found for id " + competitorId)
|
||||
.type(MediaType.TEXT_PLAIN).build();
|
||||
}
|
||||
} else {
|
||||
// map to mark
|
||||
DomainFactory domainFactory = getService().getDomainObjectFactory().getBaseDomainFactory();
|
||||
final Mark mappedToMark = domainFactory.getExistingMarkById(Helpers.tryUuidConversion(markId));
|
||||
mappedTo = mappedToMark;
|
||||
if (mappedToMark == null) {
|
||||
logger.warning("No mark found for id " + markId);
|
||||
return Response.status(Status.BAD_REQUEST).entity("No mark found for id " + markId)
|
||||
.type(MediaType.TEXT_PLAIN).build();
|
||||
}
|
||||
|
||||
}
|
||||
OpenEndedDeviceMappingFinder finder = new OpenEndedDeviceMappingFinder(isRegattaLike.getRegattaLog(), mappedTo, deviceUuid);
|
||||
Serializable deviceMappingEventId = finder.analyze();
|
||||
if (deviceMappingEventId == null) {
|
||||
logger.warning("No corresponding open competitor to device mapping has been found");
|
||||
logger.warning("No corresponding open mark to device mapping has been found");
|
||||
return Response.status(Status.BAD_REQUEST)
|
||||
.entity("No corresponding open competitor to device mapping has been found")
|
||||
.entity("No corresponding open mark to device mapping has been found")
|
||||
.type(MediaType.TEXT_PLAIN).build();
|
||||
}
|
||||
RegattaLogCloseOpenEndedDeviceMappingEventImpl event = new RegattaLogCloseOpenEndedDeviceMappingEventImpl(now,
|
||||
author, deviceMappingEventId, closingTimePoint);
|
||||
isRegattaLike.getRegattaLog().add(event);
|
||||
logger.fine("Successfully checked out competitor " + mappedTo.getName());
|
||||
logger.fine("Successfully checked out "+((markId!=null)?"mark ":"competitor ") + mappedTo.getName());
|
||||
return Response.status(Status.OK).build();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.sap.sse.common;
|
||||
|
||||
public interface NamedWithID extends Named, WithID {
|
||||
}
|
||||
@@ -12,12 +12,12 @@ import java.util.Set;
|
||||
|
||||
import org.apache.shiro.crypto.hash.Sha256Hash;
|
||||
|
||||
import com.sap.sse.common.Named;
|
||||
import com.sap.sse.common.NamedWithID;
|
||||
import com.sap.sse.common.WithID;
|
||||
import com.sap.sse.security.shared.Account;
|
||||
import com.sap.sse.security.shared.Account.AccountType;
|
||||
|
||||
public class User implements Named, WithID {
|
||||
public class User implements NamedWithID {
|
||||
private static final long serialVersionUID = 1788215575606546042L;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user