Moved top-level cache for TrackedEvent from TracTrac-specific DomainFactory to RacingEventService;

introduced a TrackedEventRegistry interface in com.sap.sailing.domain that is now extended by
RacingEventService as well as a dummy implementation for use by tests
This commit is contained in:
Axel Uhl
2011-11-14 17:00:17 +01:00
parent 90467c05db
commit ef4547357f
26 changed files with 163 additions and 112 deletions
@@ -32,6 +32,7 @@ import com.sap.sailing.domain.tracking.DynamicTrackedEvent;
import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedEventImpl;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
import com.sap.sailing.domain.tractracadapter.Receiver;
@@ -66,7 +67,7 @@ public class CourseUpdateTest extends AbstractTracTracLiveTest {
super.setUp();
domainFactory = new DomainFactoryImpl();
domainEvent = domainFactory.getOrCreateEvent(getEvent());
trackedEvent = domainFactory.getOrCreateTrackedEvent(domainEvent);
trackedEvent = new DynamicTrackedEventImpl(domainEvent);
ArrayList<Receiver> receivers = new ArrayList<Receiver>();
receivers.add(new RaceCourseReceiver(domainFactory, trackedEvent, getEvent(), /* millisecondsOverWhichToAverageWind */
EmptyWindStore.INSTANCE, this,
@@ -0,0 +1,40 @@
package com.sap.sailing.domain.test;
import java.util.HashMap;
import java.util.Map;
import com.sap.sailing.domain.base.Event;
import com.sap.sailing.domain.tracking.DynamicTrackedEvent;
import com.sap.sailing.domain.tracking.TrackedEventRegistry;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedEventImpl;
public class DummyTrackedEventRegistry implements TrackedEventRegistry {
private final Map<Event, DynamicTrackedEvent> eventTrackingCache;
public DummyTrackedEventRegistry() {
super();
this.eventTrackingCache = new HashMap<Event, DynamicTrackedEvent>();
}
@Override
public DynamicTrackedEvent getOrCreateTrackedEvent(Event event) {
synchronized (eventTrackingCache) {
DynamicTrackedEvent result = eventTrackingCache.get(event);
if (result == null) {
result = new DynamicTrackedEventImpl(event);
eventTrackingCache.put(event, result);
}
return result;
}
}
@Override
public DynamicTrackedEvent getTrackedEvent(com.sap.sailing.domain.base.Event event) {
return eventTrackingCache.get(event);
}
@Override
public void remove(Event event) {
eventTrackingCache.remove(event);
}
}
@@ -23,6 +23,7 @@ import com.sap.sailing.domain.tracking.RaceListener;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.Wind;
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixMovingTrackImpl;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedEventImpl;
import com.sap.sailing.domain.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.domain.tractracadapter.ReceiverType;
@@ -80,7 +81,7 @@ public class FetchTracksAndStoreLocallyTest extends KielWeek2011BasedTest {
}
};
Event event = getDomainFactory().getOrCreateEvent(getEvent());
DynamicTrackedEvent trackedEvent = getDomainFactory().getOrCreateTrackedEvent(event);
DynamicTrackedEvent trackedEvent = new DynamicTrackedEventImpl(event);
trackedEvent.addRaceListener(new RaceListener() {
@Override
public void raceAdded(TrackedRace trackedRace) {
@@ -28,6 +28,7 @@ import com.sap.sailing.domain.base.impl.DegreePosition;
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.tracking.DynamicTrackedEvent;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedEventImpl;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.domain.tracking.impl.GPSFixImpl;
import com.sap.sailing.domain.tracking.impl.TrackedLegImpl;
@@ -123,7 +124,7 @@ public abstract class KielWeek2011BasedTest extends AbstractTracTracLiveTest {
domainFactory = new DomainFactoryImpl();
}
domainEvent = domainFactory.getOrCreateEvent(getEvent());
trackedEvent = domainFactory.getOrCreateTrackedEvent(domainEvent);
trackedEvent = new DynamicTrackedEventImpl(domainEvent);
}
protected Competitor getCompetitorByName(String nameRegexp) {
@@ -48,25 +48,25 @@ public class MultipleClassesInEventTest {
new URL(
httpAndHost+"/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=cce678c8-97e6-11e0-9aed-406186cbf87c"),
new URI(liveURI), new URI(storedURI),
EmptyWindStore.INSTANCE);
EmptyWindStore.INSTANCE, new DummyTrackedEventRegistry());
kiwotest2 = domainFactory
.createRaceTracker(
new URL(
httpAndHost+"/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=11290bd6-97e7-11e0-9aed-406186cbf87c"),
new URI(liveURI), new URI(storedURI),
EmptyWindStore.INSTANCE);
EmptyWindStore.INSTANCE, new DummyTrackedEventRegistry());
kiwotest3 = domainFactory
.createRaceTracker(
new URL(
httpAndHost+"/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=39635b24-97e7-11e0-9aed-406186cbf87c"),
new URI(liveURI), new URI(storedURI),
EmptyWindStore.INSTANCE);
EmptyWindStore.INSTANCE, new DummyTrackedEventRegistry());
weym470may112014_2 = domainFactory
.createRaceTracker(
new URL(
httpAndHost+"/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=04498426-7dfd-11e0-8236-406186cbf87c"),
new URI(liveURI), new URI(storedURI),
EmptyWindStore.INSTANCE);
EmptyWindStore.INSTANCE, new DummyTrackedEventRegistry());
assertEquals("STG", kiwotest1.getEvent().getBoatClass().getName());
assertEquals("505", kiwotest2.getEvent().getBoatClass().getName());
@@ -16,6 +16,7 @@ import com.maptrack.client.io.TypeController;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedEventImpl;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.domain.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
@@ -87,7 +88,7 @@ public class ReceiveMarkPassingDataTest extends AbstractTracTracLiveTest {
List<Receiver> receivers = new ArrayList<Receiver>();
receivers.add(receiver);
for (Receiver r : DomainFactory.INSTANCE.getUpdateReceivers(
DomainFactory.INSTANCE.getOrCreateTrackedEvent(DomainFactory.INSTANCE.getOrCreateEvent(getEvent())),
new DynamicTrackedEventImpl(DomainFactory.INSTANCE.getOrCreateEvent(getEvent())),
getEvent(), EmptyWindStore.INSTANCE, this, ReceiverType.RACECOURSE,
ReceiverType.MARKPOSITIONS, ReceiverType.RACESTARTFINISH, ReceiverType.RAWPOSITIONS)) {
receivers.add(r);
@@ -21,6 +21,7 @@ import com.sap.sailing.domain.tracking.RaceChangeListener;
import com.sap.sailing.domain.tracking.RaceListener;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.Wind;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedEventImpl;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.domain.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
@@ -79,7 +80,7 @@ public class ReceiveTrackingDataTest extends AbstractTracTracLiveTest {
};
List<TypeController> listeners = new ArrayList<TypeController>();
Event event = domainFactory.getOrCreateEvent(getEvent());
DynamicTrackedEvent trackedEvent = domainFactory.getOrCreateTrackedEvent(event);
DynamicTrackedEvent trackedEvent = new DynamicTrackedEventImpl(event);
trackedEvent.addRaceListener(new RaceListener() {
@Override
public void raceAdded(TrackedRace trackedRace) {
@@ -44,7 +44,7 @@ public class UnicodeCharactersInCompetitorNamesTest {
new URL(
"http://germanmaster.traclive.dk/events/event_20110609_KielerWoch/clientparams.php?event=event_20110609_KielerWoch&race=5b08a9ee-9933-11e0-85be-406186cbf87c"),
new URI("tcp://germanmaster.traclive.dk:1520"), new URI("tcp://germanmaster.traclive.dk:1521"),
EmptyWindStore.INSTANCE);
EmptyWindStore.INSTANCE, new DummyTrackedEventRegistry());
Iterable<Competitor> competitors = fourtyninerYellow_2.getRaceHandle().getRace().getCompetitors();
for (Competitor competitor : competitors) {
@@ -25,6 +25,7 @@ import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.MarkPassing;
import com.sap.sailing.domain.tracking.TrackedEvent;
import com.sap.sailing.domain.tracking.TrackedEventRegistry;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.WindTrack;
@@ -105,21 +106,15 @@ public interface DomainFactory {
* respond with the {@link RaceDefinition} when its {@link DomainFactory#getRaces(Event)} is called with the TracTrac
* {@link Event} as argument that is used for its tracking.
* <p>
*
* @param windStore
* Provides the capability to obtain the {@link WindTrack}s for the different wind sources. A trivial
* implementation is {@link EmptyWindStore} which simply provides new, empty tracks. This is always
* available but loses track of the wind, e.g., during server restarts.
* @param trackedEventRegistry TODO
*/
TracTracRaceTracker createRaceTracker(URL paramURL, URI liveURI, URI storedURI, WindStore windStore) throws MalformedURLException,
TracTracRaceTracker createRaceTracker(URL paramURL, URI liveURI, URI storedURI, WindStore windStore, TrackedEventRegistry trackedEventRegistry) throws MalformedURLException,
FileNotFoundException, URISyntaxException;
/**
* Looks for tracking information about <code>event</code>. If no such object exists yet, a new one
* is created.
*/
DynamicTrackedEvent getOrCreateTrackedEvent(com.sap.sailing.domain.base.Event event);
BoatClass getOrCreateBoatClass(CompetitorClass competitorClass);
/**
@@ -183,12 +178,6 @@ public interface DomainFactory {
*/
void updateCourseWaypoints(Course courseToUpdate, List<ControlPoint> controlPoints) throws PatchFailedException;
/**
* Looks for the tracking information for <code>event</code>. If not found, <code>null</code> is returned
* immediately. See also {@link #getOrCreateTrackedEvent(com.sap.sailing.domain.base.Event)}.
*/
DynamicTrackedEvent getTrackedEvent(com.sap.sailing.domain.base.Event event);
TracTracConfiguration createTracTracConfiguration(String name, String jsonURL, String liveDataURI,
String storedDataURI);
@@ -215,7 +204,8 @@ public interface DomainFactory {
* if the {@link TrackedRace} that was removed from the {@link TrackedEvent} was the last one, the
* {@link TrackedEvent} is removed such that {@link #getOrCreateTrackedEvent(com.sap.sailing.domain.base.Event)}
* will have to create a new one.
* @param trackedEventRegistry TODO
*/
void removeRace(Event tractracEvent, Race tractracRace);
void removeRace(Event tractracEvent, Race tractracRace, TrackedEventRegistry trackedEventRegistry);
}
@@ -53,17 +53,17 @@ import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.MarkPassing;
import com.sap.sailing.domain.tracking.TrackedEvent;
import com.sap.sailing.domain.tracking.TrackedEventRegistry;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedEventImpl;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
import com.sap.sailing.domain.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.domain.tracking.impl.MarkPassingImpl;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
import com.sap.sailing.domain.tractracadapter.JSONService;
import com.sap.sailing.domain.tractracadapter.TracTracRaceTracker;
import com.sap.sailing.domain.tractracadapter.Receiver;
import com.sap.sailing.domain.tractracadapter.ReceiverType;
import com.sap.sailing.domain.tractracadapter.TracTracConfiguration;
import com.sap.sailing.domain.tractracadapter.TracTracRaceTracker;
import com.sap.sailing.util.Util;
import com.sap.sailing.util.Util.Pair;
import com.tractrac.clientmodule.CompetitorClass;
@@ -118,8 +118,6 @@ public class DomainFactoryImpl implements DomainFactory {
private final Map<Race, RaceDefinition> raceCache = new HashMap<Race, RaceDefinition>();
private final Map<Event, DynamicTrackedEvent> eventTrackingCache = new HashMap<Event, DynamicTrackedEvent>();
@Override
public Position createPosition(
com.tractrac.clientmodule.data.Position position) {
@@ -374,24 +372,7 @@ public class DomainFactoryImpl implements DomainFactory {
}
@Override
public DynamicTrackedEvent getTrackedEvent(com.sap.sailing.domain.base.Event event) {
return eventTrackingCache.get(event);
}
@Override
public DynamicTrackedEvent getOrCreateTrackedEvent(com.sap.sailing.domain.base.Event event) {
synchronized (eventTrackingCache) {
DynamicTrackedEvent result = eventTrackingCache.get(event);
if (result == null) {
result = new DynamicTrackedEventImpl(event);
eventTrackingCache.put(event, result);
}
return result;
}
}
@Override
public void removeRace(com.tractrac.clientmodule.Event tractracEvent, Race tractracRace) {
public void removeRace(com.tractrac.clientmodule.Event tractracEvent, Race tractracRace, TrackedEventRegistry trackedEventRegistry) {
RaceDefinition raceDefinition = getExistingRaceDefinitionForRace(tractracRace);
if (raceDefinition != null) { // otherwise, this domain factory doesn't seem to know about the race
synchronized (tokenToRaceDefinitionMap) {
@@ -422,11 +403,11 @@ public class DomainFactoryImpl implements DomainFactory {
if (Util.size(event.getAllRaces()) == 0) {
eventCache.remove(key);
}
TrackedEvent trackedEvent = eventTrackingCache.get(event);
TrackedEvent trackedEvent = trackedEventRegistry.getTrackedEvent(event);
if (trackedEvent != null) {
trackedEvent.removeTrackedRace(raceDefinition);
if (Util.size(trackedEvent.getTrackedRaces()) == 0) {
eventTrackingCache.remove(event);
trackedEventRegistry.remove(event);
}
}
}
@@ -513,9 +494,10 @@ public class DomainFactoryImpl implements DomainFactory {
}
@Override
public TracTracRaceTracker createRaceTracker(URL paramURL, URI liveURI, URI storedURI, WindStore windStore) throws MalformedURLException,
FileNotFoundException, URISyntaxException {
return new TracTracRaceTrackerImpl(this, paramURL, liveURI, storedURI, windStore);
public TracTracRaceTracker createRaceTracker(URL paramURL, URI liveURI, URI storedURI, WindStore windStore,
TrackedEventRegistry trackedEventRegistry) throws MalformedURLException, FileNotFoundException,
URISyntaxException {
return new TracTracRaceTrackerImpl(this, paramURL, liveURI, storedURI, windStore, trackedEventRegistry);
}
@Override
@@ -26,14 +26,15 @@ import com.sap.sailing.domain.tracking.DynamicTrackedEvent;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.GPSFix;
import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.TrackedEventRegistry;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.domain.tracking.impl.GPSFixImpl;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
import com.sap.sailing.domain.tractracadapter.TracTracRaceTracker;
import com.sap.sailing.domain.tractracadapter.Receiver;
import com.sap.sailing.domain.tractracadapter.TracTracRaceTracker;
import com.sap.sailing.util.Util.Triple;
import com.tractrac.clientmodule.ControlPoint;
import com.tractrac.clientmodule.Event;
@@ -83,14 +84,15 @@ public class TracTracRaceTrackerImpl implements Listener, TracTracRaceTracker {
* respond with the {@link RaceDefinition} when its {@link DomainFactory#getRaces(Event)} is called with the TracTrac
* {@link Event} as argument that is used for its tracking.
* <p>
*
* @param windStore
* Provides the capability to obtain the {@link WindTrack}s for the different wind sources. A trivial
* implementation is {@link EmptyWindStore} which simply provides new, empty tracks. This is always
* available but loses track of the wind, e.g., during server restarts.
* @param trackedEventRegistry TODO
*/
protected TracTracRaceTrackerImpl(DomainFactory domainFactory, URL paramURL, URI liveURI, URI storedURI, WindStore windStore)
throws URISyntaxException, MalformedURLException, FileNotFoundException {
protected TracTracRaceTrackerImpl(DomainFactory domainFactory, URL paramURL, URI liveURI, URI storedURI,
WindStore windStore, TrackedEventRegistry trackedEventRegistry) throws URISyntaxException,
MalformedURLException, FileNotFoundException {
urls = new Triple<URL, URI, URI>(paramURL, liveURI, storedURI);
this.windStore = windStore;
this.domainFactory = domainFactory;
@@ -111,10 +113,10 @@ public class TracTracRaceTrackerImpl implements Listener, TracTracRaceTracker {
// removeRace may detach the domain event from the domain factory if that
// removed the last race; therefore, it's important to getOrCreate the
// domainEvent *after* calling removeRace
domainFactory.removeRace(tractracEvent, tractracRace);
domainFactory.removeRace(tractracEvent, tractracRace, trackedEventRegistry);
}
domainEvent = domainFactory.getOrCreateEvent(tractracEvent);
trackedEvent = domainFactory.getOrCreateTrackedEvent(domainEvent);
trackedEvent = trackedEventRegistry.getOrCreateTrackedEvent(domainEvent);
receivers = new HashSet<Receiver>();
Set<TypeController> typeControllers = new HashSet<TypeController>();
for (Receiver receiver : domainFactory.getUpdateReceivers(trackedEvent, tractracEvent, windStore, this)) {
@@ -0,0 +1,28 @@
package com.sap.sailing.domain.tracking;
import com.sap.sailing.domain.base.Event;
/**
* {@link TrackedEvent}s or {@link DynamicTrackedEvent}s belong to {@link Event} objects. However, an {@link Event}
* doesn't and shouldn't know how it's being tracked. A <em>registry</em> decouples them. Test cases may use
* different, simplified registries.
*
* @author Axel Uhl (d043530)
*
*/
public interface TrackedEventRegistry {
/**
* Looks for tracking information about <code>event</code>. If no such object exists yet, a new one
* is created.
*/
DynamicTrackedEvent getOrCreateTrackedEvent(Event event);
/**
* Looks for the tracking information for <code>event</code>. If not found, <code>null</code> is returned
* immediately. See also {@link #getOrCreateTrackedEvent(com.sap.sailing.domain.base.Event)}.
*/
DynamicTrackedEvent getTrackedEvent(com.sap.sailing.domain.base.Event event);
void remove(Event event);
}
@@ -21,7 +21,7 @@
</listAttribute>
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-war C:\Users\d056866\git\git\java\com.sap.sailing.gwt.ui\war -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort 9997 com.sap.sailing.gwt.ui.UserManagement com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.Leaderboard"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-war &quot;${project_loc:com.sap.sailing.gwt.ui}/war&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort 9997 com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.ui.UserManagement"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx512m"/>
</launchConfiguration>
@@ -4,8 +4,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TabPanel;
@@ -422,8 +422,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
if (event != null) {
RaceDefinition race = getRaceByName(event, raceName);
if (race != null) {
result = getService().getDomainFactory().getTrackedEvent(event)
.getExistingTrackedRace(race);
result = getService().getOrCreateTrackedEvent(event).getExistingTrackedRace(race);
}
}
return result;
@@ -535,7 +534,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
if (event != null) {
RaceDefinition race = getRaceByName(event, raceName);
if (race != null) {
TrackedRace trackedRace = getService().getDomainFactory().getTrackedEvent(event)
TrackedRace trackedRace = getService().getOrCreateTrackedEvent(event)
.getExistingTrackedRace(race);
if (trackedRace != null) {
WindTrack estimatedTrack = null;
@@ -615,7 +614,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
}
}
Wind wind = new WindImpl(p, at, speedWithBearing);
getService().getDomainFactory().getTrackedEvent(event).getTrackedRace(race).recordWind(wind, WindSource.WEB);
getService().getOrCreateTrackedEvent(event).getTrackedRace(race).recordWind(wind, WindSource.WEB);
}
@Override
@@ -624,7 +623,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
if (event != null) {
RaceDefinition race = getRaceByName(event, raceName);
if (race != null) {
TrackedRace trackedRace = getService().getDomainFactory().getTrackedEvent(event).getTrackedRace(race);
TrackedRace trackedRace = getService().getOrCreateTrackedEvent(event).getTrackedRace(race);
if (trackedRace != null) {
trackedRace.setWindSource(WindSource.valueOf(windSourceName));
}
@@ -641,7 +640,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
if (event != null) {
RaceDefinition race = getRaceByName(event, raceName);
TimePoint end = new MillisecondsTimePoint(date);
TrackedRace trackedRace = getService().getDomainFactory().getTrackedEvent(event).getTrackedRace(race);
TrackedRace trackedRace = getService().getOrCreateTrackedEvent(event).getTrackedRace(race);
for (Competitor competitor : trackedRace.getRace().getCompetitors()) {
CompetitorDAO competitorDAO = getCompetitorDAO(competitor);
List<GPSFixDAO> fixesForCompetitor = new ArrayList<GPSFixDAO>();
@@ -690,7 +689,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
if (event != null) {
RaceDefinition race = getRaceByName(event, raceName);
TimePoint dateAsTimePoint = new MillisecondsTimePoint(date);
TrackedRace trackedRace = getService().getDomainFactory().getTrackedEvent(event).getTrackedRace(race);
TrackedRace trackedRace = getService().getOrCreateTrackedEvent(event).getTrackedRace(race);
Set<Buoy> buoys = new HashSet<Buoy>();
for (Waypoint waypoint : trackedRace.getRace().getCourse().getWaypoints()) {
for (Buoy b : waypoint.getBuoys()) {
@@ -719,7 +718,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
RaceDefinition race = getRaceByName(event, raceName);
if (race != null) {
TimePoint dateAsTimePoint = new MillisecondsTimePoint(date);
TrackedRace trackedRace = getService().getDomainFactory().getTrackedEvent(event).getTrackedRace(race);
TrackedRace trackedRace = getService().getOrCreateTrackedEvent(event).getTrackedRace(race);
for (Competitor competitor : race.getCompetitors()) {
int rank = trackedRace.getRank(competitor, dateAsTimePoint);
TrackedLegOfCompetitor trackedLeg = trackedRace.getTrackedLeg(competitor, dateAsTimePoint);
@@ -771,7 +770,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
}
}
Wind wind = new WindImpl(p, at, speedWithBearing);
getService().getDomainFactory().getTrackedEvent(event).getTrackedRace(race).removeWind(wind, WindSource.WEB);
getService().getOrCreateTrackedEvent(event).getTrackedRace(race).removeWind(wind, WindSource.WEB);
}
protected RacingEventService getService() {
@@ -166,8 +166,9 @@ public class TestColumnToggling extends GWTTestCase {
.getColumnCount(); i++) {
Column<LeaderboardRowDAO, ?> c = leaderboardPanel.getLeaderboardTable().getColumn(i);
if (c instanceof ExpandableSortableColumn<?>) {
rc = (ExpandableSortableColumn<LeaderboardRowDAO>) c;
@SuppressWarnings("unchecked")
ExpandableSortableColumn<LeaderboardRowDAO> myRc = (ExpandableSortableColumn<LeaderboardRowDAO>) c;
rc = myRc;
rc.setEnableLegDrillDown(true);
}
}
@@ -2,7 +2,6 @@ package com.sap.sailing.gwt.ui.test;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
import com.sap.sailing.gwt.ui.client.SailingService;
import com.sap.sailing.server.RacingEventService;
@RemoteServiceRelativePath("testsailing")
public interface TestSailingService extends SailingService {
@@ -1,25 +1,6 @@
package com.sap.sailing.gwt.ui.test;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.shared.CompetitorDAO;
import com.sap.sailing.gwt.ui.shared.EventDAO;
import com.sap.sailing.gwt.ui.shared.GPSFixDAO;
import com.sap.sailing.gwt.ui.shared.LeaderboardDAO;
import com.sap.sailing.gwt.ui.shared.LeaderboardEntryDAO;
import com.sap.sailing.gwt.ui.shared.MarkDAO;
import com.sap.sailing.gwt.ui.shared.Pair;
import com.sap.sailing.gwt.ui.shared.QuickRankDAO;
import com.sap.sailing.gwt.ui.shared.RaceRecordDAO;
import com.sap.sailing.gwt.ui.shared.TracTracConfigurationDAO;
import com.sap.sailing.gwt.ui.shared.WindDAO;
import com.sap.sailing.gwt.ui.shared.WindInfoForRaceDAO;
import com.sap.sailing.server.RacingEventService;
public interface TestSailingServiceAsync extends SailingServiceAsync {
@@ -13,4 +13,5 @@ Require-Bundle: org.junit4;bundle-version="4.8.1",
com.tractrac.clientmodule,
com.sap.sailing.domain.tractracadapter,
org.eclipse.osgi,
com.sap.sailing.domain.persistence
com.sap.sailing.domain.persistence,
com.sap.sailing.server
@@ -35,6 +35,7 @@ import com.sap.sailing.domain.tractracadapter.DomainFactory;
import com.sap.sailing.domain.tractracadapter.Receiver;
import com.sap.sailing.domain.tractracadapter.ReceiverType;
import com.sap.sailing.mongodb.Activator;
import com.sap.sailing.server.RacingEventServiceImpl;
public class TestStoringAndRetrievingWindTracksTest extends AbstractTracTracLiveTest implements MongoDBTest {
@@ -63,7 +64,7 @@ public class TestStoringAndRetrievingWindTracksTest extends AbstractTracTracLive
public void testStoreAFewWindEntries() throws UnknownHostException, MongoException, InterruptedException {
DomainFactory domainFactory = DomainFactory.INSTANCE;
Event domainEvent = domainFactory.getOrCreateEvent(getEvent());
DynamicTrackedEvent trackedEvent = domainFactory.getOrCreateTrackedEvent(domainEvent);
DynamicTrackedEvent trackedEvent = new RacingEventServiceImpl().getOrCreateTrackedEvent(domainEvent);
Iterable<Receiver> typeControllers = domainFactory.getUpdateReceivers(trackedEvent, getEvent(),
EmptyWindStore.INSTANCE, ReceiverType.RACECOURSE);
addListenersForStoredDataAndStartController(typeControllers);
@@ -175,7 +175,7 @@ public class AdminApp extends Servlet {
if (race == null) {
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Race not found");
} else {
DynamicTrackedRace trackedRace = getService().getDomainFactory().getTrackedEvent(event).getTrackedRace(race);
DynamicTrackedRace trackedRace = getService().getOrCreateTrackedEvent(event).getTrackedRace(race);
String windAveragingIntervalInMIllis = req.getParameter(PARAM_NAME_WIND_AVERAGING_INTERVAL_MILLIS);
if (windAveragingIntervalInMIllis != null) {
trackedRace.setMillisecondsOverWhichToAverageWind(Long.valueOf(windAveragingIntervalInMIllis));
@@ -214,7 +214,7 @@ public class AdminApp extends Servlet {
if (race == null) {
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Race not found");
} else {
TrackedRace trackedRace = getService().getDomainFactory().getTrackedEvent(event).getTrackedRace(race);
TrackedRace trackedRace = getService().getOrCreateTrackedEvent(event).getTrackedRace(race);
TimePoint time = getTimePoint(req, PARAM_NAME_TIME, PARAM_NAME_TIME_MILLIS, MillisecondsTimePoint.now());
TimePoint oneHourLater = new MillisecondsTimePoint(time.asMillis()+3600*1000);
String[] latitudes = req.getParameterValues(PARAM_NAME_LATDEG);
@@ -256,7 +256,7 @@ public class AdminApp extends Servlet {
if (race == null) {
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Race not found");
} else {
TrackedRace trackedRace = getService().getDomainFactory().getTrackedEvent(event).getTrackedRace(race);
TrackedRace trackedRace = getService().getOrCreateTrackedEvent(event).getTrackedRace(race);
TimePoint from = getTimePoint(req, PARAM_NAME_FROM_TIME, PARAM_NAME_FROM_TIME_MILLIS,
trackedRace.getStart()==null?new MillisecondsTimePoint(0):
/* 24h before race start */ new MillisecondsTimePoint(trackedRace.getStart().asMillis()-24*3600*1000));
@@ -314,7 +314,7 @@ public class AdminApp extends Servlet {
if (race == null) {
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Race not found");
} else {
TrackedRace trackedRace = getService().getDomainFactory().getTrackedEvent(event)
TrackedRace trackedRace = getService().getOrCreateTrackedEvent(event)
.getTrackedRace(race);
trackedRace.setWindSource(windSource);
resp.getWriter().println(
@@ -378,7 +378,7 @@ public class AdminApp extends Servlet {
try {
TimePoint timePoint = getTimePoint(req, PARAM_NAME_TIME, PARAM_NAME_TIME_MILLIS, MillisecondsTimePoint.now());
Wind wind = new WindImpl(p, timePoint, speed);
getService().getDomainFactory().getTrackedEvent(event).getTrackedRace(race).recordWind(wind, WindSource.WEB);
getService().getOrCreateTrackedEvent(event).getTrackedRace(race).recordWind(wind, WindSource.WEB);
} catch (InvalidDateException ex) {
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Couldn't parse time specification " + ex.getMessage());
}
@@ -407,7 +407,7 @@ public class AdminApp extends Servlet {
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Wind source name " + sourceName + " unknown");
} else {
try {
WindTrack windTrack = getService().getDomainFactory().getTrackedEvent(event)
WindTrack windTrack = getService().getOrCreateTrackedEvent(event)
.getTrackedRace(race).getWindTrack(windSource);
TimePoint timePoint = getTimePoint(req, PARAM_NAME_TIME, PARAM_NAME_TIME_MILLIS,
MillisecondsTimePoint.now());
@@ -375,7 +375,7 @@ public class ModeratorApp extends Servlet {
JSONArray jsonRaces = new JSONArray();
for (RaceDefinition race : event.getAllRaces()) {
// don't wait for the arrival of a tracked race; just ignore it if it's not currently being tracked
TrackedRace trackedRace = getService().getDomainFactory().getOrCreateTrackedEvent(event).getExistingTrackedRace(race);
TrackedRace trackedRace = getService().getOrCreateTrackedEvent(event).getExistingTrackedRace(race);
if (trackedRace != null) {
JSONObject jsonRace = new JSONObject();
jsonRace.put("name", race.getName());
@@ -18,6 +18,7 @@ import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.swisstimingadapter.SwissTimingFactory;
import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.TrackedEvent;
import com.sap.sailing.domain.tracking.TrackedEventRegistry;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
@@ -44,13 +45,11 @@ import com.sap.sailing.util.Util.Triple;
* @author Axel Uhl (d043530)
*
*/
public interface RacingEventService {
public interface RacingEventService extends TrackedEventRegistry {
Iterable<Event> getAllEvents();
Event getEventByName(String name);
DomainFactory getDomainFactory();
/**
* Defines the event and for each race listed in the JSON document that is not already being tracked by this service
* creates a {@link TracTracRaceTracker} that starts tracking the respective race. The {@link RaceDefinition}s obtained this
@@ -140,7 +139,7 @@ public interface RacingEventService {
org.json.simple.parser.ParseException, URISyntaxException;
boolean isRaceBeingTracked(RaceDefinition r);
TrackedRace getTrackedRace(Event event, RaceDefinition r);
/**
@@ -43,6 +43,7 @@ import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.WindTracker;
import com.sap.sailing.domain.tracking.WindTrackerFactory;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedEventImpl;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
import com.sap.sailing.domain.tractracadapter.JSONService;
import com.sap.sailing.domain.tractracadapter.RaceRecord;
@@ -96,6 +97,8 @@ public class RacingEventServiceImpl implements RacingEventService {
private final SwissTimingAdapterPersistence swissTimingAdapterPersistence;
private final Map<Event, DynamicTrackedEvent> eventTrackingCache;
public RacingEventServiceImpl() {
domainFactory = DomainFactory.INSTANCE;
domainObjectFactory = DomainObjectFactory.INSTANCE;
@@ -104,6 +107,7 @@ public class RacingEventServiceImpl implements RacingEventService {
swissTimingAdapterPersistence = SwissTimingAdapterPersistence.INSTANCE;
windTrackerFactory = ExpeditionWindTrackerFactory.getInstance();
eventsByName = new HashMap<String, Event>();
eventTrackingCache = new HashMap<Event, DynamicTrackedEvent>();
raceTrackersByEvent = new HashMap<Event, Set<RaceTracker>>();
windTrackers = new HashMap<RaceDefinition, WindTracker>();
raceTrackersByID = new HashMap<Object, RaceTracker>();
@@ -175,8 +179,7 @@ public class RacingEventServiceImpl implements RacingEventService {
}
}
@Override
public DomainFactory getDomainFactory() {
private DomainFactory getDomainFactory() {
return domainFactory;
}
@@ -270,7 +273,7 @@ public class RacingEventServiceImpl implements RacingEventService {
Triple<URL, URI, URI> key = new Triple<URL, URI, URI>(paramURL, liveURI, storedURI);
RaceTracker tracker = raceTrackersByID.get(key);
if (tracker == null) {
tracker = getDomainFactory().createRaceTracker(paramURL, liveURI, storedURI, windStore);
tracker = getDomainFactory().createRaceTracker(paramURL, liveURI, storedURI, windStore, this);
raceTrackersByID.put(tracker.getID(), tracker);
Set<RaceTracker> trackers = raceTrackersByEvent.get(tracker.getEvent());
if (trackers == null) {
@@ -408,7 +411,7 @@ public class RacingEventServiceImpl implements RacingEventService {
@Override
public void startTrackingWind(Event event, RaceDefinition race,
boolean correctByDeclination) throws SocketException {
windTrackerFactory.createWindTracker(getDomainFactory().getOrCreateTrackedEvent(event), race, correctByDeclination);
windTrackerFactory.createWindTracker(getOrCreateTrackedEvent(event), race, correctByDeclination);
}
@Override
@@ -435,7 +438,29 @@ public class RacingEventServiceImpl implements RacingEventService {
@Override
public TrackedRace getTrackedRace(Event e, RaceDefinition r) {
return getDomainFactory().getTrackedEvent(e).getTrackedRace(r);
return getOrCreateTrackedEvent(e).getTrackedRace(r);
}
@Override
public DynamicTrackedEvent getOrCreateTrackedEvent(Event event) {
synchronized (eventTrackingCache) {
DynamicTrackedEvent result = eventTrackingCache.get(event);
if (result == null) {
result = new DynamicTrackedEventImpl(event);
eventTrackingCache.put(event, result);
}
return result;
}
}
@Override
public DynamicTrackedEvent getTrackedEvent(com.sap.sailing.domain.base.Event event) {
return eventTrackingCache.get(event);
}
@Override
public void remove(Event event) {
eventTrackingCache.remove(event);
}
}
@@ -90,7 +90,7 @@ public abstract class Servlet extends HttpServlet {
RaceDefinition race = getRaceDefinition(req);
TrackedRace trackedRace = null;
if (event != null && race != null) {
trackedRace = getService().getDomainFactory().getTrackedEvent(event).getTrackedRace(race);
trackedRace = getService().getOrCreateTrackedEvent(event).getTrackedRace(race);
}
return trackedRace;
}
@@ -140,7 +140,7 @@ public class Action {
}
public TrackedRace getTrackedRace(Event event, RaceDefinition race) throws IOException {
DynamicTrackedEvent trackedEvent = getService().getDomainFactory().getTrackedEvent(event);
DynamicTrackedEvent trackedEvent = getService().getOrCreateTrackedEvent(event);
TrackedRace trackedRace = trackedEvent == null ? null : trackedEvent.getTrackedRace(race);
return trackedRace;
}