fixed issue with multiple boat classes per event; added test case for that

This commit is contained in:
Axel Uhl committed 2011-06-17 23:47:05 +02:00
1 parent ce3f8fc54d
commit ca128d74ce
6 files changed
+128 -15

No files matched your search

@@ -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());
}
}
@@ -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;
@@ -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;
} }
@@ -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
+1 -1
View File
@@ -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"/>