Merge remote-tracking branch 'origin/master' into bug3153

This commit is contained in:
fmittag committed 2015-07-20 17:17:18 +02:00
commit 3dd9fa45aa
38 files changed
+275 -125

No files matched your search

@@ -4,6 +4,7 @@ import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.base.configuration.DeviceConfigurationMatcher; import com.sap.sailing.domain.base.configuration.DeviceConfigurationMatcher;
import com.sap.sailing.domain.common.MarkType; import com.sap.sailing.domain.common.MarkType;
import com.sap.sailing.domain.common.PassingInstruction; import com.sap.sailing.domain.common.PassingInstruction;
@@ -108,4 +109,6 @@ public interface SharedDomainFactory extends CompetitorFactory {
ControlPointWithTwoMarks getOrCreateControlPointWithTwoMarks(Serializable id, String name, Mark left, Mark right); ControlPointWithTwoMarks getOrCreateControlPointWithTwoMarks(Serializable id, String name, Mark left, Mark right);
ControlPointWithTwoMarks getOrCreateControlPointWithTwoMarks(String id, String name, Mark left, Mark right); ControlPointWithTwoMarks getOrCreateControlPointWithTwoMarks(String id, String name, Mark left, Mark right);
RaceLogResolver getRaceLogResolver();
} }
@@ -16,6 +16,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.base.BoatClass; import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CompetitorStore; import com.sap.sailing.domain.base.CompetitorStore;
@@ -106,14 +107,18 @@ public class SharedDomainFactoryImpl implements SharedDomainFactory {
private final Set<String> mayStartWithNoUpwindLeg; private final Set<String> mayStartWithNoUpwindLeg;
private final RaceLogResolver raceLogResolver;
/** /**
* Uses a transient competitor store * Uses a transient competitor store
* @param raceLogResolver TODO
*/ */
public SharedDomainFactoryImpl() { public SharedDomainFactoryImpl(RaceLogResolver raceLogResolver) {
this(new TransientCompetitorStoreImpl()); this(new TransientCompetitorStoreImpl(), raceLogResolver);
} }
public SharedDomainFactoryImpl(CompetitorStore competitorStore) { public SharedDomainFactoryImpl(CompetitorStore competitorStore, RaceLogResolver raceLogResolver) {
this.raceLogResolver = raceLogResolver;
waypointCacheReferenceQueue = new ReferenceQueue<Waypoint>(); waypointCacheReferenceQueue = new ReferenceQueue<Waypoint>();
nationalityCache = new HashMap<String, Nationality>(); nationalityCache = new HashMap<String, Nationality>();
markCache = new HashMap<Serializable, Mark>(); markCache = new HashMap<Serializable, Mark>();
@@ -386,4 +391,8 @@ public class SharedDomainFactoryImpl implements SharedDomainFactory {
return markCache.get(markIdCache.get(toStringRepresentationOfID)); return markCache.get(markIdCache.get(toStringRepresentationOfID));
} }
@Override
public RaceLogResolver getRaceLogResolver() {
return raceLogResolver;
}
} }
@@ -17,7 +17,7 @@ public class DomainFactoryTest {
@Before @Before
public void before() { public void before() {
com.sap.sailing.domain.base.DomainFactory baseDomainFactory = new com.sap.sailing.domain.base.impl.DomainFactoryImpl(); com.sap.sailing.domain.base.DomainFactory baseDomainFactory = new com.sap.sailing.domain.base.impl.DomainFactoryImpl((srlid)->null);
swissTimingDomainFactory = new com.sap.sailing.domain.swisstimingadapter.impl.DomainFactoryImpl( swissTimingDomainFactory = new com.sap.sailing.domain.swisstimingadapter.impl.DomainFactoryImpl(
baseDomainFactory); baseDomainFactory);
} }
@@ -63,7 +63,7 @@ public class CompetitorListenerTest extends AbstractSerializationTest {
@Before @Before
public void setUp() { public void setUp() {
baseDomainFactory = new DomainFactoryImpl(); baseDomainFactory = new DomainFactoryImpl((srlid)->null);
competitor = TrackBasedTest.createCompetitor("Hasso"); competitor = TrackBasedTest.createCompetitor("Hasso");
nationalityChanged = false; nationalityChanged = false;
whatChangedNationality = null; whatChangedNationality = null;
@@ -251,7 +251,7 @@ public class CompetitorListenerTest extends AbstractSerializationTest {
@Test @Test
public void testCompetitorSerializationLosesAllExternalListeners() throws ClassNotFoundException, IOException { public void testCompetitorSerializationLosesAllExternalListeners() throws ClassNotFoundException, IOException {
DomainFactory baseDomainFactory = new DomainFactoryImpl(); DomainFactory baseDomainFactory = new DomainFactoryImpl((srlid)->null);
DynamicCompetitor clonedCompetitor = cloneBySerialization(competitor, baseDomainFactory); DynamicCompetitor clonedCompetitor = cloneBySerialization(competitor, baseDomainFactory);
clonedCompetitor.setName("Dr. Hasso Plattner"); clonedCompetitor.setName("Dr. Hasso Plattner");
clonedCompetitor.getBoat().setSailId("POR 40"); clonedCompetitor.getBoat().setSailId("POR 40");
@@ -80,7 +80,7 @@ public class CourseUpdateTest extends AbstractTracTracLiveTest {
@Before @Before
public void setUp() throws MalformedURLException, IOException, InterruptedException, URISyntaxException, SubscriberInitializationException, ParseException, CreateModelException { public void setUp() throws MalformedURLException, IOException, InterruptedException, URISyntaxException, SubscriberInitializationException, ParseException, CreateModelException {
super.setUp(); super.setUp();
domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl()); domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl((srlid)->null));
domainRegatta = domainFactory.getOrCreateDefaultRegatta(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, domainRegatta = domainFactory.getOrCreateDefaultRegatta(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE,
getTracTracRace(), /* trackedRegattaRegistry */ null); getTracTracRace(), /* trackedRegattaRegistry */ null);
trackedRegatta = new DynamicTrackedRegattaImpl(domainRegatta); trackedRegatta = new DynamicTrackedRegattaImpl(domainRegatta);
@@ -118,7 +118,7 @@ public class LeaderboardCourseChangeTest {
ThresholdBasedResultDiscardingRule rule = new ThresholdBasedResultDiscardingRuleImpl(ruleRaw); ThresholdBasedResultDiscardingRule rule = new ThresholdBasedResultDiscardingRuleImpl(ruleRaw);
Leaderboard leaderboard = new RegattaLeaderboardImpl(mockedRegatta, rule); Leaderboard leaderboard = new RegattaLeaderboardImpl(mockedRegatta, rule);
DomainFactory baseDomainFactory = new DomainFactoryImpl(); DomainFactory baseDomainFactory = new DomainFactoryImpl((srlid)->null);
LeaderboardDTO leaderboardDTO = leaderboard.getLeaderboardDTO(timePoint, raceColumnNames, false, LeaderboardDTO leaderboardDTO = leaderboard.getLeaderboardDTO(timePoint, raceColumnNames, false,
trackedRegattaRegistry, baseDomainFactory, /* fillNetPointsUncorrected */ false); trackedRegattaRegistry, baseDomainFactory, /* fillNetPointsUncorrected */ false);
@@ -39,7 +39,7 @@ public class MultipleClassesInRegattaTest {
@Before @Before
public void setUp() { public void setUp() {
domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl()); domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl((srlid)->null));
} }
@Test @Test
@@ -59,7 +59,7 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
*/ */
@Test @Test
public void testHashCodeOfSerializedPairIsConsistent() throws ClassNotFoundException, IOException { public void testHashCodeOfSerializedPairIsConsistent() throws ClassNotFoundException, IOException {
DomainFactory receiverDomainFactory = new DomainFactoryImpl(); DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
final Throwable s1 = new Throwable(); final Throwable s1 = new Throwable();
final Throwable s2 = new Throwable(); final Throwable s2 = new Throwable();
com.sap.sse.common.Util.Pair<Throwable, Throwable> p = com.sap.sse.common.Util.Pair<Throwable, Throwable> p =
@@ -91,7 +91,7 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
*/ */
@Test @Test
public void testSerializingIntArray() throws ClassNotFoundException, IOException { public void testSerializingIntArray() throws ClassNotFoundException, IOException {
DomainFactory receiverDomainFactory = new DomainFactoryImpl(); DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
int[] intArray = new int[] { 5, 8 }; int[] intArray = new int[] { 5, 8 };
int[] clone = cloneBySerialization(intArray, receiverDomainFactory); int[] clone = cloneBySerialization(intArray, receiverDomainFactory);
assertTrue(Arrays.equals(intArray, clone)); assertTrue(Arrays.equals(intArray, clone));
@@ -99,7 +99,7 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
@Test @Test
public void testSerializingEventWithLeaderboardGroups() throws ClassNotFoundException, IOException { public void testSerializingEventWithLeaderboardGroups() throws ClassNotFoundException, IOException {
DomainFactory receiverDomainFactory = new DomainFactoryImpl(); DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
Event e = new EventImpl("Event Name", MillisecondsTimePoint.now(), MillisecondsTimePoint.now().plus( Event e = new EventImpl("Event Name", MillisecondsTimePoint.now(), MillisecondsTimePoint.now().plus(
Duration.ONE_DAY.times(10)), "At Home", /* is public */true, UUID.randomUUID()); Duration.ONE_DAY.times(10)), "At Home", /* is public */true, UUID.randomUUID());
LeaderboardGroup lg1 = new LeaderboardGroupImpl("LG1", "LG1 Description", /* displayName */ null, /* displayGroupsInReverseOrder */ false, Collections.<Leaderboard> emptyList()); LeaderboardGroup lg1 = new LeaderboardGroupImpl("LG1", "LG1 Description", /* displayName */ null, /* displayGroupsInReverseOrder */ false, Collections.<Leaderboard> emptyList());
@@ -117,7 +117,7 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
*/ */
@Test @Test
public void testSerializingResultDiscardingRuleImpl() throws ClassNotFoundException, IOException { public void testSerializingResultDiscardingRuleImpl() throws ClassNotFoundException, IOException {
DomainFactory receiverDomainFactory = new DomainFactoryImpl(); DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
ThresholdBasedResultDiscardingRuleImpl rdri = new ThresholdBasedResultDiscardingRuleImpl(new int[] { 5, 8 }); ThresholdBasedResultDiscardingRuleImpl rdri = new ThresholdBasedResultDiscardingRuleImpl(new int[] { 5, 8 });
ThresholdBasedResultDiscardingRuleImpl clone = cloneBySerialization(rdri, receiverDomainFactory); ThresholdBasedResultDiscardingRuleImpl clone = cloneBySerialization(rdri, receiverDomainFactory);
assertTrue(Arrays.equals(rdri.getDiscardIndexResultsStartingWithHowManyRaces(), assertTrue(Arrays.equals(rdri.getDiscardIndexResultsStartingWithHowManyRaces(),
@@ -136,7 +136,7 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
final double FACTOR = 2.0; final double FACTOR = 2.0;
overallLeaderboard.getRaceColumnByName("Test Leaderboard").setFactor(FACTOR); overallLeaderboard.getRaceColumnByName("Test Leaderboard").setFactor(FACTOR);
DomainFactory receiverDomainFactory = new DomainFactoryImpl(); DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
LeaderboardGroup clone = cloneBySerialization(leaderboardGroup, receiverDomainFactory); LeaderboardGroup clone = cloneBySerialization(leaderboardGroup, receiverDomainFactory);
assertEquals(FACTOR, overallLeaderboard.getRaceColumnByName("Test Leaderboard").getFactor(), 0.00000001); assertEquals(FACTOR, overallLeaderboard.getRaceColumnByName("Test Leaderboard").getFactor(), 0.00000001);
assertEquals(FACTOR, clone.getOverallLeaderboard().getRaceColumnByName("Test Leaderboard").getFactor(), 0.00000001); assertEquals(FACTOR, clone.getOverallLeaderboard().getRaceColumnByName("Test Leaderboard").getFactor(), 0.00000001);
@@ -144,8 +144,8 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
@Test @Test
public void testIdentityStabilityOfMarkSerialization() throws ClassNotFoundException, IOException { public void testIdentityStabilityOfMarkSerialization() throws ClassNotFoundException, IOException {
DomainFactory senderDomainFactory = new DomainFactoryImpl(); DomainFactory senderDomainFactory = new DomainFactoryImpl((srlid)->null);
DomainFactory receiverDomainFactory = new DomainFactoryImpl(); DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
Mark sendersMark1 = senderDomainFactory.getOrCreateMark("TestBuoy1"); Mark sendersMark1 = senderDomainFactory.getOrCreateMark("TestBuoy1");
Mark receiversMark1 = cloneBySerialization(sendersMark1, receiverDomainFactory); Mark receiversMark1 = cloneBySerialization(sendersMark1, receiverDomainFactory);
Mark receiversSecondCopyOfMark1 = cloneBySerialization(sendersMark1, receiverDomainFactory); Mark receiversSecondCopyOfMark1 = cloneBySerialization(sendersMark1, receiverDomainFactory);
@@ -154,8 +154,8 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
@Test @Test
public void testIdentityStabilityOfWaypointSerialization() throws ClassNotFoundException, IOException { public void testIdentityStabilityOfWaypointSerialization() throws ClassNotFoundException, IOException {
DomainFactory senderDomainFactory = new DomainFactoryImpl(); DomainFactory senderDomainFactory = new DomainFactoryImpl((srlid)->null);
DomainFactory receiverDomainFactory = new DomainFactoryImpl(); DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
Mark sendersMark1 = senderDomainFactory.getOrCreateMark("TestBuoy1"); Mark sendersMark1 = senderDomainFactory.getOrCreateMark("TestBuoy1");
Waypoint sendersWaypoint1 = senderDomainFactory.createWaypoint(sendersMark1, /*passingInstruction*/null); Waypoint sendersWaypoint1 = senderDomainFactory.createWaypoint(sendersMark1, /*passingInstruction*/null);
Waypoint receiversWaypoint1 = cloneBySerialization(sendersWaypoint1, receiverDomainFactory); Waypoint receiversWaypoint1 = cloneBySerialization(sendersWaypoint1, receiverDomainFactory);
@@ -165,8 +165,8 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
@Test @Test
public void testIdentityStabilityOfBoatClassSerialization() throws ClassNotFoundException, IOException { public void testIdentityStabilityOfBoatClassSerialization() throws ClassNotFoundException, IOException {
DomainFactory senderDomainFactory = new DomainFactoryImpl(); DomainFactory senderDomainFactory = new DomainFactoryImpl((srlid)->null);
DomainFactory receiverDomainFactory = new DomainFactoryImpl(); DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
BoatClass sendersBoatClass1 = senderDomainFactory.getOrCreateBoatClass("49er", /* typicallyStartsUpwind */ true); BoatClass sendersBoatClass1 = senderDomainFactory.getOrCreateBoatClass("49er", /* typicallyStartsUpwind */ true);
BoatClass receiversBoatClass1 = cloneBySerialization(sendersBoatClass1, receiverDomainFactory); BoatClass receiversBoatClass1 = cloneBySerialization(sendersBoatClass1, receiverDomainFactory);
BoatClass receiversSecondCopyOfBoatClass1 = cloneBySerialization(sendersBoatClass1, receiverDomainFactory); BoatClass receiversSecondCopyOfBoatClass1 = cloneBySerialization(sendersBoatClass1, receiverDomainFactory);
@@ -175,8 +175,8 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
@Test @Test
public void testIdentityStabilityOfNationalitySerialization() throws ClassNotFoundException, IOException { public void testIdentityStabilityOfNationalitySerialization() throws ClassNotFoundException, IOException {
DomainFactory senderDomainFactory = new DomainFactoryImpl(); DomainFactory senderDomainFactory = new DomainFactoryImpl((srlid)->null);
DomainFactory receiverDomainFactory = new DomainFactoryImpl(); DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
Nationality sendersNationality1 = senderDomainFactory.getOrCreateNationality("GER"); Nationality sendersNationality1 = senderDomainFactory.getOrCreateNationality("GER");
Nationality receiversNationality1 = cloneBySerialization(sendersNationality1, receiverDomainFactory); Nationality receiversNationality1 = cloneBySerialization(sendersNationality1, receiverDomainFactory);
Nationality receiversSecondCopyOfNationality1 = cloneBySerialization(sendersNationality1, receiverDomainFactory); Nationality receiversSecondCopyOfNationality1 = cloneBySerialization(sendersNationality1, receiverDomainFactory);
@@ -185,8 +185,8 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
@Test @Test
public void testIdentityStabilityOfCompetitorSerialization() throws ClassNotFoundException, IOException { public void testIdentityStabilityOfCompetitorSerialization() throws ClassNotFoundException, IOException {
DomainFactory senderDomainFactory = new DomainFactoryImpl(); DomainFactory senderDomainFactory = new DomainFactoryImpl((srlid)->null);
DomainFactory receiverDomainFactory = new DomainFactoryImpl(); DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
String competitorName = "Tina Maximiliane Lutz"; String competitorName = "Tina Maximiliane Lutz";
Competitor sendersCompetitor1 = new CompetitorImpl(123, competitorName, Color.RED, null, null, new TeamImpl("STG", Collections.singleton( Competitor sendersCompetitor1 = new CompetitorImpl(123, competitorName, Color.RED, null, null, new TeamImpl("STG", Collections.singleton(
new PersonImpl(competitorName, senderDomainFactory.getOrCreateNationality("GER"), new PersonImpl(competitorName, senderDomainFactory.getOrCreateNationality("GER"),
@@ -201,8 +201,8 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
@Test @Test
public void ensureSameObjectWrittenTwiceComesOutIdentical() throws ClassNotFoundException, IOException { public void ensureSameObjectWrittenTwiceComesOutIdentical() throws ClassNotFoundException, IOException {
final DomainFactoryImpl senderDomainFactory = new DomainFactoryImpl(); final DomainFactoryImpl senderDomainFactory = new DomainFactoryImpl((srlid)->null);
DomainFactory receiverDomainFactory = new DomainFactoryImpl(); DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
Nationality n = senderDomainFactory.getOrCreateNationality("GER"); Nationality n = senderDomainFactory.getOrCreateNationality("GER");
Object[] copies = cloneManyBySerialization(receiverDomainFactory, n, n); Object[] copies = cloneManyBySerialization(receiverDomainFactory, n, n);
assertEquals(2, copies.length); assertEquals(2, copies.length);
@@ -86,7 +86,7 @@ public abstract class OnlineTracTracBasedTest extends AbstractTracTracLiveTest {
@Before @Before
public void setUp() throws MalformedURLException, IOException, InterruptedException, URISyntaxException, ParseException, SubscriberInitializationException, CreateModelException { public void setUp() throws MalformedURLException, IOException, InterruptedException, URISyntaxException, ParseException, SubscriberInitializationException, CreateModelException {
domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl()); domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl((srlid)->null));
// keep superclass implementation from automatically setting up for a Weymouth event and force subclasses // keep superclass implementation from automatically setting up for a Weymouth event and force subclasses
// to select a race // to select a race
} }
@@ -219,7 +219,7 @@ public abstract class OnlineTracTracBasedTest extends AbstractTracTracLiveTest {
throws FileNotFoundException, MalformedURLException, URISyntaxException, SubscriberInitializationException, CreateModelException { throws FileNotFoundException, MalformedURLException, URISyntaxException, SubscriberInitializationException, CreateModelException {
super.setUp(paramUrl, liveUri, storedUri); super.setUp(paramUrl, liveUri, storedUri);
if (domainFactory == null) { if (domainFactory == null) {
domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl()); domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl((srlid)->null));
} }
domainEvent = domainFactory.getOrCreateDefaultRegatta(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, domainEvent = domainFactory.getOrCreateDefaultRegatta(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE,
getTracTracRace(), /* trackedRegattaRegistry */ null); getTracTracRace(), /* trackedRegattaRegistry */ null);
@@ -38,7 +38,7 @@ public class UnicodeCharactersInCompetitorNamesTest {
@Before @Before
public void setUp() { public void setUp() {
domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl()); domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl((srlid)->null));
} }
public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException, CreateModelException, SubscriberInitializationException { public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException, CreateModelException, SubscriberInitializationException {
@@ -23,6 +23,7 @@ import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta; import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.RegattaListener; import com.sap.sailing.domain.base.RegattaListener;
import com.sap.sailing.domain.base.Series; import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.base.Sideline; import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.SpeedWithConfidence; import com.sap.sailing.domain.base.SpeedWithConfidence;
import com.sap.sailing.domain.base.Waypoint; import com.sap.sailing.domain.base.Waypoint;
@@ -75,6 +76,7 @@ import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.domain.tracking.WindWithConfidence; import com.sap.sailing.domain.tracking.WindWithConfidence;
import com.sap.sailing.domain.tracking.impl.WindTrackImpl; import com.sap.sailing.domain.tracking.impl.WindTrackImpl;
import com.sap.sse.common.Duration; import com.sap.sse.common.Duration;
import com.sap.sse.common.IsManagedByCache;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util; import com.sap.sse.common.Util;
@@ -985,4 +987,9 @@ public class MockedTrackedRace implements DynamicTrackedRace {
public RankingMetric getRankingMetric() { public RankingMetric getRankingMetric() {
return null; return null;
} }
@Override
public IsManagedByCache<SharedDomainFactory> resolve(SharedDomainFactory domainFactory) {
return this;
}
} }
@@ -14,6 +14,7 @@ import com.sap.sailing.domain.base.Leg;
import com.sap.sailing.domain.base.Mark; import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.RaceDefinition; import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta; import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.base.Sideline; import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.SpeedWithConfidence; import com.sap.sailing.domain.base.SpeedWithConfidence;
import com.sap.sailing.domain.base.Waypoint; import com.sap.sailing.domain.base.Waypoint;
@@ -57,6 +58,7 @@ import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.domain.tracking.WindWithConfidence; import com.sap.sailing.domain.tracking.WindWithConfidence;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl; import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
import com.sap.sse.common.Duration; import com.sap.sse.common.Duration;
import com.sap.sse.common.IsManagedByCache;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util; import com.sap.sse.common.Util;
@@ -646,4 +648,9 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
@Override @Override
public void detachRaceExecutionOrderProvider(RaceExecutionOrderProvider raceExecutionOrderProvider) { public void detachRaceExecutionOrderProvider(RaceExecutionOrderProvider raceExecutionOrderProvider) {
} }
@Override
public IsManagedByCache<SharedDomainFactory> resolve(SharedDomainFactory domainFactory) {
return this;
}
} }
@@ -31,7 +31,7 @@ public interface DomainFactory extends SharedDomainFactory {
* the <code>RacingEventService.getBaseDomainFactory()</code> instead which should be the single instance used * the <code>RacingEventService.getBaseDomainFactory()</code> instead which should be the single instance used
* by all other services linked to the <code>RacingEventService</code>. * by all other services linked to the <code>RacingEventService</code>.
*/ */
static DomainFactory INSTANCE = new DomainFactoryImpl(); static DomainFactory INSTANCE = new DomainFactoryImpl((srlid)->null);
MarkPassing createMarkPassing(TimePoint timePoint, Waypoint waypoint, Competitor competitor); MarkPassing createMarkPassing(TimePoint timePoint, Waypoint waypoint, Competitor competitor);
@@ -8,6 +8,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.logging.Logger; import java.util.logging.Logger;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CompetitorStore; import com.sap.sailing.domain.base.CompetitorStore;
import com.sap.sailing.domain.base.DomainFactory; import com.sap.sailing.domain.base.DomainFactory;
@@ -67,12 +68,12 @@ public class DomainFactoryImpl extends SharedDomainFactoryImpl implements Domain
/** /**
* Uses a transient competitor store * Uses a transient competitor store
*/ */
public DomainFactoryImpl() { public DomainFactoryImpl(RaceLogResolver raceLogResolver) {
super(new TransientCompetitorStoreImpl()); super(new TransientCompetitorStoreImpl(), raceLogResolver);
} }
public DomainFactoryImpl(CompetitorStore competitorStore) { public DomainFactoryImpl(CompetitorStore competitorStore, RaceLogResolver raceLogResolver) {
super(competitorStore); super(competitorStore, raceLogResolver);
} }
@Override @Override
@@ -1670,8 +1670,9 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
result.estimatedTimeToNextWaypointInSeconds = estimatedTimeToNextMarkInSeconds==null?null:estimatedTimeToNextMarkInSeconds.asSeconds(); result.estimatedTimeToNextWaypointInSeconds = estimatedTimeToNextMarkInSeconds==null?null:estimatedTimeToNextMarkInSeconds.asSeconds();
result.timeInMilliseconds = time.asMillis(); result.timeInMilliseconds = time.asMillis();
result.finished = trackedLeg.hasFinishedLeg(timePoint); result.finished = trackedLeg.hasFinishedLeg(timePoint);
final TimePoint legFinishTime = trackedLeg.getFinishTime();
result.correctedTotalTime = trackedLeg.hasStartedLeg(timePoint) ? trackedLeg.getTrackedLeg().getTrackedRace().getRankingMetric().getCorrectedTime(trackedLeg.getCompetitor(), result.correctedTotalTime = trackedLeg.hasStartedLeg(timePoint) ? trackedLeg.getTrackedLeg().getTrackedRace().getRankingMetric().getCorrectedTime(trackedLeg.getCompetitor(),
trackedLeg.hasFinishedLeg(timePoint) ? trackedLeg.getFinishTime() : timePoint, cache) : null; trackedLeg.hasFinishedLeg(timePoint) ? legFinishTime : timePoint, cache) : null;
// fetch the leg gap in own corrected time from the ranking metric // fetch the leg gap in own corrected time from the ranking metric
final Duration gapToLeaderInOwnTime = trackedLeg.getTrackedLeg().getTrackedRace().getRankingMetric(). final Duration gapToLeaderInOwnTime = trackedLeg.getTrackedLeg().getTrackedRace().getRankingMetric().
getLegGapToLegLeaderInOwnTime(trackedLeg, timePoint, rankingInfo, cache); getLegGapToLegLeaderInOwnTime(trackedLeg, timePoint, rankingInfo, cache);
@@ -1721,8 +1722,8 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
case TACK: case TACK:
case JIBE: case JIBE:
case PENALTY_CIRCLE: case PENALTY_CIRCLE:
if (!maneuver.getTimePoint().before(startOfLeg) && (!trackedLeg.hasFinishedLeg(timePoint) || if (!maneuver.getTimePoint().before(startOfLeg) && (legFinishTime == null || legFinishTime.after(timePoint) ||
maneuver.getTimePoint().before(trackedLeg.getFinishTime()))) { maneuver.getTimePoint().before(legFinishTime))) {
if (maneuver.getManeuverLoss() != null) { if (maneuver.getManeuverLoss() != null) {
result.numberOfManeuvers.put(maneuver.getType(), result.numberOfManeuvers.put(maneuver.getType(),
result.numberOfManeuvers.get(maneuver.getType()) + 1); result.numberOfManeuvers.get(maneuver.getType()) + 1);
@@ -1,6 +1,7 @@
package com.sap.sailing.domain.leaderboard.impl; package com.sap.sailing.domain.leaderboard.impl;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set; import java.util.Set;
import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Competitor;
@@ -43,7 +44,7 @@ public class PerSeriesResultDiscardingRuleImpl implements ResultDiscardingRule {
} }
private Iterable<RaceColumn> getColumnsToConsiderInSeries(Series series, Iterable<RaceColumn> allRaceColumnsToConsider) { private Iterable<RaceColumn> getColumnsToConsiderInSeries(Series series, Iterable<RaceColumn> allRaceColumnsToConsider) {
Set<RaceColumn> result = new HashSet<>(); Set<RaceColumn> result = new LinkedHashSet<>();
for (RaceColumn seriesColumn : series.getRaceColumns()) { for (RaceColumn seriesColumn : series.getRaceColumns()) {
if (Util.contains(allRaceColumnsToConsider, seriesColumn)) { if (Util.contains(allRaceColumnsToConsider, seriesColumn)) {
result.add(seriesColumn); result.add(seriesColumn);
@@ -593,7 +593,9 @@ public abstract class AbstractRankingMetric implements RankingMetric {
* For each leg the total windward distance sailed is limited to the leg's windward distance at its * For each leg the total windward distance sailed is limited to the leg's windward distance at its
* {@link TrackedLeg#getReferenceTimePoint() reference time point}. This ensures that significantly "overstaying" the lay lines * {@link TrackedLeg#getReferenceTimePoint() reference time point}. This ensures that significantly "overstaying" the lay lines
* doesn't let a competitor rank better than one who already passed the mark but traveled little windward distance in * doesn't let a competitor rank better than one who already passed the mark but traveled little windward distance in
* the next leg. * the next leg.<p>
*
* If mark positions along the way are not known, the windward distance of those legs will be counted as 0.
* *
* @param timePoint needed to determine <code>competitor</code>'s position at that time point; note that the * @param timePoint needed to determine <code>competitor</code>'s position at that time point; note that the
* time point for wind approximation is taken to be a reference time point selected based on the mark passings * time point for wind approximation is taken to be a reference time point selected based on the mark passings
@@ -620,7 +622,7 @@ public abstract class AbstractRankingMetric implements RankingMetric {
if (estimatedPosition != null) { if (estimatedPosition != null) {
final Distance windwardDistanceFromLegStart = trackedLeg.getWindwardDistanceFromLegStart(estimatedPosition, cache); final Distance windwardDistanceFromLegStart = trackedLeg.getWindwardDistanceFromLegStart(estimatedPosition, cache);
final Distance legWindwardDistance = trackedLeg.getWindwardDistance(cache); final Distance legWindwardDistance = trackedLeg.getWindwardDistance(cache);
if (legWindwardDistance.compareTo(windwardDistanceFromLegStart) < 0) { if (legWindwardDistance != null && legWindwardDistance.compareTo(windwardDistanceFromLegStart) < 0) {
d = d.add(legWindwardDistance); d = d.add(legWindwardDistance);
} else { } else {
// if the competitor is currently at the mark rounding, the windward distance within the leg may // if the competitor is currently at the mark rounding, the windward distance within the leg may
@@ -632,7 +634,10 @@ public abstract class AbstractRankingMetric implements RankingMetric {
} }
break; break;
} else { } else {
d = d.add(trackedLeg.getWindwardDistance(cache)); final Distance legWindwardDistance = trackedLeg.getWindwardDistance(cache);
if (legWindwardDistance != null) {
d = d.add(legWindwardDistance);
}
} }
} }
} }
@@ -17,6 +17,7 @@ import com.sap.sailing.domain.base.Leg;
import com.sap.sailing.domain.base.Mark; import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.RaceDefinition; import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta; import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.base.Sideline; import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.SpeedWithConfidence; import com.sap.sailing.domain.base.SpeedWithConfidence;
import com.sap.sailing.domain.base.Waypoint; import com.sap.sailing.domain.base.Waypoint;
@@ -46,6 +47,7 @@ import com.sap.sailing.domain.ranking.RankingMetric;
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo; import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl; import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl;
import com.sap.sse.common.Duration; import com.sap.sse.common.Duration;
import com.sap.sse.common.IsManagedByCache;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util; import com.sap.sse.common.Util;
@@ -64,7 +66,7 @@ import com.sap.sse.common.Util;
* @author Axel Uhl (d043530) * @author Axel Uhl (d043530)
* *
*/ */
public interface TrackedRace extends Serializable { public interface TrackedRace extends Serializable, IsManagedByCache<SharedDomainFactory> {
final long MAX_TIME_BETWEEN_START_AND_FIRST_MARK_PASSING_IN_MILLISECONDS = 30000; final long MAX_TIME_BETWEEN_START_AND_FIRST_MARK_PASSING_IN_MILLISECONDS = 30000;
final long DEFAULT_LIVE_DELAY_IN_MILLISECONDS = 5000; final long DEFAULT_LIVE_DELAY_IN_MILLISECONDS = 5000;
@@ -454,27 +454,30 @@ public class TrackedLegImpl implements TrackedLeg {
Distance getWindwardDistance(final Position pos1, final Position pos2, TimePoint at, WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache) { Distance getWindwardDistance(final Position pos1, final Position pos2, TimePoint at, WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache) {
Distance result; Distance result;
try { if (pos1 == null || pos2 == null) {
final LegType legType = cache.getLegType(this, at); result = null;
if (legType != LegType.REACHING) { // upwind or downwind } else {
final Position effectivePosition = getEffectiveWindPosition( try {
() -> pos1.translateGreatCircle(pos1.getBearingGreatCircle(pos2), pos1.getDistance(pos2).scale(0.5)), final LegType legType = cache.getLegType(this, at);
at, windPositionMode); if (legType != LegType.REACHING) { // upwind or downwind
Wind wind = getTrackedRace().getWind(effectivePosition, at); final Position effectivePosition = getEffectiveWindPosition(() -> pos1.translateGreatCircle(
if (wind == null) { pos1.getBearingGreatCircle(pos2), pos1.getDistance(pos2).scale(0.5)), at, windPositionMode);
result = pos2.alongTrackDistance(pos1, cache.getLegBearing(this, at)); Wind wind = getTrackedRace().getWind(effectivePosition, at);
if (wind == null) {
result = pos2.alongTrackDistance(pos1, cache.getLegBearing(this, at));
} else {
Position projectionToLineThroughPos2 = pos1.projectToLineThrough(pos2, wind.getBearing());
result = pos2.alongTrackDistance(projectionToLineThroughPos2,
legType == LegType.UPWIND ? wind.getFrom() : wind.getBearing());
}
} else { } else {
Position projectionToLineThroughPos2 = pos1.projectToLineThrough(pos2, wind.getBearing()); // reaching leg, return distance projected onto leg's bearing
result = pos2.alongTrackDistance(projectionToLineThroughPos2, result = pos2.alongTrackDistance(pos1, cache.getLegBearing(this, at));
legType == LegType.UPWIND ? wind.getFrom() : wind.getBearing());
} }
} else { } catch (NoWindException e) {
// reaching leg, return distance projected onto leg's bearing // no wind information; use along-track distance as fallback
result = pos2.alongTrackDistance(pos1, cache.getLegBearing(this, at)); result = pos2.alongTrackDistance(pos1, cache.getLegBearing(this, at));
} }
} catch (NoWindException e) {
// no wind information; use along-track distance as fallback
result = pos2.alongTrackDistance(pos1, cache.getLegBearing(this, at));
} }
return result; return result;
} }
@@ -54,6 +54,7 @@ import com.sap.sailing.domain.base.CourseListener;
import com.sap.sailing.domain.base.Leg; import com.sap.sailing.domain.base.Leg;
import com.sap.sailing.domain.base.Mark; import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.RaceDefinition; import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.base.Sideline; import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.SpeedWithBearingWithConfidence; import com.sap.sailing.domain.base.SpeedWithBearingWithConfidence;
import com.sap.sailing.domain.base.SpeedWithConfidence; import com.sap.sailing.domain.base.SpeedWithConfidence;
@@ -134,6 +135,7 @@ import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.WindTrack; import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.domain.tracking.WindWithConfidence; import com.sap.sailing.domain.tracking.WindWithConfidence;
import com.sap.sse.common.Duration; import com.sap.sse.common.Duration;
import com.sap.sse.common.IsManagedByCache;
import com.sap.sse.common.NoCorrespondingServiceRegisteredException; import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Timed; import com.sap.sse.common.Timed;
@@ -1022,14 +1024,16 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
&& timePoint.compareTo(markPassings.last().getTimePoint()) > 0) { && timePoint.compareTo(markPassings.last().getTimePoint()) > 0) {
// competitor has finished race at or before the requested time point; use time point of crossing the finish line // competitor has finished race at or before the requested time point; use time point of crossing the finish line
end = markPassings.last().getTimePoint(); end = markPassings.last().getTimePoint();
} else if ((trackedLegOfCompetitor=getTrackedLeg(competitor, timePoint)) == null || } else {
(!trackedLegOfCompetitor.hasFinishedLeg(getEndOfTracking()) final TimePoint endOfTracking = getEndOfTracking();
&& ((getEndOfTracking() != null && timePoint.after(getEndOfTracking())) if ((trackedLegOfCompetitor=getTrackedLeg(competitor, timePoint)) == null ||
|| getStatus().getStatus() == TrackedRaceStatusEnum.FINISHED))) { (endOfTracking != null && !trackedLegOfCompetitor.hasFinishedLeg(endOfTracking)
// If the race is no longer tracking and hence no more data can be expected, and the competitor && (timePoint.after(endOfTracking) || getStatus().getStatus() == TrackedRaceStatusEnum.FINISHED))) {
// hasn't finished a leg after the requested time point, no valid distance traveled can be determined // If the race is no longer tracking and hence no more data can be expected, and the competitor
// for the competitor in this race the the time point requested // hasn't finished a leg after the requested time point, no valid distance traveled can be determined
end = null; // for the competitor in this race the the time point requested
end = null;
}
} }
if (end == null) { if (end == null) {
result = null; result = null;
@@ -3692,4 +3696,14 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
public void setRaceLogResolver(RaceLogResolver raceLogResolver) { public void setRaceLogResolver(RaceLogResolver raceLogResolver) {
this.raceLogResolver = raceLogResolver; this.raceLogResolver = raceLogResolver;
} }
/**
* When given the opportunity to resolve after de-serialization, grabs the {@link RaceLogResolver} from the
* {@link SharedDomainFactory} because the field is transient and needs filling after de-serialization.
*/
@Override
public IsManagedByCache<SharedDomainFactory> resolve(SharedDomainFactory domainFactory) {
this.raceLogResolver = domainFactory.getRaceLogResolver();
return this;
}
} }
@@ -17,6 +17,7 @@ import com.sap.sailing.domain.base.Leg;
import com.sap.sailing.domain.base.Mark; import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.RaceDefinition; import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta; import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.base.Sideline; import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.SpeedWithConfidence; import com.sap.sailing.domain.base.SpeedWithConfidence;
import com.sap.sailing.domain.base.Waypoint; import com.sap.sailing.domain.base.Waypoint;
@@ -63,6 +64,7 @@ import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.domain.tracking.WindWithConfidence; import com.sap.sailing.domain.tracking.WindWithConfidence;
import com.sap.sailing.domain.tracking.impl.WindTrackImpl; import com.sap.sailing.domain.tracking.impl.WindTrackImpl;
import com.sap.sse.common.Duration; import com.sap.sse.common.Duration;
import com.sap.sse.common.IsManagedByCache;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util; import com.sap.sse.common.Util;
@@ -783,4 +785,9 @@ public class MockedTrackedRace implements DynamicTrackedRace {
@Override @Override
public void attachRaceExecutionProvider(RaceExecutionOrderProvider raceExecutionOrderProvider) { public void attachRaceExecutionProvider(RaceExecutionOrderProvider raceExecutionOrderProvider) {
} }
@Override
public IsManagedByCache<SharedDomainFactory> resolve(SharedDomainFactory domainFactory) {
return this;
}
} }
@@ -3,6 +3,7 @@
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/> <booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/> <stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/> <booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
<booleanAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT_AUTO" value="true"/>
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES"> <listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
<listEntry value="com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart"/> <listEntry value="com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart"/>
<listEntry value="com.sap.sailing.gwt.ui.RaceBoard"/> <listEntry value="com.sap.sailing.gwt.ui.RaceBoard"/>
@@ -71,7 +72,7 @@
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/> <booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/> <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-superDevMode -incremental -workDir &quot;${project_loc:com.sap.sailing.gwt.ui}/.tmp/gwt-work&quot; -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort 9997 -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/EmbeddedMapAndWindChart com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.home.Desktop com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.PolarSheets com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart"/> <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-superDevMode -incremental -workDir &quot;${project_loc:com.sap.sailing.gwt.ui}/.tmp/gwt-work&quot; -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/EmbeddedMapAndWindChart com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.home.Desktop com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.PolarSheets com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/> <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms1024m -Xmx3072m"/> <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms1024m -Xmx3072m"/>
</launchConfiguration> </launchConfiguration>
@@ -36,7 +36,7 @@ public class StoreCompetitorTest extends AbstractMongoDBTest {
@Before @Before
public void setUp() { public void setUp() {
// clear the domainFactory competitor store for a clean start: // clear the domainFactory competitor store for a clean start:
domainFactory = new DomainFactoryImpl(); domainFactory = new DomainFactoryImpl((srlid)->null);
} }
private void dropCompetitorCollection() { private void dropCompetitorCollection() {
@@ -347,7 +347,7 @@ public class TestStoringAndRetrievingLeaderboards extends AbstractMongoDBTest {
final int[] discardIndexResultsStartingWithHowManyRaces = new int[] { 5, 8 }; final int[] discardIndexResultsStartingWithHowManyRaces = new int[] { 5, 8 };
FlexibleLeaderboardImpl leaderboard = new FlexibleLeaderboardImpl(leaderboardName, new ThresholdBasedResultDiscardingRuleImpl(discardIndexResultsStartingWithHowManyRaces), FlexibleLeaderboardImpl leaderboard = new FlexibleLeaderboardImpl(leaderboardName, new ThresholdBasedResultDiscardingRuleImpl(discardIndexResultsStartingWithHowManyRaces),
new LowPoint(), null); new LowPoint(), null);
final DomainFactory domainFactory = new DomainFactoryImpl(); final DomainFactory domainFactory = new DomainFactoryImpl((srlid)->null);
// create the competitor through the competitor store/factory here so that the DomainObjectFactory finds it and // create the competitor through the competitor store/factory here so that the DomainObjectFactory finds it and
// resolves the score corrections appropriate // resolves the score corrections appropriate
Competitor competitor = domainFactory.getOrCreateCompetitor(123, "$$$Dr. Wolfgang+Hunger$$$", Color.RED, "someone@nowhere.de", null, new TeamImpl("STG", Collections.singleton( Competitor competitor = domainFactory.getOrCreateCompetitor(123, "$$$Dr. Wolfgang+Hunger$$$", Color.RED, "someone@nowhere.de", null, new TeamImpl("STG", Collections.singleton(
@@ -1,7 +1,10 @@
package com.sap.sailing.server.replication.test; package com.sap.sailing.server.replication.test;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.base.CompetitorStore;
import com.sap.sailing.domain.base.DomainFactory; import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.base.impl.DomainFactoryImpl; import com.sap.sailing.domain.base.impl.DomainFactoryImpl;
import com.sap.sailing.domain.persistence.DomainObjectFactory;
import com.sap.sailing.domain.persistence.MongoObjectFactory; import com.sap.sailing.domain.persistence.MongoObjectFactory;
import com.sap.sailing.domain.persistence.PersistenceFactory; import com.sap.sailing.domain.persistence.PersistenceFactory;
import com.sap.sailing.domain.persistence.media.MediaDBFactory; import com.sap.sailing.domain.persistence.media.MediaDBFactory;
@@ -9,6 +12,7 @@ import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore; import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.server.RacingEventService; import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.impl.RacingEventServiceImpl; import com.sap.sailing.server.impl.RacingEventServiceImpl;
import com.sap.sailing.server.impl.RacingEventServiceImpl.ConstructorParameters;
import com.sap.sse.mongodb.MongoDBService; import com.sap.sse.mongodb.MongoDBService;
public abstract class AbstractServerReplicationTest extends com.sap.sse.replication.testsupport.AbstractServerWithSingleServiceReplicationTest<RacingEventService, RacingEventServiceImpl> { public abstract class AbstractServerReplicationTest extends com.sap.sse.replication.testsupport.AbstractServerWithSingleServiceReplicationTest<RacingEventService, RacingEventServiceImpl> {
@@ -42,17 +46,35 @@ public abstract class AbstractServerReplicationTest extends com.sap.sse.replicat
@Override @Override
public RacingEventServiceImpl createNewMaster() { public RacingEventServiceImpl createNewMaster() {
return new RacingEventServiceImpl(PersistenceFactory.INSTANCE.getDomainObjectFactory(mongoDBService, return new RacingEventServiceImpl((final RaceLogResolver raceLogResolver)-> {
DomainFactory.INSTANCE), mongoObjectFactory, MediaDBFactory.INSTANCE.getMediaDB(mongoDBService), return new ConstructorParameters() {
EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE); private final DomainFactory baseDomainFactory = new DomainFactoryImpl(raceLogResolver);
@Override public DomainObjectFactory getDomainObjectFactory() { return PersistenceFactory.INSTANCE.getDomainObjectFactory(mongoDBService, baseDomainFactory); }
@Override public MongoObjectFactory getMongoObjectFactory() { return mongoObjectFactory; }
@Override public DomainFactory getBaseDomainFactory() { return baseDomainFactory; }
@Override public CompetitorStore getCompetitorStore() { return getBaseDomainFactory().getCompetitorStore(); }
};
}, MediaDBFactory.INSTANCE.getMediaDB(mongoDBService), EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, null);
} }
@Override @Override
public RacingEventServiceImpl createNewReplica() { public RacingEventServiceImpl createNewReplica() {
return new RacingEventServiceImpl(PersistenceFactory.INSTANCE.getDomainObjectFactory(mongoDBService, return new RacingEventServiceImpl(
// replica gets its own base DomainFactory: (final RaceLogResolver raceLogResolver) -> {
new DomainFactoryImpl()), mongoObjectFactory, MediaDBFactory.INSTANCE.getMediaDB(mongoDBService), return new RacingEventServiceImpl.ConstructorParameters() {
EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE); private final DomainObjectFactory domainObjectFactory =
PersistenceFactory.INSTANCE.getDomainObjectFactory(mongoDBService,
// replica gets its own base DomainFactory:
new DomainFactoryImpl(raceLogResolver));
@Override public DomainObjectFactory getDomainObjectFactory() { return domainObjectFactory; }
@Override public MongoObjectFactory getMongoObjectFactory() { return mongoObjectFactory; }
@Override public DomainFactory getBaseDomainFactory() { return domainObjectFactory.getBaseDomainFactory(); }
@Override public CompetitorStore getCompetitorStore() { return getBaseDomainFactory().getCompetitorStore(); }
};
}, MediaDBFactory.INSTANCE.getMediaDB(mongoDBService), EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE,
/* serviceFinderFactory */ null);
} }
} }
} }
@@ -77,7 +77,7 @@ public class DelayedLeaderboardCorrectionsReplicationTest extends AbstractServer
// then start initial load, wait until finished; then link a tracked race to leaderboard's RaceColumn on master and // then start initial load, wait until finished; then link a tracked race to leaderboard's RaceColumn on master and
// verify that on the replica it is associated to the RaceColumn as well, and the DelayedLeaderboardCorrections are // verify that on the replica it is associated to the RaceColumn as well, and the DelayedLeaderboardCorrections are
// resolved properly on the replica. // resolved properly on the replica.
final DomainFactory domainFactory = new DomainFactoryImpl(); final DomainFactory domainFactory = new DomainFactoryImpl((srlid)->null);
BoatClass boatClass = domainFactory.getOrCreateBoatClass("29erXX", /* typicallyStartsUpwind */ true); BoatClass boatClass = domainFactory.getOrCreateBoatClass("29erXX", /* typicallyStartsUpwind */ true);
DynamicCompetitor hasso = AbstractLeaderboardTest.createCompetitor("Dr. Hasso Plattner"); // don't create competitor using CompetitorStore DynamicCompetitor hasso = AbstractLeaderboardTest.createCompetitor("Dr. Hasso Plattner"); // don't create competitor using CompetitorStore
final DynamicTrackedRace q2YellowTrackedRace = new MockedTrackedRaceWithFixedRank(hasso, /* rank */ 1, /* started */ false, boatClass) { final DynamicTrackedRace q2YellowTrackedRace = new MockedTrackedRaceWithFixedRank(hasso, /* rank */ 1, /* started */ false, boatClass) {
@@ -105,7 +105,7 @@ public class DelayedLeaderboardCorrectionsReplicationTest extends AbstractServer
// re-load new master from persistence // re-load new master from persistence
master = createRacingEventServiceWithOneMockedTrackedRace(q2YellowTrackedRace, domainFactory); master = createRacingEventServiceWithOneMockedTrackedRace(q2YellowTrackedRace, domainFactory);
DomainFactoryImpl replicaDomainFactory = new DomainFactoryImpl(); DomainFactoryImpl replicaDomainFactory = new DomainFactoryImpl((srlid)->null);
replica = createRacingEventServiceWithOneMockedTrackedRace(q2YellowTrackedRace, replicaDomainFactory); replica = createRacingEventServiceWithOneMockedTrackedRace(q2YellowTrackedRace, replicaDomainFactory);
final Leaderboard masterLeaderboardReloaded = master.getLeaderboardByName(leaderboardName); final Leaderboard masterLeaderboardReloaded = master.getLeaderboardByName(leaderboardName);
assertNotNull(masterLeaderboardReloaded); assertNotNull(masterLeaderboardReloaded);
@@ -78,8 +78,7 @@ public class ServerReplicationTest extends AbstractServerReplicationTest {
@Test @Test
public void testWaypointRemovalReplication() throws InterruptedException { public void testWaypointRemovalReplication() throws InterruptedException {
final String boatClassName = "49er"; final String boatClassName = "49er";
// FIXME use master DomainFactory; see bug 592 final DomainFactory masterDomainFactory = testSetUp.getMaster().getBaseDomainFactory();
final DomainFactory masterDomainFactory = DomainFactory.INSTANCE;
BoatClass boatClass = masterDomainFactory.getOrCreateBoatClass(boatClassName); BoatClass boatClass = masterDomainFactory.getOrCreateBoatClass(boatClassName);
final String baseEventName = "Test Event"; final String baseEventName = "Test Event";
AddDefaultRegatta addRegattaOperation = new AddDefaultRegatta(RegattaImpl.getDefaultName(baseEventName, boatClassName), boatClassName, AddDefaultRegatta addRegattaOperation = new AddDefaultRegatta(RegattaImpl.getDefaultName(baseEventName, boatClassName), boatClassName,
@@ -61,6 +61,7 @@ public class SimpleRabbitMQTest {
new Thread(consumer2).start(); new Thread(consumer2).start();
String message = "Hello World!"; String message = "Hello World!";
channel.basicPublish(EXCHANGE_NAME, /* queue name */ "", null, message.getBytes()); channel.basicPublish(EXCHANGE_NAME, /* queue name */ "", null, message.getBytes());
Thread.sleep(1000);
consumer1.waitUntilReceived(1000); consumer1.waitUntilReceived(1000);
consumer2.waitUntilReceived(1000); consumer2.waitUntilReceived(1000);
assertEquals(message, received.get(consumer1)); assertEquals(message, received.get(consumer1));
@@ -76,13 +76,13 @@ public class TrackedRaceContentsReplicationTest extends AbstractServerReplicatio
super.setUp(); super.setUp();
final String boatClassName = "49er"; final String boatClassName = "49er";
// FIXME use master DomainFactory; see bug 592 // FIXME use master DomainFactory; see bug 592
final DomainFactory masterDomainFactory = DomainFactory.INSTANCE; final DomainFactory masterDomainFactory = testSetUp.getMaster().getBaseDomainFactory();
BoatClass boatClass = masterDomainFactory.getOrCreateBoatClass(boatClassName, /* typicallyStartsUpwind */true); BoatClass boatClass = masterDomainFactory.getOrCreateBoatClass(boatClassName, /* typicallyStartsUpwind */true);
competitor = masterDomainFactory.getCompetitorStore().getOrCreateCompetitor("GER 61", "Tina Lutz", Color.RED, "someone@nowhere.de", null, new TeamImpl("Tina Lutz + Susann Beucke", competitor = masterDomainFactory.getCompetitorStore().getOrCreateCompetitor("GER 61", "Tina Lutz", Color.RED, "someone@nowhere.de", null, new TeamImpl("Tina Lutz + Susann Beucke",
(List<PersonImpl>) Arrays.asList(new PersonImpl[] { new PersonImpl("Tina Lutz", DomainFactory.INSTANCE.getOrCreateNationality("GER"), null, null), (List<PersonImpl>) Arrays.asList(new PersonImpl[] { new PersonImpl("Tina Lutz", masterDomainFactory.getOrCreateNationality("GER"), null, null),
new PersonImpl("Tina Lutz", DomainFactory.INSTANCE.getOrCreateNationality("GER"), null, null) }), new PersonImpl("Tina Lutz", masterDomainFactory.getOrCreateNationality("GER"), null, null) }),
new PersonImpl("Rigo de Mas", DomainFactory.INSTANCE.getOrCreateNationality("NED"), null, null)), new PersonImpl("Rigo de Mas", masterDomainFactory.getOrCreateNationality("NED"), null, null)),
new BoatImpl("GER 61", DomainFactory.INSTANCE.getOrCreateBoatClass("470", /* typicallyStartsUpwind */ true), "GER 61"), new BoatImpl("GER 61", masterDomainFactory.getOrCreateBoatClass("470", /* typicallyStartsUpwind */ true), "GER 61"),
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null); /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null);
final String baseEventName = "Test Event"; final String baseEventName = "Test Event";
AddDefaultRegatta addEventOperation = new AddDefaultRegatta(RegattaImpl.getDefaultName(baseEventName, boatClassName), boatClassName, AddDefaultRegatta addEventOperation = new AddDefaultRegatta(RegattaImpl.getDefaultName(baseEventName, boatClassName), boatClassName,
@@ -75,8 +75,7 @@ public class TrackedRaceWithGPSFixStoreContentsReplicationTest extends AbstractS
/* dropDB */true, /* master=null means create a new one */null, /* dropDB */true, /* master=null means create a new one */null,
/* replica=null means create a new one */null); /* replica=null means create a new one */null);
final String boatClassName = "49er"; final String boatClassName = "49er";
// FIXME use master DomainFactory; see bug 592 final DomainFactory masterDomainFactory = testSetUp.getMaster().getBaseDomainFactory();
final DomainFactory masterDomainFactory = DomainFactory.INSTANCE;
BoatClass boatClass = masterDomainFactory.getOrCreateBoatClass(boatClassName, /* typicallyStartsUpwind */true); BoatClass boatClass = masterDomainFactory.getOrCreateBoatClass(boatClassName, /* typicallyStartsUpwind */true);
competitor = masterDomainFactory.getCompetitorStore().getOrCreateCompetitor("GER 61", "Tina Lutz", Color.RED, "someone@nowhere.de", null, new TeamImpl("Tina Lutz + Susann Beucke", competitor = masterDomainFactory.getCompetitorStore().getOrCreateCompetitor("GER 61", "Tina Lutz", Color.RED, "someone@nowhere.de", null, new TeamImpl("Tina Lutz + Susann Beucke",
(List<PersonImpl>) Arrays.asList(new PersonImpl[] { new PersonImpl("Tina Lutz", DomainFactory.INSTANCE.getOrCreateNationality("GER"), null, null), (List<PersonImpl>) Arrays.asList(new PersonImpl[] { new PersonImpl("Tina Lutz", DomainFactory.INSTANCE.getOrCreateNationality("GER"), null, null),
@@ -145,5 +144,9 @@ public class TrackedRaceWithGPSFixStoreContentsReplicationTest extends AbstractS
} }
} }
@Test
public void testTrackedRaceHasValidRaceLogResolverAfterDeserialization() {
TrackedRace replicaTrackedRace = replica.getTrackedRace(raceIdentifier);
assertNotNull(replicaTrackedRace.getRaceLogResolver());
}
} }
@@ -52,14 +52,14 @@ public class CompetitorStoreTest {
@Test @Test
public void testPersistentCompetitorStore() { public void testPersistentCompetitorStore() {
CompetitorStore persistentStore1 = new PersistentCompetitorStore( CompetitorStore persistentStore1 = new PersistentCompetitorStore(
PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(), /* clearStore */true, null); PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(), /* clearStore */true, null, /* raceLogResolver */ (srlid)->null);
DynamicCompetitor template = AbstractLeaderboardTest.createCompetitor("Test Competitor"); DynamicCompetitor template = AbstractLeaderboardTest.createCompetitor("Test Competitor");
Competitor competitor = persistentStore1.getOrCreateCompetitor(template.getId(), template.getName(), Competitor competitor = persistentStore1.getOrCreateCompetitor(template.getId(), template.getName(),
template.getColor(), template.getEmail(), template.getFlagImage(), template.getTeam(), template.getColor(), template.getEmail(), template.getFlagImage(), template.getTeam(),
template.getBoat(), /* timeOnTimeFactor */ 1.234, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ Duration.ONE_SECOND.times(730)); template.getBoat(), /* timeOnTimeFactor */ 1.234, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ Duration.ONE_SECOND.times(730));
CompetitorStore persistentStore2 = new PersistentCompetitorStore( CompetitorStore persistentStore2 = new PersistentCompetitorStore(
PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(), /* clearStore */false, null); PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(), /* clearStore */false, null, /* raceLogResolver */ (srlid)->null);
Competitor competitor2 = persistentStore2.getExistingCompetitorById(template.getId()); Competitor competitor2 = persistentStore2.getExistingCompetitorById(template.getId());
assertNotSame(competitor2, template); // the new store loads new instances from the database assertNotSame(competitor2, template); // the new store loads new instances from the database
assertEquals(template.getId(), competitor2.getId()); assertEquals(template.getId(), competitor2.getId());
@@ -741,7 +741,7 @@ public class MasterDataImportTest {
public void testMasterDataImportForRaceLogEventsReferencingCompetitors() throws MalformedURLException, IOException, public void testMasterDataImportForRaceLogEventsReferencingCompetitors() throws MalformedURLException, IOException,
InterruptedException, ClassNotFoundException { InterruptedException, ClassNotFoundException {
// Setup source service // Setup source service
DomainFactory sourceDomainFactory = new DomainFactoryImpl(); DomainFactory sourceDomainFactory = new DomainFactoryImpl((srlid)->null);
RacingEventService sourceService = new RacingEventServiceImpl( RacingEventService sourceService = new RacingEventServiceImpl(
PersistenceFactory.INSTANCE.getDomainObjectFactory(MongoDBService.INSTANCE, sourceDomainFactory), PersistenceFactory.INSTANCE.getDomainObjectFactory(MongoDBService.INSTANCE, sourceDomainFactory),
PersistenceFactory.INSTANCE.getMongoObjectFactory(MongoDBService.INSTANCE), PersistenceFactory.INSTANCE.getMongoObjectFactory(MongoDBService.INSTANCE),
@@ -5,6 +5,7 @@ import java.io.ObjectInputStream;
import java.io.Serializable; import java.io.Serializable;
import java.net.URI; import java.net.URI;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CompetitorStore; import com.sap.sailing.domain.base.CompetitorStore;
import com.sap.sailing.domain.base.DomainFactory; import com.sap.sailing.domain.base.DomainFactory;
@@ -40,8 +41,9 @@ public class PersistentCompetitorStore extends TransientCompetitorStoreImpl impl
* if <code>true</code>, the persistent competitor store is initially cleared, with all persistent * if <code>true</code>, the persistent competitor store is initially cleared, with all persistent
* competitor data removed; use with caution! * competitor data removed; use with caution!
*/ */
public PersistentCompetitorStore(MongoObjectFactory storeTo, boolean clear, TypeBasedServiceFinderFactory serviceFinderFactory) { public PersistentCompetitorStore(MongoObjectFactory storeTo, boolean clear,
DomainFactoryImpl baseDomainFactory = new DomainFactoryImpl(this); TypeBasedServiceFinderFactory serviceFinderFactory, RaceLogResolver raceLogResolver) {
DomainFactoryImpl baseDomainFactory = new DomainFactoryImpl(this, raceLogResolver);
this.loadFrom = PersistenceFactory.INSTANCE.getDomainObjectFactory(MongoDBService.INSTANCE, baseDomainFactory, serviceFinderFactory); this.loadFrom = PersistenceFactory.INSTANCE.getDomainObjectFactory(MongoDBService.INSTANCE, baseDomainFactory, serviceFinderFactory);
this.storeTo = storeTo; this.storeTo = storeTo;
if (clear) { if (clear) {
@@ -34,6 +34,7 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -52,6 +53,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor; import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier; 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.state.RaceState; import com.sap.sailing.domain.abstractlog.race.state.RaceState;
import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState; import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState;
import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateImpl; import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateImpl;
@@ -396,6 +398,23 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
private final JoinedClassLoader joinedClassLoader; private final JoinedClassLoader joinedClassLoader;
/**
* Providing the constructor parameters for a new {@link RacingEventServiceImpl} instance is a bit tricky
* in some cases because containment and initialization order of some types is fairly tightly coupled.
* There is a dependency of many such objects on an instance of {@link RaceLogResolver} which is implemented
* by {@link RacingEventServiceImpl}. However, therefore, this instance only becomes available in the
* innermost constructor.
*
* @author Axel Uhl (d043530)
*
*/
public static interface ConstructorParameters {
DomainObjectFactory getDomainObjectFactory();
MongoObjectFactory getMongoObjectFactory();
com.sap.sailing.domain.base.DomainFactory getBaseDomainFactory();
CompetitorStore getCompetitorStore();
}
/** /**
* Constructs a {@link DomainFactory base domain factory} that uses this object's {@link #competitorStore competitor * Constructs a {@link DomainFactory base domain factory} that uses this object's {@link #competitorStore competitor
* store} for competitor management. This base domain factory is then also used for the construction of the * store} for competitor management. This base domain factory is then also used for the construction of the
@@ -421,29 +440,41 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
* be cleared before the service starts. * be cleared before the service starts.
* *
* @param clearPersistentCompetitorStore * @param clearPersistentCompetitorStore
* if <code>true</code>, the {@link PersistentCompetitorStore} is created empty, with the correcponding * if <code>true</code>, the {@link PersistentCompetitorStore} is created empty, with the corresponding
* database collection cleared as well. Use with caution! When used with <code>false</code>, competitors * database collection cleared as well. Use with caution! When used with <code>false</code>, competitors
* created and stored during previous service executions will initially be loaded. * created and stored during previous service executions will initially be loaded.
*/ */
public RacingEventServiceImpl(boolean clearPersistentCompetitorStore, public RacingEventServiceImpl(boolean clearPersistentCompetitorStore, final TypeBasedServiceFinderFactory serviceFinderFactory) {
TypeBasedServiceFinderFactory serviceFinderFactory) { this((final RaceLogResolver raceLogResolver)-> {
this(new PersistentCompetitorStore( return new ConstructorParameters() {
PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(serviceFinderFactory), private final MongoObjectFactory mongoObjectFactory = PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(serviceFinderFactory);
clearPersistentCompetitorStore, serviceFinderFactory), null, null, serviceFinderFactory); private final PersistentCompetitorStore competitorStore = new PersistentCompetitorStore(
PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(serviceFinderFactory),
clearPersistentCompetitorStore, serviceFinderFactory, raceLogResolver);
@Override public DomainObjectFactory getDomainObjectFactory() { return competitorStore.getDomainObjectFactory(); }
@Override public MongoObjectFactory getMongoObjectFactory() { return mongoObjectFactory; }
@Override public DomainFactory getBaseDomainFactory() { return competitorStore.getBaseDomainFactory(); }
@Override public CompetitorStore getCompetitorStore() { return competitorStore; }
};
}, MediaDBFactory.INSTANCE.getDefaultMediaDB(), null, null, serviceFinderFactory);
} }
private RacingEventServiceImpl(boolean clearPersistentCompetitorStore, WindStore windStore, private RacingEventServiceImpl(final boolean clearPersistentCompetitorStore, WindStore windStore,
GPSFixStore gpsFixStore, TypeBasedServiceFinderFactory serviceFinderFactory) { GPSFixStore gpsFixStore, final TypeBasedServiceFinderFactory serviceFinderFactory) {
this(new PersistentCompetitorStore( this((final RaceLogResolver raceLogResolver)-> {
PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(serviceFinderFactory), return new ConstructorParameters() {
clearPersistentCompetitorStore, serviceFinderFactory), windStore, gpsFixStore, serviceFinderFactory); private final MongoObjectFactory mongoObjectFactory = PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(serviceFinderFactory);
} private final PersistentCompetitorStore competitorStore = new PersistentCompetitorStore(
mongoObjectFactory,
clearPersistentCompetitorStore, serviceFinderFactory, raceLogResolver);
private RacingEventServiceImpl(PersistentCompetitorStore persistentCompetitorStore, WindStore windStore, @Override public DomainObjectFactory getDomainObjectFactory() { return competitorStore.getDomainObjectFactory(); }
GPSFixStore gpsFixStore, TypeBasedServiceFinderFactory serviceFinderFactory) { @Override public MongoObjectFactory getMongoObjectFactory() { return mongoObjectFactory; }
this(persistentCompetitorStore.getDomainObjectFactory(), persistentCompetitorStore.getMongoObjectFactory(), @Override public DomainFactory getBaseDomainFactory() { return competitorStore.getBaseDomainFactory(); }
persistentCompetitorStore.getBaseDomainFactory(), MediaDBFactory.INSTANCE.getDefaultMediaDB(), @Override public CompetitorStore getCompetitorStore() { return competitorStore; }
persistentCompetitorStore, windStore, gpsFixStore, serviceFinderFactory); };
}, MediaDBFactory.INSTANCE.getDefaultMediaDB(), windStore, gpsFixStore, serviceFinderFactory);
} }
/** /**
@@ -452,10 +483,30 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
* be used for testing because it provides a transient {@link CompetitorStore} as required for competitor * be used for testing because it provides a transient {@link CompetitorStore} as required for competitor
* persistence. * persistence.
*/ */
public RacingEventServiceImpl(DomainObjectFactory domainObjectFactory, MongoObjectFactory mongoObjectFactory, public RacingEventServiceImpl(Function<RaceLogResolver, DomainObjectFactory> domainObjectFactoryProvider,
final MongoObjectFactory mongoObjectFactory, MediaDB mediaDB, WindStore windStore, GPSFixStore gpsFixStore) {
this((final RaceLogResolver raceLogResolver)-> {
return new ConstructorParameters() {
private final DomainObjectFactory domainObjectFactory = domainObjectFactoryProvider.apply(raceLogResolver);
@Override public DomainObjectFactory getDomainObjectFactory() { return domainObjectFactory; }
@Override public MongoObjectFactory getMongoObjectFactory() { return mongoObjectFactory; }
@Override public DomainFactory getBaseDomainFactory() { return domainObjectFactory.getBaseDomainFactory(); }
@Override public CompetitorStore getCompetitorStore() { return getBaseDomainFactory().getCompetitorStore(); }
};
}, mediaDB, windStore, gpsFixStore, null);
}
public RacingEventServiceImpl(final DomainObjectFactory domainObjectFactory, MongoObjectFactory mongoObjectFactory,
MediaDB mediaDB, WindStore windStore, GPSFixStore gpsFixStore) { MediaDB mediaDB, WindStore windStore, GPSFixStore gpsFixStore) {
this(domainObjectFactory, mongoObjectFactory, domainObjectFactory.getBaseDomainFactory(), mediaDB, this((final RaceLogResolver raceLogResolver)-> {
domainObjectFactory.getBaseDomainFactory().getCompetitorStore(), windStore, gpsFixStore, null); return new ConstructorParameters() {
@Override public DomainObjectFactory getDomainObjectFactory() { return domainObjectFactory; }
@Override public MongoObjectFactory getMongoObjectFactory() { return mongoObjectFactory; }
@Override public DomainFactory getBaseDomainFactory() { return domainObjectFactory.getBaseDomainFactory(); }
@Override public CompetitorStore getCompetitorStore() { return getBaseDomainFactory().getCompetitorStore(); }
};
}, mediaDB, windStore, gpsFixStore, null);
} }
/** /**
@@ -467,14 +518,18 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
* of {@link DeviceIdentifier}s of specific device types or the managing of the device-to-competitor * of {@link DeviceIdentifier}s of specific device types or the managing of the device-to-competitor
* associations per race tracked. * associations per race tracked.
*/ */
private RacingEventServiceImpl(DomainObjectFactory domainObjectFactory, MongoObjectFactory mongoObjectFactory, public RacingEventServiceImpl(Function<RaceLogResolver, ConstructorParameters> constructorParametersProvider, MediaDB mediaDb,
com.sap.sailing.domain.base.DomainFactory baseDomainFactory, MediaDB mediaDb, WindStore windStore, GPSFixStore gpsFixStore, TypeBasedServiceFinderFactory serviceFinderFactory) {
CompetitorStore competitorStore, WindStore windStore, GPSFixStore gpsFixStore,
TypeBasedServiceFinderFactory serviceFinderFactory) {
logger.info("Created " + this); logger.info("Created " + this);
final ConstructorParameters constructorParameters = constructorParametersProvider.apply(this);
this.domainObjectFactory = constructorParameters.getDomainObjectFactory();
this.masterDataClassLoaders.add(this.getClass().getClassLoader()); this.masterDataClassLoaders.add(this.getClass().getClassLoader());
joinedClassLoader = new JoinedClassLoader(masterDataClassLoaders); joinedClassLoader = new JoinedClassLoader(masterDataClassLoaders);
this.operationsSentToMasterForReplication = new HashSet<>(); this.operationsSentToMasterForReplication = new HashSet<>();
this.baseDomainFactory = constructorParameters.getBaseDomainFactory();
this.mongoObjectFactory = constructorParameters.getMongoObjectFactory();
this.mediaDB = mediaDb;
this.competitorStore = constructorParameters.getCompetitorStore();
if (windStore == null) { if (windStore == null) {
try { try {
windStore = MongoWindStoreFactory.INSTANCE.getMongoWindStore(mongoObjectFactory, domainObjectFactory); windStore = MongoWindStoreFactory.INSTANCE.getMongoWindStore(mongoObjectFactory, domainObjectFactory);
@@ -482,11 +537,6 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
this.baseDomainFactory = baseDomainFactory;
this.domainObjectFactory = domainObjectFactory;
this.mongoObjectFactory = mongoObjectFactory;
this.mediaDB = mediaDb;
this.competitorStore = competitorStore;
this.competitorStore.addCompetitorUpdateListener(new CompetitorUpdateListener() { this.competitorStore.addCompetitorUpdateListener(new CompetitorUpdateListener() {
@Override @Override
public void competitorUpdated(Competitor competitor) { public void competitorUpdated(Competitor competitor) {
@@ -14,6 +14,7 @@ import com.sap.sailing.domain.base.Leg;
import com.sap.sailing.domain.base.Mark; import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.RaceDefinition; import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta; import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.base.Sideline; import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.SpeedWithConfidence; import com.sap.sailing.domain.base.SpeedWithConfidence;
import com.sap.sailing.domain.base.Waypoint; import com.sap.sailing.domain.base.Waypoint;
@@ -56,6 +57,7 @@ import com.sap.sailing.domain.tracking.WindWithConfidence;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl; import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore; import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sse.common.Duration; import com.sap.sse.common.Duration;
import com.sap.sse.common.IsManagedByCache;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util; import com.sap.sse.common.Util;
@@ -621,4 +623,9 @@ public class DummyTrackedRace extends TrackedRaceWithWindEssentials {
@Override @Override
public void detachRaceExecutionOrderProvider(RaceExecutionOrderProvider raceExecutionOrderProvider) { public void detachRaceExecutionOrderProvider(RaceExecutionOrderProvider raceExecutionOrderProvider) {
} }
@Override
public IsManagedByCache<SharedDomainFactory> resolve(SharedDomainFactory domainFactory) {
return this;
}
} }
@@ -132,7 +132,8 @@ public class PathImpl implements Path, Serializable {
if ((this.pathPoints.get(idx).getTimePoint().asMillis() >= nextTimePoint.asMillis())||(idx == this.pathPoints.size()-1)) { if ((this.pathPoints.get(idx).getTimePoint().asMillis() >= nextTimePoint.asMillis())||(idx == this.pathPoints.size()-1)) {
if (idx == this.pathPoints.size()-1) { // for the last step, next-time-point needs to be aligned to the time-range of the course
if (nextTimePoint.after(endTime)) {
nextTimePoint = endTime; nextTimePoint = endTime;
} }
@@ -44,7 +44,7 @@ public enum InMemoryDataStore implements DataStore {
managedRaceById = new HashMap<>(); managedRaceById = new HashMap<>();
marksById = new HashMap<>(); marksById = new HashMap<>();
courseData = null; courseData = null;
domainFactory = new SharedDomainFactoryImpl(); domainFactory = new SharedDomainFactoryImpl(new AndroidRaceLogResolver());
eventUUID = null; eventUUID = null;
courseUUID = null; courseUUID = null;
@@ -2,6 +2,7 @@ package com.sap.sailing.racecommittee.app.ui.fragments.raceinfo;
import android.app.FragmentTransaction; import android.app.FragmentTransaction;
import android.support.annotation.IdRes; import android.support.annotation.IdRes;
import com.sap.sailing.racecommittee.app.R; import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.ui.fragments.RaceFragment; import com.sap.sailing.racecommittee.app.ui.fragments.RaceFragment;
@@ -21,6 +22,9 @@ public class BaseFragment extends RaceFragment {
} else { } else {
fragment.getArguments().putAll(getRecentArguments()); fragment.getArguments().putAll(getRecentArguments());
} }
if (getArguments() != null) {
fragment.getArguments().putAll(getArguments());
}
FragmentTransaction transaction = getFragmentManager().beginTransaction(); FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(viewId, fragment).commit(); transaction.replace(viewId, fragment).commit();
} }