mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-04 03:13:49 +00:00
fixed issue with multiple boat classes per event; added test case for that
This commit is contained in:
1 parent
ce3f8fc54d
commit
ca128d74ce
6 files changed
+128
-15
No files matched your search
Executable
+65
@@ -0,0 +1,65 @@
|
|||||||
|
package com.sap.sailing.domain.test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotSame;
|
||||||
|
import static org.junit.Assert.assertSame;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
||||||
|
import com.sap.sailing.domain.tractracadapter.DomainFactory;
|
||||||
|
import com.sap.sailing.domain.tractracadapter.RaceTracker;
|
||||||
|
import com.sap.sailing.domain.tractracadapter.impl.DomainFactoryImpl;
|
||||||
|
|
||||||
|
public class MultipleClassesInEventTest {
|
||||||
|
private DomainFactory domainFactory;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
domainFactory = new DomainFactoryImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoadTwoRacesWithEqualEventNameButDifferentClasses() throws MalformedURLException, FileNotFoundException, URISyntaxException {
|
||||||
|
RaceTracker kiwotest1 = domainFactory
|
||||||
|
.createRaceTracker(
|
||||||
|
new URL(
|
||||||
|
"http://germanmaster.traclive.dk/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=cce678c8-97e6-11e0-9aed-406186cbf87c"),
|
||||||
|
new URI("tcp://germanmaster.traclive.dk:4400"), new URI("tcp://germanmaster.traclive.dk:4401"),
|
||||||
|
EmptyWindStore.INSTANCE);
|
||||||
|
RaceTracker kiwotest2 = domainFactory
|
||||||
|
.createRaceTracker(
|
||||||
|
new URL(
|
||||||
|
"http://germanmaster.traclive.dk/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=11290bd6-97e7-11e0-9aed-406186cbf87c"),
|
||||||
|
new URI("tcp://germanmaster.traclive.dk:4400"), new URI("tcp://germanmaster.traclive.dk:4401"),
|
||||||
|
EmptyWindStore.INSTANCE);
|
||||||
|
RaceTracker kiwotest3 = domainFactory
|
||||||
|
.createRaceTracker(
|
||||||
|
new URL(
|
||||||
|
"http://germanmaster.traclive.dk/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=39635b24-97e7-11e0-9aed-406186cbf87c"),
|
||||||
|
new URI("tcp://germanmaster.traclive.dk:4400"), new URI("tcp://germanmaster.traclive.dk:4401"),
|
||||||
|
EmptyWindStore.INSTANCE);
|
||||||
|
RaceTracker weym470may112014_2 = domainFactory
|
||||||
|
.createRaceTracker(
|
||||||
|
new URL(
|
||||||
|
"http://germanmaster.traclive.dk/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=04498426-7dfd-11e0-8236-406186cbf87c"),
|
||||||
|
new URI("tcp://germanmaster.traclive.dk:4400"), new URI("tcp://germanmaster.traclive.dk:4401"),
|
||||||
|
EmptyWindStore.INSTANCE);
|
||||||
|
|
||||||
|
assertEquals("STG", kiwotest1.getEvent().getBoatClass().getName());
|
||||||
|
assertEquals("505", kiwotest2.getEvent().getBoatClass().getName());
|
||||||
|
assertEquals("49er", kiwotest3.getEvent().getBoatClass().getName());
|
||||||
|
assertEquals("STG", weym470may112014_2.getEvent().getBoatClass().getName());
|
||||||
|
assertSame(weym470may112014_2.getEvent(), kiwotest1.getEvent());
|
||||||
|
assertNotSame(kiwotest1.getEvent(), kiwotest2.getEvent());
|
||||||
|
assertNotSame(kiwotest1.getEvent(), kiwotest3.getEvent());
|
||||||
|
assertNotSame(kiwotest2.getEvent(), kiwotest3.getEvent());
|
||||||
|
}
|
||||||
|
}
|
||||||
+29
@@ -24,8 +24,12 @@ import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
|||||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||||
import com.sap.sailing.domain.tracking.TrackedEvent;
|
import com.sap.sailing.domain.tracking.TrackedEvent;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.WindStore;
|
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.tractracadapter.impl.DomainFactoryImpl;
|
import com.sap.sailing.domain.tractracadapter.impl.DomainFactoryImpl;
|
||||||
|
import com.sap.sailing.domain.tractracadapter.impl.RaceCourseReceiver;
|
||||||
import com.tractrac.clientmodule.Competitor;
|
import com.tractrac.clientmodule.Competitor;
|
||||||
import com.tractrac.clientmodule.CompetitorClass;
|
import com.tractrac.clientmodule.CompetitorClass;
|
||||||
import com.tractrac.clientmodule.ControlPoint;
|
import com.tractrac.clientmodule.ControlPoint;
|
||||||
@@ -70,9 +74,34 @@ public interface DomainFactory {
|
|||||||
/**
|
/**
|
||||||
* Creates an {@link com.sap.sailing.domain.base.Event event} from a
|
* Creates an {@link com.sap.sailing.domain.base.Event event} from a
|
||||||
* TracTrac event description. It doesn't have {@link RaceDefinition}s yet.
|
* TracTrac event description. It doesn't have {@link RaceDefinition}s yet.
|
||||||
|
* A new {@link com.sap.sailing.domain.base.Event} is created if no event by
|
||||||
|
* an equal name with a boat class with an equal name as the <code>event</code>'s
|
||||||
|
* boat class exists yet.
|
||||||
*/
|
*/
|
||||||
com.sap.sailing.domain.base.Event createEvent(Event event);
|
com.sap.sailing.domain.base.Event createEvent(Event event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a race tracked for the specified URL/URIs and starts receiving all available existing and future push
|
||||||
|
* data from there. Receiving continues until {@link RaceTracker#stop()} is called.
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* A race tracker uses the <code>paramURL</code> for the TracTrac Java client to register for push data about one
|
||||||
|
* race. The {@link RaceDefinition} for that race, however, isn't created until the {@link Course} has been
|
||||||
|
* received. Therefore, the {@link RaceCourseReceiver} will create the {@link RaceDefinition} and will add it to the
|
||||||
|
* {@link com.sap.sailing.domain.base.Event}.
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* The link to the {@link RaceDefinition} is created in the {@link DomainFactory} when the
|
||||||
|
* {@link RaceCourseReceiver} creates the {@link TrackedRace} object. Starting then, the {@link DomainFactory} will
|
||||||
|
* respond with the {@link RaceDefinition} when its {@link DomainFactory#getRace(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.
|
||||||
|
*/
|
||||||
RaceTracker createRaceTracker(URL paramURL, URI liveURI, URI storedURI, WindStore windStore) throws MalformedURLException,
|
RaceTracker createRaceTracker(URL paramURL, URI liveURI, URI storedURI, WindStore windStore) throws MalformedURLException,
|
||||||
FileNotFoundException, URISyntaxException;
|
FileNotFoundException, URISyntaxException;
|
||||||
|
|
||||||
|
|||||||
+23
-6
@@ -61,6 +61,7 @@ import com.sap.sailing.domain.tractracadapter.JSONService;
|
|||||||
import com.sap.sailing.domain.tractracadapter.RaceTracker;
|
import com.sap.sailing.domain.tractracadapter.RaceTracker;
|
||||||
import com.sap.sailing.domain.tractracadapter.Receiver;
|
import com.sap.sailing.domain.tractracadapter.Receiver;
|
||||||
import com.sap.sailing.domain.tractracadapter.ReceiverType;
|
import com.sap.sailing.domain.tractracadapter.ReceiverType;
|
||||||
|
import com.sap.sailing.util.Util.Pair;
|
||||||
import com.tractrac.clientmodule.CompetitorClass;
|
import com.tractrac.clientmodule.CompetitorClass;
|
||||||
import com.tractrac.clientmodule.ControlPoint;
|
import com.tractrac.clientmodule.ControlPoint;
|
||||||
import com.tractrac.clientmodule.Race;
|
import com.tractrac.clientmodule.Race;
|
||||||
@@ -99,10 +100,10 @@ public class DomainFactoryImpl implements DomainFactory {
|
|||||||
private final Map<CompetitorClass, BoatClass> classCache = new HashMap<CompetitorClass, BoatClass>();
|
private final Map<CompetitorClass, BoatClass> classCache = new HashMap<CompetitorClass, BoatClass>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caches events by their name
|
* Caches events by their name and their boat class's name
|
||||||
*/
|
*/
|
||||||
private final Map<String, com.sap.sailing.domain.base.Event> eventCache =
|
private final Map<Pair<String, String>, com.sap.sailing.domain.base.Event> eventCache =
|
||||||
new HashMap<String, com.sap.sailing.domain.base.Event>();
|
new HashMap<Pair<String, String>, com.sap.sailing.domain.base.Event>();
|
||||||
|
|
||||||
private final Map<com.tractrac.clientmodule.Event, RaceDefinition> tractracEventToRaceDefinitionMap = new HashMap<com.tractrac.clientmodule.Event, RaceDefinition>();
|
private final Map<com.tractrac.clientmodule.Event, RaceDefinition> tractracEventToRaceDefinitionMap = new HashMap<com.tractrac.clientmodule.Event, RaceDefinition>();
|
||||||
|
|
||||||
@@ -292,10 +293,26 @@ public class DomainFactoryImpl implements DomainFactory {
|
|||||||
@Override
|
@Override
|
||||||
public Event createEvent(com.tractrac.clientmodule.Event event) {
|
public Event createEvent(com.tractrac.clientmodule.Event event) {
|
||||||
synchronized (eventCache) {
|
synchronized (eventCache) {
|
||||||
Event result = eventCache.get(event.getName());
|
// FIXME Dialog with Lasse by Skype on 2011-06-17:
|
||||||
|
// [6:20:04 PM] Axel Uhl: Lasse, can Event.getCompetitorClassList() ever produce more than one result?
|
||||||
|
// [6:20:20 PM] Axel Uhl: Or is it similar to Event.getRaceList() which always delivers one Race?
|
||||||
|
// [6:22:19 PM] Lasse Staffensen: It can deliver several classes, if more classes are present in a race.
|
||||||
|
// [6:27:20 PM] Axel Uhl: Will that happen at Kiel Week?
|
||||||
|
// [6:27:58 PM] Lasse Staffensen: No
|
||||||
|
// [6:28:34 PM] Axel Uhl: Good :)
|
||||||
|
// This means that currently it is permissible to assume that we'll get at most one
|
||||||
|
// boat class per TracTrac event. Generally, however, we have to assume that
|
||||||
|
// one TracTrac event may map to multiple domain Event objects with one BoatClass each
|
||||||
|
Collection<CompetitorClass> competitorClassList = event.getCompetitorClassList();
|
||||||
|
BoatClass boatClass = null;
|
||||||
|
if (competitorClassList != null && !competitorClassList.isEmpty()) {
|
||||||
|
boatClass = getBoatClass(competitorClassList.iterator().next());
|
||||||
|
}
|
||||||
|
Pair<String, String> key = new Pair<String, String>(event.getName(), boatClass==null?null:boatClass.getName());
|
||||||
|
Event result = eventCache.get(key);
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
result = new EventImpl(event.getName());
|
result = new EventImpl(event.getName(), boatClass);
|
||||||
eventCache.put(event.getName(), result);
|
eventCache.put(key, result);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -47,6 +47,12 @@ public class MarkPositionReceiver extends AbstractReceiverWithQueue<ControlPoint
|
|||||||
super(domainFactory);
|
super(domainFactory);
|
||||||
this.tractracEvent = tractracEvent;
|
this.tractracEvent = tractracEvent;
|
||||||
// assumption: there is currently only one race per TracTrac Event object
|
// assumption: there is currently only one race per TracTrac Event object
|
||||||
|
if (tractracEvent.getRaceList().isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("Can't receive mark positions from event "+tractracEvent.getName()+" that has no race");
|
||||||
|
}
|
||||||
|
if (tractracEvent.getRaceList().size() > 1) {
|
||||||
|
logger.warning("Received event "+tractracEvent.getName()+" that has more than one race ("+tractracEvent.getRaceList().size()+")");
|
||||||
|
}
|
||||||
final Race race = tractracEvent.getRaceList().iterator().next();
|
final Race race = tractracEvent.getRaceList().iterator().next();
|
||||||
new Thread("MarkPositionReceiver waiting for RaceDefinition for "+race.getName()) {
|
new Thread("MarkPositionReceiver waiting for RaceDefinition for "+race.getName()) {
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.sap.sailing.domain.base.impl;
|
package com.sap.sailing.domain.base.impl;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.sap.sailing.domain.base.BoatClass;
|
import com.sap.sailing.domain.base.BoatClass;
|
||||||
@@ -11,10 +10,12 @@ import com.sap.sailing.domain.base.RaceDefinition;
|
|||||||
|
|
||||||
public class EventImpl extends NamedImpl implements Event {
|
public class EventImpl extends NamedImpl implements Event {
|
||||||
private final Set<RaceDefinition> races;
|
private final Set<RaceDefinition> races;
|
||||||
|
private final BoatClass boatClass;
|
||||||
|
|
||||||
public EventImpl(String name) {
|
public EventImpl(String name, BoatClass boatClass) {
|
||||||
super(name);
|
super(name);
|
||||||
races = new HashSet<RaceDefinition>();
|
races = new HashSet<RaceDefinition>();
|
||||||
|
this.boatClass = boatClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -32,12 +33,7 @@ public class EventImpl extends NamedImpl implements Event {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BoatClass getBoatClass() {
|
public BoatClass getBoatClass() {
|
||||||
Iterator<RaceDefinition> raceIter = getAllRaces().iterator();
|
return boatClass;
|
||||||
if (raceIter.hasNext()) {
|
|
||||||
return raceIter.next().getBoatClass();
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<classpathentry kind="src" path="src"/>
|
<classpathentry kind="src" path="src"/>
|
||||||
<classpathentry exported="true" kind="lib" path="lib/TracTracClientModule.jar">
|
<classpathentry exported="true" kind="lib" path="lib/TracTracClientModule.jar">
|
||||||
<attributes>
|
<attributes>
|
||||||
<attribute name="javadoc_location" value="file:/C:/data/SAP/sailing/workspace/com.tractrac.clientmodule/javadoc/"/>
|
<attribute name="javadoc_location" value="file:/C:/data/SAP/sailing/workspace/java/com.tractrac.clientmodule/javadoc/"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</classpathentry>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||||
|
|||||||
Reference in new issue
Block a user