adjusted SwissTiming connector to accomodate UUIDs for mark devices and competitors

Change-Id: Ieaca20de4eacbbc5c64e218fb557045f2590e6f6
This commit is contained in:
Axel Uhl committed 2018-04-19 17:24:54 +02:00
1 parent e3bbce0b99
commit 18c777a99f
41 files changed
+242 -232

No files matched your search

@@ -263,6 +263,7 @@ import com.sap.sse.shared.media.VideoDescriptor;
import com.sap.sse.shared.media.impl.ImageDescriptorImpl;
import com.sap.sse.shared.media.impl.VideoDescriptorImpl;
import com.sap.sse.util.ThreadPoolUtil;
import com.sap.sse.util.impl.UUIDHelper;
public class DomainObjectFactoryImpl implements DomainObjectFactory {
private static final Logger logger = Logger.getLogger(DomainObjectFactoryImpl.class.getName());
@@ -1626,7 +1627,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
private RaceLogEvent loadRaceLogRevokeEvent(TimePoint createdAt, AbstractLogEventAuthor author,
TimePoint logicalTimePoint, Serializable id, Integer passId, List<Competitor> competitors,
DBObject dbObject) {
Serializable revokedEventId = Helpers
Serializable revokedEventId = UUIDHelper
.tryUuidConversion((Serializable) dbObject.get(FieldNames.RACE_LOG_REVOKED_EVENT_ID.name()));
String revokedEventType = (String) dbObject.get(FieldNames.RACE_LOG_REVOKED_EVENT_TYPE.name());
String revokedEventShortInfo = (String) dbObject.get(FieldNames.RACE_LOG_REVOKED_EVENT_SHORT_INFO.name());
@@ -2044,7 +2045,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
private RegattaLogRevokeEvent loadRegattaLogRevokeEvent(TimePoint createdAt, AbstractLogEventAuthor author,
TimePoint logicalTimePoint, Serializable id, DBObject dbObject) {
Serializable revokedEventId = Helpers
Serializable revokedEventId = UUIDHelper
.tryUuidConversion((Serializable) dbObject.get(FieldNames.REGATTA_LOG_REVOKED_EVENT_ID.name()));
String revokedEventType = (String) dbObject.get(FieldNames.REGATTA_LOG_REVOKED_EVENT_TYPE.name());
String revokedEventShortInfo = (String) dbObject.get(FieldNames.REGATTA_LOG_REVOKED_EVENT_SHORT_INFO.name());
@@ -2092,7 +2093,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
private RegattaLogCloseOpenEndedDeviceMappingEvent loadRegattaLogCloseOpenEndedDeviceMappingEvent(
TimePoint createdAt, AbstractLogEventAuthor author, TimePoint logicalTimePoint, Serializable id,
DBObject dbObject) {
Serializable deviceMappingEventId = Helpers
Serializable deviceMappingEventId = UUIDHelper
.tryUuidConversion((Serializable) dbObject.get(FieldNames.REGATTA_LOG_DEVICE_MAPPING_EVENT_ID.name()));
TimePoint closingTimePointInclusive = loadTimePoint(dbObject, FieldNames.REGATTA_LOG_CLOSING_TIMEPOINT);
return new RegattaLogCloseOpenEndedDeviceMappingEventImpl(createdAt, author, logicalTimePoint, id,
@@ -113,4 +113,6 @@ public interface SharedDomainFactory extends CompetitorFactory, BoatFactory {
RaceLogResolver getRaceLogResolver();
Mark getOrCreateMark(String name, MarkType markType);
Mark getOrCreateMark(Serializable id, String name, MarkType markType);
}
@@ -161,7 +161,8 @@ public class SharedDomainFactoryImpl implements SharedDomainFactory {
return getOrCreateMark(name, name, markType);
}
private Mark getOrCreateMark(Serializable id, String name, MarkType markType) {
@Override
public Mark getOrCreateMark(Serializable id, String name, MarkType markType) {
return getOrCreateMark(id, name, markType, /* color */ null, /* shape */ null, /* pattern */ null);
}
@@ -44,7 +44,7 @@ public class SwissTimingConnectivityParamsHandler extends AbstractRaceTrackingCo
private static final String COMPETITOR_THREE_LETTER_IOC_CODE = "competitorThreeLetterIocCode";
private static final String COMPETITOR_NAME = "competitorName";
private static final String COMPETITOR_BOAT_ID = "competitorBoatId";
private static final String COMPETITOR_ID = "competitorId";
private static final String COMPETITOR_ID_AS_STRING = "competitorId"; // the competitor ID as String
private static final String USE_INTERNAL_MARK_PASSING_ALGORITHM = "useInternalMarkPassingAlgorithm";
private static final String DELAY_TO_LIVE_IN_MILLIS = "delayToLiveInMillis";
private static final String START_LIST = "startList";
@@ -107,7 +107,7 @@ public class SwissTimingConnectivityParamsHandler extends AbstractRaceTrackingCo
private DBObject createCompetitorDBObject(Competitor competitor) {
final DBObject result = new BasicDBObject();
result.put(COMPETITOR_ID, competitor.getID());
result.put(COMPETITOR_ID_AS_STRING, competitor.getIdAsString());
result.put(COMPETITOR_BOAT_ID, competitor.getBoatID());
result.put(COMPETITOR_NAME, competitor.getName());
result.put(COMPETITOR_THREE_LETTER_IOC_CODE, competitor.getThreeLetterIOCCode());
@@ -150,15 +150,15 @@ public class SwissTimingConnectivityParamsHandler extends AbstractRaceTrackingCo
private Competitor createCompetitorFromDBObject(DBObject competitorDBObject) {
final Competitor result;
final String competitorId = (String) competitorDBObject.get(COMPETITOR_ID);
final String competitorIdAsString = (String) competitorDBObject.get(COMPETITOR_ID_AS_STRING);
final String boatID = (String) competitorDBObject.get(COMPETITOR_BOAT_ID);
final String threeLetterIOCCode = (String) competitorDBObject.get(COMPETITOR_THREE_LETTER_IOC_CODE);
final String name = (String) competitorDBObject.get(COMPETITOR_NAME);
final BasicDBList crewDBObject = (BasicDBList) competitorDBObject.get(COMPETITOR_CREW);
if (competitorId == null) {
if (competitorIdAsString == null) {
result = new CompetitorWithoutID(boatID, threeLetterIOCCode, name);
} else {
result = new CompetitorWithID(competitorId, boatID, threeLetterIOCCode, name, createCrewFromDBObject(crewDBObject));
result = new CompetitorWithID(competitorIdAsString, boatID, threeLetterIOCCode, name, createCrewFromDBObject(crewDBObject));
}
return result;
}
@@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import com.sap.sailing.domain.swisstimingadapter.Mark;
import com.sap.sse.common.Util;
public class CCGMessage {
private String raceId;
@@ -37,17 +38,11 @@ public class CCGMessage {
@Override
public String toString() {
// TODO Auto-generated method stub
String s = "";
for (Mark m : markList) {
s = s + "|" + m.getIndex() + ";" + m.getDescription() + ";";
for (String str : m.getDevices()) {
s = s + str + ";";
}
s = s.substring(0, s.length() - 1);
s += Util.join(";", m.getDeviceIds());
}
return "CCG|" +raceId + "|" + markList.size() + s;
}
}
@@ -6,6 +6,7 @@ import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -13,6 +14,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import com.sap.sailing.domain.common.Distance;
import com.sap.sailing.domain.common.Speed;
@@ -205,9 +208,8 @@ public class MessageFileServiceImpl implements MessageFileService {
} else {
devicesNamesStartIndex = 2;
}
marks.add(new MarkImpl(markDetails[1], Integer.valueOf(markDetails[0]),
Arrays.asList(markDetails).subList(devicesNamesStartIndex, markDetails.length),
markType));
List<Serializable> markIds = Arrays.asList(markDetails).subList(devicesNamesStartIndex, markDetails.length).stream().map(idAsString->UUID.fromString(idAsString)).collect(Collectors.toList());
marks.add(new MarkImpl(markDetails[1], Integer.valueOf(markDetails[0]), markIds, markType));
}
return new CCGMessage(raceId, marks);
}
@@ -239,11 +239,11 @@ public class SailMasterConnectivityTest {
Iterator<Mark> mi = course1.getMarks().iterator();
Mark m11 = mi.next();
assertEquals("Lee Gate", m11.getDescription());
assertEquals(Arrays.asList(new String[] { "LG1", "LG2" }), m11.getDevices());
assertEquals(Arrays.asList(new String[] { "LG1", "LG2" }), m11.getDeviceIds());
assertEquals(1, m11.getIndex());
Mark m12 = mi.next();
assertEquals("Windward", m12.getDescription());
assertEquals(Arrays.asList(new String[] { "WW1" }), m12.getDevices());
assertEquals(Arrays.asList(new String[] { "WW1" }), m12.getDeviceIds());
assertEquals(2, m12.getIndex());
Race r2 = connector4712.getRace();
@@ -253,15 +253,15 @@ public class SailMasterConnectivityTest {
mi = course2.getMarks().iterator();
Mark m21 = mi.next();
assertEquals("Lee Gate", m21.getDescription());
assertEquals(Arrays.asList(new String[] { "LG1", "LG2" }), m21.getDevices());
assertEquals(Arrays.asList(new String[] { "LG1", "LG2" }), m21.getDeviceIds());
assertEquals(1, m21.getIndex());
Mark m22 = mi.next();
assertEquals("Windward", m22.getDescription());
assertEquals(Arrays.asList(new String[] { "WW1" }), m22.getDevices());
assertEquals(Arrays.asList(new String[] { "WW1" }), m22.getDeviceIds());
assertEquals(2, m22.getIndex());
Mark m23 = mi.next();
assertEquals("Offset", m23.getDescription());
assertEquals(Arrays.asList(new String[] { "OS1" }), m23.getDevices());
assertEquals(Arrays.asList(new String[] { "OS1" }), m23.getDeviceIds());
assertEquals(3, m23.getIndex());
}
@@ -10,6 +10,7 @@
*/
package com.sap.sailing.domain.swisstimingadapter.test.ui;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@@ -248,11 +249,12 @@ public class EditCCG extends javax.swing.JDialog {
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
// TODO add your handling code here:
List<String> devices = new ArrayList<String>();
devices.add(jSailNumber1.getText());
if (jRadioButton2.isSelected())
devices.add(jSailNumber2.getText());
marks.add(new MarkWithDesc(jMarkDescription.getText(), Integer.parseInt(jMarkIndex.getText()),devices));
List<Serializable> deviceIds = new ArrayList<>();
deviceIds.add(jSailNumber1.getText());
if (jRadioButton2.isSelected()) {
deviceIds.add(jSailNumber2.getText());
}
marks.add(new MarkWithDesc(jMarkDescription.getText(), Integer.parseInt(jMarkIndex.getText()), deviceIds));
jMarkList.setListData(marks.toArray(new CCGMessage[0]));
}//GEN-LAST:event_jButton2ActionPerformed
@@ -272,13 +274,13 @@ public class EditCCG extends javax.swing.JDialog {
private class MarkWithDesc extends MarkImpl {
public MarkWithDesc(String description, int index, Iterable<String> devices) {
super(description, index, devices, /* markType */ null);
public MarkWithDesc(String description, int index, Iterable<Serializable> deviceIds) {
super(description, index, deviceIds, /* markType */ null);
}
@Override
public String toString(){
return "Mark " + getIndex() + ": " + getDescription() + getDevices();
return "Mark " + getIndex() + ": " + getDescription() + getDeviceIds();
}
}
@@ -11,5 +11,5 @@ public interface Competitor {
String getName();
String getID();
String getIdAsString();
}
@@ -1,5 +1,6 @@
package com.sap.sailing.domain.swisstimingadapter;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
@@ -46,7 +47,7 @@ public interface DomainFactory {
Pair<Competitor, Boat> createCompetitorWithID(com.sap.sailing.domain.swisstimingadapter.Competitor competitor, BoatClass boatClass);
Pair<Competitor, Boat> createCompetitorWithoutID(String boatID, String threeLetterIOCCode, String name, String raceId, BoatClass boatClass);
Pair<Competitor, Boat> createCompetitorWithoutID(String competitorId, String threeLetterIOCCode, String name, String raceId, BoatClass boatClass);
String getCompetitorID(String boatID, RaceType raceType);
@@ -54,7 +55,7 @@ public interface DomainFactory {
RaceDefinition createRaceDefinition(Regatta regatta, Race race, StartList startList, com.sap.sailing.domain.swisstimingadapter.Course course);
com.sap.sailing.domain.base.Mark getOrCreateMark(String trackerID);
com.sap.sailing.domain.base.Mark getOrCreateMark(Serializable trackerID, String description);
GPSFixMoving createGPSFix(TimePoint timePointOfTransmission, Fix fix);
@@ -71,7 +72,7 @@ public interface DomainFactory {
long delayToLiveInMillis, SwissTimingFactory swissTimingFactory, DomainFactory domainFactory,
RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, boolean useInternalMarkPassingAlgorithm, boolean trackWind, boolean correctWindDirectionByMagneticDeclination);
ControlPoint getOrCreateControlPoint(Iterable<String> devices, MarkType markType);
ControlPoint getOrCreateControlPoint(String description, Iterable<Serializable> deviceIds, MarkType markType);
RaceDefinition createRaceDefinition(Regatta regatta, String swissTimingRaceID, Map<Competitor, Boat> competitorsAndBoats,
List<ControlPoint> courseDefinition, String raceName, String raceIdForRaceDefinition);
@@ -1,5 +1,7 @@
package com.sap.sailing.domain.swisstimingadapter;
import java.io.Serializable;
import com.sap.sailing.domain.common.Distance;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.Speed;
@@ -13,7 +15,7 @@ import com.sap.sailing.domain.common.SpeedWithBearing;
*
*/
public interface Fix {
String getBoatID();
Serializable getTrackedObjectId();
TrackerType getTrackerType();
@@ -1,11 +1,13 @@
package com.sap.sailing.domain.swisstimingadapter;
import java.io.Serializable;
public interface Mark extends WithDescription {
public enum MarkType { MANUAL, LINE_CROSSING, BUOY_ROUNDING };
int getIndex();
Iterable<String> getDevices();
Iterable<Serializable> getDeviceIds();
MarkType getMarkType();
}
@@ -1,7 +1,5 @@
package com.sap.sailing.domain.swisstimingadapter;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sse.common.Util;
@@ -10,6 +8,4 @@ public interface SwissTimingRaceTracker extends RaceTracker {
* The key for a SwissTiming race tracker is the triple of raceID, host name and port number.
*/
Util.Triple<String, String, Integer> getID();
Competitor getCompetitorByBoatIDAndRaceIDOrBoatClass(String boatID, String raceID, BoatClass boatClass);
}
@@ -29,7 +29,7 @@ public abstract class AbstractCompetitor implements Competitor {
return name;
}
public String getID() {
public String getIdAsString() {
return null;
}
@@ -5,17 +5,17 @@ import java.util.List;
import com.sap.sailing.domain.swisstimingadapter.CrewMember;
public class CompetitorWithID extends AbstractCompetitor {
private final String id;
private final String idAsString;
private List<CrewMember> crew;
public CompetitorWithID(String id, String boatID, String threeLetterIOCCode, String name, List<CrewMember> crew) {
public CompetitorWithID(String idAsString, String boatID, String threeLetterIOCCode, String name, List<CrewMember> crew) {
super(boatID, threeLetterIOCCode, name);
this.id = id;
this.idAsString = idAsString;
this.crew = crew;
}
public String getID() {
return id;
public String getIdAsString() {
return idAsString;
}
@Override
@@ -28,7 +28,7 @@ public class CompetitorWithID extends AbstractCompetitor {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((crew == null) ? 0 : crew.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((idAsString == null) ? 0 : idAsString.hashCode());
return result;
}
@@ -46,10 +46,10 @@ public class CompetitorWithID extends AbstractCompetitor {
return false;
} else if (!crew.equals(other.crew))
return false;
if (id == null) {
if (other.id != null)
if (idAsString == null) {
if (other.idAsString != null)
return false;
} else if (!id.equals(other.id))
} else if (!idAsString.equals(other.idAsString))
return false;
return true;
}
@@ -57,6 +57,6 @@ public class CompetitorWithID extends AbstractCompetitor {
@Override
public String toString() {
return "CompetitorWithID [boatID=" + getBoatID() + ", threeLetterIOCCode=" + getThreeLetterIOCCode() + ", name=" + getName()
+ ", id=" + id + ", crew=" + getCrew() + "]";
+ ", id=" + idAsString + ", crew=" + getCrew() + "]";
}
}
@@ -10,7 +10,7 @@ public class CompetitorWithoutID extends AbstractCompetitor {
}
@Override
public String getID() {
public String getIdAsString() {
return null;
}
@@ -1,5 +1,6 @@
package com.sap.sailing.domain.swisstimingadapter.impl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
@@ -58,6 +59,7 @@ import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.WithID;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.util.impl.UUIDHelper;
import difflib.PatchFailedException;
@@ -72,7 +74,7 @@ import difflib.PatchFailedException;
public class DomainFactoryImpl implements DomainFactory {
private final static Logger logger = Logger.getLogger(DomainFactoryImpl.class.getName());
private final Map<String, Regatta> raceIDToRegattaCache;
private final Map<Iterable<String>, ControlPoint> controlPointCache;
private final Map<Iterable<Serializable>, ControlPoint> controlPointCache;
private final Map<String, RaceType> raceTypeByID;
private final RaceType unknownRaceType;
private final com.sap.sailing.domain.base.DomainFactory baseDomainFactory;
@@ -80,7 +82,7 @@ public class DomainFactoryImpl implements DomainFactory {
public DomainFactoryImpl(com.sap.sailing.domain.base.DomainFactory baseDomainFactory) {
this.baseDomainFactory = baseDomainFactory;
raceIDToRegattaCache = new HashMap<String, Regatta>();
controlPointCache = new HashMap<Iterable<String>, ControlPoint>();
controlPointCache = new HashMap<>();
raceTypeByID = new HashMap<String, RaceType>();
for (OlympicRaceCode olympicRaceCode : OlympicRaceCode.values()) {
@@ -121,7 +123,8 @@ public class DomainFactoryImpl implements DomainFactory {
@Override
public Pair<Competitor, Boat> createCompetitorWithID(com.sap.sailing.domain.swisstimingadapter.Competitor competitor, BoatClass boatClass) {
CompetitorAndBoatStore competitorAndBoatStore = baseDomainFactory.getCompetitorAndBoatStore();
CompetitorWithBoat domainCompetitor = competitorAndBoatStore.getExistingCompetitorWithBoatByIdAsString(competitor.getID());
final Serializable competitorId = UUIDHelper.tryUuidConversion(competitor.getIdAsString());
CompetitorWithBoat domainCompetitor = competitorAndBoatStore.getExistingCompetitorWithBoatById(competitorId);
if (domainCompetitor == null || competitorAndBoatStore.isCompetitorToUpdateDuringGetOrCreate(domainCompetitor)) {
List<DynamicPerson> teamMembers = new ArrayList<DynamicPerson>();
for (CrewMember crewMember: competitor.getCrew()) {
@@ -130,8 +133,8 @@ public class DomainFactoryImpl implements DomainFactory {
teamMembers.add(person);
}
DynamicTeam team = new TeamImpl(competitor.getName(), teamMembers, /* coach */ null);
DynamicBoat domainBoat = new BoatImpl(competitor.getID(), null, boatClass, competitor.getBoatID(), null);
domainCompetitor = competitorAndBoatStore.getOrCreateCompetitorWithBoat(competitor.getID(), competitor.getName(), null /* shortName */, null /*displayColor*/, null /*email*/, null, team,
DynamicBoat domainBoat = new BoatImpl(competitorId, null, boatClass, competitor.getBoatID(), null);
domainCompetitor = competitorAndBoatStore.getOrCreateCompetitorWithBoat(competitorId, competitor.getName(), null /* shortName */, null /*displayColor*/, null /*email*/, null, team,
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, domainBoat);
}
return new Pair<Competitor, Boat>(domainCompetitor, domainCompetitor.getBoat());
@@ -266,8 +269,8 @@ public class DomainFactoryImpl implements DomainFactory {
private Map<Competitor,Boat> createCompetitorsAndBoats(StartList startList, String raceId, BoatClass boatClass) {
Map<Competitor, Boat> result = new LinkedHashMap<>();
for (com.sap.sailing.domain.swisstimingadapter.Competitor swissTimingCompetitor : startList.getCompetitors()) {
Pair<Competitor,Boat> domainCompetitorAndBoat;
if (swissTimingCompetitor.getID() != null) {
Pair<Competitor, Boat> domainCompetitorAndBoat;
if (swissTimingCompetitor.getIdAsString() != null) {
domainCompetitorAndBoat = createCompetitorWithID(swissTimingCompetitor, boatClass);
} else {
domainCompetitorAndBoat = createCompetitorWithoutID(swissTimingCompetitor, raceId, boatClass);
@@ -280,7 +283,7 @@ public class DomainFactoryImpl implements DomainFactory {
private com.sap.sailing.domain.base.Course createCourse(String courseName, Course course) {
List<Waypoint> waypoints = new ArrayList<Waypoint>();
for (Mark mark : course.getMarks()) {
ControlPoint controlPoint = getOrCreateControlPoint(mark.getDevices(), getMarkType(mark.getMarkType()));
ControlPoint controlPoint = getOrCreateControlPoint(mark.getDescription(), mark.getDeviceIds(), getMarkType(mark.getMarkType()));
Waypoint waypoint = baseDomainFactory.createWaypoint(controlPoint, /* passingInstruction */ PassingInstruction.None);
waypoints.add(waypoint);
}
@@ -302,44 +305,44 @@ public class DomainFactoryImpl implements DomainFactory {
}
@Override
public ControlPoint getOrCreateControlPoint(Iterable<String> devices, MarkType markType) {
public ControlPoint getOrCreateControlPoint(String description, Iterable<Serializable> deviceIds, MarkType markType) {
ControlPoint result;
synchronized (controlPointCache) {
result = controlPointCache.get(devices);
result = controlPointCache.get(deviceIds);
if (result == null) {
switch (Util.size(devices)) {
switch (Util.size(deviceIds)) {
case 1:
result = getOrCreateMark(devices.iterator().next(), markType);
result = getOrCreateMark(description, deviceIds.iterator().next(), markType);
break;
case 2:
Iterator<String> markNameIter = devices.iterator();
String left = markNameIter.next();
String right = markNameIter.next();
result = baseDomainFactory.createControlPointWithTwoMarks(getOrCreateMark(left), getOrCreateMark(right), left + "/" + right);
Iterator<Serializable> markNameIter = deviceIds.iterator();
final Serializable idLeft = markNameIter.next();
final Serializable idRight = markNameIter.next();
result = baseDomainFactory.createControlPointWithTwoMarks(getOrCreateMark(idLeft, description), getOrCreateMark(idRight, description), description);
break;
default:
throw new RuntimeException(
"Don't know how to handle control points with number of devices neither 1 nor 2. Was "
+ Util.size(devices));
+ Util.size(deviceIds));
}
controlPointCache.put(devices, result);
controlPointCache.put(deviceIds, result);
}
}
return result;
}
private ControlPoint getOrCreateMark(String name, MarkType markType) {
return baseDomainFactory.getOrCreateMark(name, markType);
private ControlPoint getOrCreateMark(String description, Serializable id, MarkType markType) {
return baseDomainFactory.getOrCreateMark(id, description, markType);
}
/**
* @param trackerID
* @param trackerId
* the "device name" and the "sail number" in case of an {@link MessageType#RPD RPD} message, used as the mark's
* {@link Named#getName() name} and {@link WithID#getId() ID}.
*/
@Override
public com.sap.sailing.domain.base.Mark getOrCreateMark(String trackerID) {
return baseDomainFactory.getOrCreateMark(trackerID);
public com.sap.sailing.domain.base.Mark getOrCreateMark(Serializable trackerId, String description) {
return baseDomainFactory.getOrCreateMark(trackerId, description);
}
@Override
@@ -354,7 +357,7 @@ public class DomainFactoryImpl implements DomainFactory {
List<com.sap.sse.common.Util.Pair<com.sap.sailing.domain.base.ControlPoint, PassingInstruction>> newDomainControlPoints = new ArrayList<com.sap.sse.common.Util.Pair<com.sap.sailing.domain.base.ControlPoint, PassingInstruction>>();
for (Mark mark : marks) {
// TODO bug 1043: propagate the mark names to the waypoint names
com.sap.sailing.domain.base.ControlPoint domainControlPoint = getOrCreateControlPoint(mark.getDevices(), getMarkType(mark.getMarkType()));
com.sap.sailing.domain.base.ControlPoint domainControlPoint = getOrCreateControlPoint(mark.getDescription(), mark.getDeviceIds(), getMarkType(mark.getMarkType()));
newDomainControlPoints.add(new com.sap.sse.common.Util.Pair<>(domainControlPoint, PassingInstruction.None));
}
courseToUpdate.update(newDomainControlPoints, baseDomainFactory);
@@ -1,5 +1,7 @@
package com.sap.sailing.domain.swisstimingadapter.impl;
import java.io.Serializable;
import com.sap.sailing.domain.common.Distance;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.Speed;
@@ -8,7 +10,7 @@ import com.sap.sailing.domain.swisstimingadapter.Fix;
import com.sap.sailing.domain.swisstimingadapter.TrackerType;
public class FixImpl implements Fix {
private final String boatID;
private final Serializable trackedObjectId;
private final TrackerType trackerType;
private final Long ageOfDataInMilliseconds;
private final Position position;
@@ -25,11 +27,11 @@ public class FixImpl implements Fix {
*/
private final String boatIRM;
public FixImpl(String boatID, TrackerType trackerType, Long ageOfDataInMilliseconds, Position position,
public FixImpl(Serializable trackedObjectId, TrackerType trackerType, Long ageOfDataInMilliseconds, Position position,
SpeedWithBearing speed, Integer nextMarkIndex, Integer rank, Speed averageSpeedOverGroundPerLeg,
Speed velocityMadeGood, Distance distanceToLeader, Distance distanceToNextMark, String boatIRM) {
super();
this.boatID = boatID;
this.trackedObjectId = trackedObjectId;
this.trackerType = trackerType;
this.ageOfDataInMilliseconds = ageOfDataInMilliseconds;
this.position = position;
@@ -49,8 +51,8 @@ public class FixImpl implements Fix {
}
@Override
public String getBoatID() {
return boatID;
public Serializable getTrackedObjectId() {
return trackedObjectId;
}
@Override
@@ -1,25 +1,28 @@
package com.sap.sailing.domain.swisstimingadapter.impl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.sap.sailing.domain.swisstimingadapter.Mark;
import com.sap.sse.common.Util;
public class MarkImpl implements Mark {
private final String description;
private final int index;
private final Iterable<String> devices;
private final Iterable<Serializable> deviceIds;
private final MarkType markType;
public MarkImpl(String description, int index, Iterable<String> devices, MarkType markType) {
public MarkImpl(String description, int index, Iterable<Serializable> devices, MarkType markType) {
super();
this.description = description;
this.index = index;
this.markType = markType;
ArrayList<String> l = new ArrayList<String>();
for (String device : devices) {
List<Serializable> l = new ArrayList<>();
for (Serializable device : devices) {
l.add(device);
}
this.devices = l;
this.deviceIds = l;
}
@Override
@@ -38,8 +41,8 @@ public class MarkImpl implements Mark {
}
@Override
public Iterable<String> getDevices() {
return devices;
public Iterable<Serializable> getDeviceIds() {
return deviceIds;
}
@Override
@@ -49,11 +52,7 @@ public class MarkImpl implements Mark {
result.append(": ");
result.append(getDescription());
result.append(" [");
for (String device : getDevices()) {
result.append(device);
result.append(", ");
}
result.delete(result.length()-2, result.length());
result.append(Util.join(", ", getDeviceIds()));
result.append("]");
return result.toString();
}
@@ -25,6 +25,7 @@ import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.common.AbstractBearing;
@@ -55,6 +56,7 @@ import com.sap.sailing.domain.swisstimingadapter.TrackerType;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.util.impl.UUIDHelper;
/**
* Implements the connector to the SwissTiming Sail Master system. It uses a host name and port number to establish the
@@ -283,7 +285,7 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement
private void notifyListenersTMD(SailMasterMessage message) {
// example message: TMD|W4702|NZL 75|1|4;;00:49:43
String raceID = message.getSections()[1];
String boatID = message.getSections()[2];
String competitorIdAsString = message.getSections()[2];
int count = Integer.valueOf(message.getSections()[3]);
List<Util.Triple<Integer, Integer, Long>> markIndicesRanksAndTimesSinceStartInMilliseconds = new ArrayList<Util.Triple<Integer,Integer,Long>>();
for (int i = 0; i < count; i++) {
@@ -296,7 +298,7 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement
}
for (SailMasterListener listener : getListeners()) {
try {
listener.receivedTimingData(raceID, boatID, markIndicesRanksAndTimesSinceStartInMilliseconds);
listener.receivedTimingData(raceID, competitorIdAsString, markIndicesRanksAndTimesSinceStartInMilliseconds);
} catch (Exception e) {
logger.info("Exception occurred trying to notify listener "+listener+" about "+message+": "+e.getMessage());
logger.throwing(SailMasterConnectorImpl.class.getName(), "notifyListenersTMD", e);
@@ -359,12 +361,12 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement
String raceID = sections[1];
final RaceStatus raceStatus;
final RacingStatus racingStatus;
if (sections[2].contains(",")) {
final String[] raceStatusIntAndRacingStatusInt = sections[2].split(",");
final String[] raceStatusIntAndRacingStatusInt = sections[2].split(",");
if (raceStatusIntAndRacingStatusInt.length > 1) {
raceStatus = RaceStatus.values()[Integer.valueOf(raceStatusIntAndRacingStatusInt[0])];
racingStatus = RacingStatus.values()[Integer.valueOf(raceStatusIntAndRacingStatusInt[1])];
} else {
raceStatus = RaceStatus.values()[Integer.valueOf(sections[2])];
raceStatus = RaceStatus.values()[Integer.valueOf(raceStatusIntAndRacingStatusInt[0])];
racingStatus = null;
}
TimePoint timePoint = new MillisecondsTimePoint(parseTimeAndDateISO(sections[3], raceID));
@@ -386,45 +388,47 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement
final String[] fixSections = sections[9+i].split(";");
final boolean postVersion1_0 = sections[9+i].split(";", -1).length >= 14;
if (fixSections.length > 2) {
final String boatID = fixSections[fixDetailIndex++];
final TrackerType trackerType = TrackerType.values()[Integer.valueOf(fixSections[fixDetailIndex++])];
final Long ageOfDataInMilliseconds = 1000l * Long.valueOf(fixSections[fixDetailIndex++]);
final Position position = new DegreePosition(Double.valueOf(fixSections[fixDetailIndex++]),
Double.valueOf(fixSections[fixDetailIndex++]));
final Double speedOverGroundInKnots = Double.valueOf(fixSections[fixDetailIndex++]);
final int alsIndex = postVersion1_0 ? fixDetailIndex+1 : fixDetailIndex;
final int vmgIndex = postVersion1_0 ? fixDetailIndex : fixDetailIndex+1;
final Speed averageSpeedOverGround = fixSections[alsIndex].trim().length() == 0 ? null
: new KnotSpeedImpl(Double.valueOf(fixSections[alsIndex]));
final Speed velocityMadeGood = fixSections[vmgIndex].trim().length() == 0 ? null : new KnotSpeedImpl(
Double.valueOf(fixSections[vmgIndex]));
fixDetailIndex += 2;
final AbstractBearing cog = new DegreeBearingImpl(
Double.valueOf(fixSections[fixDetailIndex++]));
final SpeedWithBearing speed = new KnotSpeedWithBearingImpl(speedOverGroundInKnots, cog);
final Integer nextMarkIndex = fixSections.length <= fixDetailIndex
|| fixSections[fixDetailIndex].trim().length() == 0 ? null : Integer
.valueOf(fixSections[fixDetailIndex]);
fixDetailIndex++;
final Integer rank = fixSections.length <= fixDetailIndex || fixSections[fixDetailIndex].trim().length() == 0 ? null
: Integer.valueOf(fixSections[fixDetailIndex]);
fixDetailIndex++;
final Distance distanceToLeader = fixSections.length <= fixDetailIndex
|| fixSections[fixDetailIndex].trim().length() == 0 ? null : new MeterDistance(
Double.valueOf(fixSections[fixDetailIndex]));
fixDetailIndex++;
final Distance distanceToNextMark = fixSections.length <= fixDetailIndex
|| fixSections[fixDetailIndex].trim().length() == 0 ? null : new MeterDistance(
Double.valueOf(fixSections[fixDetailIndex]));
fixDetailIndex++;
final String boatIRM; // the "disqualification" or "MaxPointReason"
if (postVersion1_0 && fixSections.length > fixDetailIndex) {
boatIRM = fixSections[fixDetailIndex++];
} else {
boatIRM = null;
final String trackedObjectIdAsString = fixSections[fixDetailIndex++].trim();
if (trackedObjectIdAsString != null && !trackedObjectIdAsString.isEmpty()) {
final TrackerType trackerType = TrackerType.values()[Integer.valueOf(fixSections[fixDetailIndex++])];
final Long ageOfDataInMilliseconds = 1000l * Long.valueOf(fixSections[fixDetailIndex++]);
final Position position = new DegreePosition(Double.valueOf(fixSections[fixDetailIndex++]),
Double.valueOf(fixSections[fixDetailIndex++]));
final Double speedOverGroundInKnots = Double.valueOf(fixSections[fixDetailIndex++]);
final int alsIndex = postVersion1_0 ? fixDetailIndex+1 : fixDetailIndex;
final int vmgIndex = postVersion1_0 ? fixDetailIndex : fixDetailIndex+1;
final Speed averageSpeedOverGround = fixSections[alsIndex].trim().length() == 0 ? null
: new KnotSpeedImpl(Double.valueOf(fixSections[alsIndex]));
final Speed velocityMadeGood = fixSections[vmgIndex].trim().length() == 0 ? null : new KnotSpeedImpl(
Double.valueOf(fixSections[vmgIndex]));
fixDetailIndex += 2;
final AbstractBearing cog = new DegreeBearingImpl(
Double.valueOf(fixSections[fixDetailIndex++]));
final SpeedWithBearing speed = new KnotSpeedWithBearingImpl(speedOverGroundInKnots, cog);
final Integer nextMarkIndex = fixSections.length <= fixDetailIndex
|| fixSections[fixDetailIndex].trim().length() == 0 ? null : Integer
.valueOf(fixSections[fixDetailIndex]);
fixDetailIndex++;
final Integer rank = fixSections.length <= fixDetailIndex || fixSections[fixDetailIndex].trim().length() == 0 ? null
: Integer.valueOf(fixSections[fixDetailIndex]);
fixDetailIndex++;
final Distance distanceToLeader = fixSections.length <= fixDetailIndex
|| fixSections[fixDetailIndex].trim().length() == 0 ? null : new MeterDistance(
Double.valueOf(fixSections[fixDetailIndex]));
fixDetailIndex++;
final Distance distanceToNextMark = fixSections.length <= fixDetailIndex
|| fixSections[fixDetailIndex].trim().length() == 0 ? null : new MeterDistance(
Double.valueOf(fixSections[fixDetailIndex]));
fixDetailIndex++;
final String boatIRM; // the "disqualification" or "MaxPointReason"
if (postVersion1_0 && fixSections.length > fixDetailIndex) {
boatIRM = fixSections[fixDetailIndex++];
} else {
boatIRM = null;
}
fixes.add(new FixImpl(UUIDHelper.tryUuidConversion(trackedObjectIdAsString), trackerType, ageOfDataInMilliseconds, position, speed, nextMarkIndex,
rank, averageSpeedOverGround, velocityMadeGood, distanceToLeader, distanceToNextMark, boatIRM));
}
fixes.add(new FixImpl(boatID, trackerType, ageOfDataInMilliseconds, position, speed, nextMarkIndex,
rank, averageSpeedOverGround, velocityMadeGood, distanceToLeader, distanceToNextMark, boatIRM));
}
}
Set<SailMasterListener> allListeners = getListeners();
@@ -625,7 +629,7 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement
devicesNamesStartIndex = 2;
}
marks.add(new MarkImpl(markDetails[1], Integer.valueOf(markDetails[0]),
Arrays.asList(markDetails).subList(devicesNamesStartIndex, markDetails.length),
Arrays.asList(markDetails).subList(devicesNamesStartIndex, markDetails.length).stream().map(idAsString->UUIDHelper.tryUuidConversion(idAsString)).collect(Collectors.toList()),
markType));
}
return new CourseImpl(courseConfigurationMessage.getSections()[1], marks);
@@ -99,7 +99,6 @@ public class SwissTimingAdapterImpl implements SwissTimingAdapter {
teams.put(t.getTeamID(), t);
}
}
for (Object o : regattaResults.getPersonOrBoatOrTeam()) {
if (o instanceof Event) {
Event event = (Event) o;
@@ -1,6 +1,7 @@
package com.sap.sailing.domain.swisstimingadapter.impl;
import java.io.IOException;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
import java.text.ParseException;
@@ -12,6 +13,7 @@ import java.util.Map;
import java.util.NavigableSet;
import java.util.Optional;
import java.util.TreeMap;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -42,7 +44,6 @@ import com.sap.sailing.domain.swisstimingadapter.DomainFactory;
import com.sap.sailing.domain.swisstimingadapter.Fix;
import com.sap.sailing.domain.swisstimingadapter.Race;
import com.sap.sailing.domain.swisstimingadapter.RaceStatus;
import com.sap.sailing.domain.swisstimingadapter.RaceType;
import com.sap.sailing.domain.swisstimingadapter.RacingStatus;
import com.sap.sailing.domain.swisstimingadapter.SailMasterConnector;
import com.sap.sailing.domain.swisstimingadapter.SailMasterListener;
@@ -276,13 +277,13 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl
case JURY:
case TIMINGSCORING:
case UNIDENTIFIED:
String trackerID = fix.getBoatID();
Mark mark = domainFactory.getOrCreateMark(trackerID);
Serializable trackerID = fix.getTrackedObjectId();
Mark mark = domainFactory.getOrCreateMark(trackerID, /* description */ null);
trackedRace.recordFix(mark, gpsFix);
break;
case COMPETITOR:
String boatID = fix.getBoatID();
Competitor competitor = getCompetitorByBoatIDAndRaceIDOrBoatClass(boatID, raceID, boatClass);
Serializable competitorId = fix.getTrackedObjectId();
Competitor competitor = getDomainFactory().getBaseDomainFactory().getExistingCompetitorById(competitorId);
if (competitor == null) {
// TODO: read startlist again from Manage2Sail
// use competitorStore.isCompetitorToUpdateDuringGetOrCreate(result)
@@ -291,7 +292,7 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl
DynamicGPSFixTrack<Competitor, GPSFixMoving> competitorTrack = trackedRace.getTrack(competitor);
competitorTrack.addGPSFix(gpsFix);
} else {
logger.info("Unknown competitor " + boatID + " found for race with id " + raceID);
logger.info("Unknown competitor " + competitorId + " found for race with id " + raceID);
}
break;
default:
@@ -310,41 +311,15 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl
}
private Competitor getCompetitorByBoatIDAndRaceType(String boatID, RaceType raceType) {
return domainFactory.getBaseDomainFactory().getExistingCompetitorById(domainFactory.getCompetitorID(boatID, raceType));
}
private Competitor getCompetitorByBoatIDAndBoatClass(String boatID, BoatClass boatClass) {
return domainFactory.getBaseDomainFactory().getExistingCompetitorById(domainFactory.getCompetitorID(boatID, boatClass));
}
@Override
public Competitor getCompetitorByBoatIDAndRaceIDOrBoatClass(String boatID, String raceID, BoatClass boatClass) {
Competitor result = null;
// first look into the temp cache
result = competitorsByBoatId.get(boatID);
if (result == null) {
if (boatClass != null) {
result = getCompetitorByBoatIDAndBoatClass(boatID, boatClass);
} else {
RaceType raceType = domainFactory.getRaceTypeFromRaceID(raceID);
if (raceType != null) {
result = getCompetitorByBoatIDAndRaceType(boatID, raceType);
}
}
}
return result;
}
@Override
public void receivedTimingData(String raceID, String boatID,
public void receivedTimingData(String raceID, String competitorIdAsString,
List<com.sap.sse.common.Util.Triple<Integer, Integer, Long>> markIndicesRanksAndTimesSinceStartInMilliseconds) {
assert this.raceID.equals(raceID);
if (!useInternalMarkPassingAlgorithm) {
if (isTrackedRaceStillReachable()) {
Competitor competitor = getCompetitorByBoatIDAndRaceIDOrBoatClass(boatID, raceID, boatClass);
final Competitor competitor = domainFactory.getBaseDomainFactory().getExistingCompetitorById(UUID.fromString(competitorIdAsString));
if (competitor == null) {
logger.info("Received timing data for boat ID " + boatID + " in race " + raceID
logger.info("Received timing data for boat ID " + competitorIdAsString + " in race " + raceID
+ " but couldn't find a competitor with that boat ID in this race. Ignoring.");
} else {
// the list of mark indices and time stamps is partial and usually only shows the last mark passing;
@@ -378,8 +353,7 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl
final TimePoint startTime = trackedRace.getStartOfRace();
MillisecondsTimePoint timePoint = new MillisecondsTimePoint(startTime.asMillis()
+ markIndexRankAndTimeSinceStartInMilliseconds.getC());
MarkPassing markPassing = domainFactory.createMarkPassing(timePoint, waypoint,
getCompetitorByBoatIDAndRaceIDOrBoatClass(boatID, raceID, boatClass));
MarkPassing markPassing = domainFactory.createMarkPassing(timePoint, waypoint, competitor);
markPassingsByMarkIndex.put(markIndexRankAndTimeSinceStartInMilliseconds.getA(),
markPassing);
} else {
@@ -387,7 +361,7 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl
+ trackedRace.getRace().getName()
+ " before having received a race start time."
+ " Queueing message for re-application when a start time has been received.");
tmdMessageQueue.enqueue(raceID, boatID,
tmdMessageQueue.enqueue(raceID, competitorIdAsString,
markIndicesRanksAndTimesSinceStartInMilliseconds);
}
}
@@ -474,7 +448,7 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl
// temp
CompetitorAndBoatStore competitorStore = domainFactory.getBaseDomainFactory().getCompetitorAndBoatStore();
for (com.sap.sailing.domain.swisstimingadapter.Competitor c : startList.getCompetitors()) {
Competitor existingCompetitor = competitorStore.getExistingCompetitorByIdAsString(c.getID());
Competitor existingCompetitor = competitorStore.getExistingCompetitorByIdAsString(c.getIdAsString());
if (existingCompetitor != null) {
competitorsByBoatId.put(c.getBoatID(), existingCompetitor);
}
@@ -8,6 +8,7 @@ import java.util.Map;
import java.util.NavigableSet;
import java.util.Set;
import java.util.TreeMap;
import java.util.UUID;
import java.util.logging.Logger;
import com.sap.sailing.domain.base.Competitor;
@@ -30,14 +31,14 @@ public class TMDMessageQueue {
private static class TMDMessageContents {
private final String raceID;
private final String boatID;
private final String competitorIdAsString;
private final List<Util.Triple<Integer, Integer, Long>> markIndicesRanksAndTimesSinceStartInMilliseconds;
public TMDMessageContents(String raceID, String boatID,
public TMDMessageContents(String raceID, String competitorIdAsString,
List<Util.Triple<Integer, Integer, Long>> markIndicesRanksAndTimesSinceStartInMilliseconds) {
super();
this.raceID = raceID;
this.boatID = boatID;
this.competitorIdAsString = competitorIdAsString;
this.markIndicesRanksAndTimesSinceStartInMilliseconds = markIndicesRanksAndTimesSinceStartInMilliseconds;
}
@@ -45,8 +46,8 @@ public class TMDMessageQueue {
return raceID;
}
public String getBoatID() {
return boatID;
public String getCompetitorIdAsString() {
return competitorIdAsString;
}
public List<Util.Triple<Integer, Integer, Long>> getMarkIndicesRanksAndTimesSinceStartInMilliseconds() {
@@ -55,7 +56,7 @@ public class TMDMessageQueue {
@Override
public String toString() {
StringBuilder result = new StringBuilder("TMD|"+getRaceID()+"|"+getBoatID()+"|");
StringBuilder result = new StringBuilder("TMD|"+getRaceID()+"|"+getCompetitorIdAsString()+"|");
result.append(getMarkIndicesRanksAndTimesSinceStartInMilliseconds().size());
result.append('|');
for (Util.Triple<Integer, Integer, Long> markIndexRankAndTimeSinceStartInMilliseconds : getMarkIndicesRanksAndTimesSinceStartInMilliseconds()) {
@@ -82,8 +83,8 @@ public class TMDMessageQueue {
queuedMessages = new HashSet<>();
}
public synchronized void enqueue(String raceID, String boatID, List<Util.Triple<Integer, Integer, Long>> markIndicesRanksAndTimesSinceStartInMilliseconds) {
final TMDMessageContents message = new TMDMessageContents(raceID, boatID, markIndicesRanksAndTimesSinceStartInMilliseconds);
public synchronized void enqueue(String raceID, String competitorIdAsString, List<Util.Triple<Integer, Integer, Long>> markIndicesRanksAndTimesSinceStartInMilliseconds) {
final TMDMessageContents message = new TMDMessageContents(raceID, competitorIdAsString, markIndicesRanksAndTimesSinceStartInMilliseconds);
queuedMessages.add(message);
logger.info("Queued TMD message "+message+" for replay when start time has been received");
}
@@ -101,10 +102,9 @@ public class TMDMessageQueue {
// otherwise, this could lead to the "guessed time" to
while (i.hasNext()) {
TMDMessageContents messageContents = i.next();
Competitor competitor = raceTracker.getCompetitorByBoatIDAndRaceIDOrBoatClass(messageContents.getBoatID(),
messageContents.getRaceID(), raceTracker.getBoatClass());
Competitor competitor = raceTracker.getDomainFactory().getBaseDomainFactory().getExistingCompetitorById(UUID.fromString(messageContents.getCompetitorIdAsString()));
if (competitor == null) {
logger.info("Received timing data for boat ID " + messageContents.getBoatID() + " in race " + messageContents.getRaceID()
logger.info("Received timing data for boat ID " + messageContents.getCompetitorIdAsString() + " in race " + messageContents.getRaceID()
+ " but couldn't find a competitor with that boat ID in this race. Ignoring.");
} else {
NavigableSet<MarkPassing> oldMarkPassings = trackedRace.getMarkPassings(competitor);
@@ -156,7 +156,7 @@ public class TMDMessageQueue {
while (i.hasNext()) {
TMDMessageContents messageContents = i.next();
logger.info("Re-Playing TMD message "+messageContents+" with new race start time "+trackedRace.getStartOfRace());
raceTracker.receivedTimingData(messageContents.getRaceID(), messageContents.getBoatID(),
raceTracker.receivedTimingData(messageContents.getRaceID(), messageContents.getCompetitorIdAsString(),
messageContents.getMarkIndicesRanksAndTimesSinceStartInMilliseconds());
i.remove();
}
@@ -1,5 +1,6 @@
package com.sap.sailing.domain.swisstimingreplayadapter.impl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
@@ -308,7 +309,7 @@ public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter i
competitorByHashValue.put(hashValue, competitorAndBoat.getA());
} else {
// consider it a mark
Mark mark = domainFactory.getOrCreateMark(sailNumberOrTrackerID.trim());
Mark mark = domainFactory.getOrCreateMark(sailNumberOrTrackerID.trim(), name);
Map<String, Mark> marksOfCurrentRace = marksPerRaceIDPerMarkID.get(currentRaceID);
if (marksOfCurrentRace == null) {
marksOfCurrentRace = new HashMap<>();
@@ -323,12 +324,12 @@ public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter i
@Override
public void mark(MarkType markType, String name, byte index, String id1, String id2, short windSpeedInKnots,
short trueWindDirectionInDegrees) {
final List<String> markNames = new ArrayList<>();
markNames.add(id1.trim());
final List<Serializable> markNamesAsIds = new ArrayList<>();
markNamesAsIds.add(id1.trim());
if (id2 != null && !id2.trim().isEmpty()) {
markNames.add(id2.trim());
markNamesAsIds.add(id2.trim());
}
final ControlPoint controlPoint = domainFactory.getOrCreateControlPoint(markNames, getMarkType(markType));
final ControlPoint controlPoint = domainFactory.getOrCreateControlPoint(name, markNamesAsIds, getMarkType(markType));
if (index == 0) {
currentCourseDefinition = new ArrayList<>();
}
@@ -9,10 +9,10 @@ import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.common.MarkType;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.Helpers;
import com.sap.sailing.server.gateway.serialization.coursedata.impl.MarkJsonSerializer;
import com.sap.sse.common.Color;
import com.sap.sse.common.impl.AbstractColor;
import com.sap.sse.util.impl.UUIDHelper;
/**
* Deserializer for marks.
@@ -27,7 +27,7 @@ public class MarkDeserializer implements JsonDeserializer<Mark> {
@Override
public Mark deserialize(JSONObject object) throws JsonDeserializationException {
Serializable id = Helpers.tryUuidConversion((Serializable) object.get(MarkJsonSerializer.FIELD_ID));
Serializable id = UUIDHelper.tryUuidConversion((Serializable) object.get(MarkJsonSerializer.FIELD_ID));
String colorAsString = (String) object.get(MarkJsonSerializer.FIELD_COLOR);
Color color = colorAsString == null ? null : AbstractColor.getCssColor(colorAsString);
String pattern = (String) object.get(MarkJsonSerializer.FIELD_PATTERN);
@@ -16,6 +16,7 @@ import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
import com.sap.sailing.server.gateway.serialization.impl.BoatJsonSerializer;
import com.sap.sse.common.Color;
import com.sap.sse.common.impl.RGBColor;
import com.sap.sse.util.impl.UUIDHelper;
public class BoatJsonDeserializer implements JsonDeserializer<DynamicBoat> {
private static final Logger logger = Logger.getLogger(BoatJsonDeserializer.class.getName());
@@ -63,7 +64,7 @@ public class BoatJsonDeserializer implements JsonDeserializer<DynamicBoat> {
Constructor<?> constructorFromString = idClass.getConstructor(String.class);
boatId = (Serializable) constructorFromString.newInstance(boatIdFromJson.toString());
} else if (UUID.class.isAssignableFrom(idClass)) {
boatId = Helpers.tryUuidConversion(boatIdFromJson);
boatId = UUIDHelper.tryUuidConversion(boatIdFromJson);
} else {
boatId = boatIdFromJson;
}
@@ -21,6 +21,7 @@ import com.sap.sailing.server.gateway.serialization.impl.CompetitorJsonSerialize
import com.sap.sse.common.Color;
import com.sap.sse.common.impl.MillisecondsDurationImpl;
import com.sap.sse.common.impl.RGBColor;
import com.sap.sse.util.impl.UUIDHelper;
public class CompetitorJsonDeserializer implements JsonDeserializer<DynamicCompetitor> {
private final CompetitorFactory competitorWithBoatFactory;
@@ -52,7 +53,7 @@ public class CompetitorJsonDeserializer implements JsonDeserializer<DynamicCompe
Constructor<?> constructorFromString = idClass.getConstructor(String.class);
competitorId = (Serializable) constructorFromString.newInstance(competitorId.toString());
} else if (UUID.class.isAssignableFrom(idClass)) {
competitorId = Helpers.tryUuidConversion(competitorId);
competitorId = UUIDHelper.tryUuidConversion(competitorId);
}
String name = (String) object.get(CompetitorJsonConstants.FIELD_NAME);
String shortName = (String) object.get(CompetitorJsonConstants.FIELD_SHORT_NAME);
@@ -14,6 +14,7 @@ import com.sap.sailing.domain.base.impl.DynamicBoat;
import com.sap.sailing.domain.base.impl.DynamicTeam;
import com.sap.sailing.domain.common.tracking.impl.CompetitorJsonConstants;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
import com.sap.sse.util.impl.UUIDHelper;
public class CompetitorWithBoatRefJsonDeserializer extends CompetitorJsonDeserializer {
private final BoatFactory boatFactory;
@@ -47,7 +48,7 @@ public class CompetitorWithBoatRefJsonDeserializer extends CompetitorJsonDeseria
Constructor<?> constructorFromString = boatIdClass.getConstructor(String.class);
boatId = (Serializable) constructorFromString.newInstance(boatId.toString());
} else if (UUID.class.isAssignableFrom(boatIdClass)) {
boatId = Helpers.tryUuidConversion(boatId);
boatId = UUIDHelper.tryUuidConversion(boatId);
}
}
final DynamicBoat existingBoat = (DynamicBoat) (boatId != null ? boatFactory.getExistingBoatById(boatId) : null);
@@ -10,6 +10,7 @@ import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
import com.sap.sailing.server.gateway.serialization.impl.CourseAreaJsonSerializer;
import com.sap.sse.util.impl.UUIDHelper;
public class CourseAreaJsonDeserializer implements JsonDeserializer<CourseArea> {
@@ -24,7 +25,7 @@ public class CourseAreaJsonDeserializer implements JsonDeserializer<CourseArea>
String name = (String) object.get(CourseAreaJsonSerializer.FIELD_NAME);
Serializable id = (Serializable) object.get(CourseAreaJsonSerializer.FIELD_ID);
return factory.getOrCreateCourseArea((UUID) Helpers.tryUuidConversion(id), name);
return factory.getOrCreateCourseArea((UUID) UUIDHelper.tryUuidConversion(id), name);
}
}
@@ -1,9 +1,7 @@
package com.sap.sailing.server.gateway.deserialization.impl;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.UUID;
import java.util.logging.Logger;
import org.json.simple.JSONArray;
@@ -12,7 +10,6 @@ import org.json.simple.JSONObject;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
public class Helpers {
private final static Logger logger = Logger.getLogger(Helpers.class.getName());
public static JSONArray toJSONArraySafe(Object object) throws JsonDeserializationException {
@@ -62,19 +59,4 @@ public class Helpers {
}
return result;
}
/**
* If the {@link Object#toString() string representation} of {@code serializableId} {@link UUID#fromString(String) parses}
* as a {@link UUID}, the resulting {@link UUID} is returned. Otherwise, the {@code serializableId} parameter's value
* is returned unchanged.
*/
public static Serializable tryUuidConversion(Serializable serializableId) {
try {
return UUID.fromString(serializableId.toString());
} catch (IllegalArgumentException iae) {
logger.warning("The serializable " + serializableId.toString() + " could not be converted to a UUID");
}
return serializableId;
}
}
@@ -16,6 +16,7 @@ import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
import com.sap.sailing.server.gateway.serialization.impl.BoatJsonSerializer;
import com.sap.sse.common.Color;
import com.sap.sse.common.impl.RGBColor;
import com.sap.sse.util.impl.UUIDHelper;
public class LegacyBoatJsonDeserializer implements JsonDeserializer<DynamicBoat> {
private final BoatClassJsonDeserializer boatClassDeserializer;
@@ -41,7 +42,7 @@ public class LegacyBoatJsonDeserializer implements JsonDeserializer<DynamicBoat>
Constructor<?> constructorFromString = idClass.getConstructor(String.class);
boatId = (Serializable) constructorFromString.newInstance(boatId.toString());
} else if (UUID.class.isAssignableFrom(idClass)) {
boatId = Helpers.tryUuidConversion(boatId);
boatId = UUIDHelper.tryUuidConversion(boatId);
}
}
String name = (String) object.get(BoatJsonSerializer.FIELD_NAME);
@@ -21,6 +21,7 @@ import com.sap.sailing.server.gateway.serialization.impl.CompetitorJsonSerialize
import com.sap.sse.common.Color;
import com.sap.sse.common.impl.MillisecondsDurationImpl;
import com.sap.sse.common.impl.RGBColor;
import com.sap.sse.util.impl.UUIDHelper;
public class LegacyCompetitorWithContainedBoatJsonDeserializer implements JsonDeserializer<CompetitorWithBoat> {
protected final CompetitorFactory competitorWithBoatFactory;
@@ -52,7 +53,7 @@ public class LegacyCompetitorWithContainedBoatJsonDeserializer implements JsonDe
Constructor<?> constructorFromString = idClass.getConstructor(String.class);
competitorId = (Serializable) constructorFromString.newInstance(competitorId.toString());
} else if (UUID.class.isAssignableFrom(idClass)) {
competitorId = Helpers.tryUuidConversion(competitorId);
competitorId = UUIDHelper.tryUuidConversion(competitorId);
}
String name = (String) object.get(CompetitorJsonConstants.FIELD_NAME);
String shortName = (String) object.get(CompetitorJsonConstants.FIELD_SHORT_NAME);
@@ -18,6 +18,7 @@ import com.sap.sailing.server.gateway.deserialization.impl.Helpers;
import com.sap.sailing.server.gateway.serialization.racelog.impl.BaseRaceLogEventSerializer;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.util.impl.UUIDHelper;
public abstract class BaseRaceLogEventDeserializer implements JsonDeserializer<RaceLogEvent> {
@@ -55,7 +56,7 @@ public abstract class BaseRaceLogEventDeserializer implements JsonDeserializer<R
}
return deserialize(
object,
Helpers.tryUuidConversion(id),
UUIDHelper.tryUuidConversion(id),
new MillisecondsTimePoint(createdAt.longValue()),
author,
timeStamp == null ? null : new MillisecondsTimePoint(timeStamp.longValue()),
@@ -22,6 +22,7 @@ import com.sap.sailing.server.gateway.deserialization.impl.Helpers;
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogFinishPositioningConfirmedEventSerializer;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.util.impl.UUIDHelper;
public abstract class RaceLogFinishPositioningEventDeserializer extends BaseRaceLogEventDeserializer {
@@ -47,7 +48,7 @@ public abstract class RaceLogFinishPositioningEventDeserializer extends BaseRace
for (Object object : jsonPositionedCompetitors) {
JSONObject jsonPositionedCompetitor = Helpers.toJSONObjectSafe(object);
Serializable competitorId = (Serializable) jsonPositionedCompetitor.get(RaceLogFinishPositioningConfirmedEventSerializer.FIELD_COMPETITOR_ID);
competitorId = Helpers.tryUuidConversion(competitorId);
competitorId = UUIDHelper.tryUuidConversion(competitorId);
final String competitorDisplayName = (String) jsonPositionedCompetitor.get(RaceLogFinishPositioningConfirmedEventSerializer.FIELD_COMPETITOR_NAME);
final String maxPointsReasonName = (String) jsonPositionedCompetitor.get(RaceLogFinishPositioningConfirmedEventSerializer.FIELD_SCORE_CORRECTIONS_MAX_POINTS_REASON);
final MaxPointsReason maxPointsReason = MaxPointsReason.valueOf(maxPointsReasonName);
@@ -12,9 +12,9 @@ import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.impl.DynamicCompetitor;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.Helpers;
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogRevokeEventSerializer;
import com.sap.sse.common.TimePoint;
import com.sap.sse.util.impl.UUIDHelper;
public class RaceLogRevokeEventDeserializer extends BaseRaceLogEventDeserializer {
public RaceLogRevokeEventDeserializer(JsonDeserializer<DynamicCompetitor> competitorDeserializer) {
@@ -24,7 +24,7 @@ public class RaceLogRevokeEventDeserializer extends BaseRaceLogEventDeserializer
@Override
protected RaceLogEvent deserialize(JSONObject object, Serializable id, TimePoint createdAt, AbstractLogEventAuthor author, TimePoint timePoint, int passId, List<Competitor> competitors)
throws JsonDeserializationException {
Serializable revokedEventId = Helpers.tryUuidConversion(
Serializable revokedEventId = UUIDHelper.tryUuidConversion(
(Serializable) object.get(RaceLogRevokeEventSerializer.FIELD_REVOKED_EVENT_ID));
String revokedEventType = (String) object.get(RaceLogRevokeEventSerializer.FIELD_REVOKED_EVENT_TYPE);
String revokedEventShortInfo = (String) object.get(RaceLogRevokeEventSerializer.FIELD_REVOKED_EVENT_SHORT_INFO);
@@ -16,6 +16,7 @@ import com.sap.sailing.server.gateway.deserialization.TypeBasedJsonDeserializer;
import com.sap.sailing.server.gateway.serialization.racelog.tracking.GPSFixJsonHandler;
import com.sap.sse.common.TypeBasedServiceFinder;
import com.sap.sse.common.Util;
import com.sap.sse.util.impl.UUIDHelper;
public class DeviceAndSessionIdentifierWithGPSFixesDeserializer
implements JsonDeserializer<Util.Triple<DeviceIdentifier, Serializable, List<GPSFix>>> {
@@ -41,7 +42,7 @@ implements JsonDeserializer<Util.Triple<DeviceIdentifier, Serializable, List<GPS
Object sessionObject = object.get(FIELD_SESSION_UUID);
Serializable sessionId = sessionObject == null ?
null : Helpers.tryUuidConversion(((Serializable) sessionObject));
null : UUIDHelper.tryUuidConversion(((Serializable) sessionObject));
JSONArray fixesJson = Helpers.getNestedArraySafe(object, FIELD_FIXES);
List<GPSFix> fixes = new ArrayList<GPSFix>();
@@ -124,6 +124,7 @@ import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.util.impl.UUIDHelper;
@Path("/v1/leaderboards")
public class LeaderboardsResource extends AbstractLeaderboardsResource {
@@ -322,7 +323,7 @@ public class LeaderboardsResource extends AbstractLeaderboardsResource {
from, /* to */ null);
} else {
// map to a mark
final Mark mappedToMark = domainFactory.getExistingMarkById(Helpers.tryUuidConversion(markId));
final Mark mappedToMark = domainFactory.getExistingMarkById(UUIDHelper.tryUuidConversion(markId));
mappedTo = mappedToMark;
if (mappedToMark == null) {
logger.warning("No mark found for id " + markId);
@@ -396,7 +397,7 @@ public class LeaderboardsResource extends AbstractLeaderboardsResource {
} else {
// map to mark
DomainFactory domainFactory = getService().getDomainObjectFactory().getBaseDomainFactory();
final Mark mappedToMark = domainFactory.getExistingMarkById(Helpers.tryUuidConversion(markId));
final Mark mappedToMark = domainFactory.getExistingMarkById(UUIDHelper.tryUuidConversion(markId));
mappedTo = mappedToMark;
if (mappedToMark == null) {
logger.warning("No mark found for id " + markId);
@@ -22,7 +22,7 @@
<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.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -console -clean"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Declipse.ignoreApp=true -Dosgi.noShutdown=true -Dfile.encoding=cp1252 -Dexpedition.udp.port=5010 -Xmx6000m -XX:+UseG1GC -Djetty.home=${project_loc:com.sap.sailing.server}/../target/configuration/jetty -Djava.util.logging.config.file=${project_loc:com.sap.sailing.server}/../target/configuration/logging_debug.properties -Dkiwo.results=${project_loc:com.sap.sailing.kiworesultimport.test}/resources -Dpersistentcompetitors.clear=false -XX:+UseMembar -Dpolardata.source.url=https://www.sapsailing.com -Drestore.tracked.races=true"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Declipse.ignoreApp=true -Dosgi.noShutdown=true -Dfile.encoding=cp1252 -Dexpedition.udp.port=5010 -Xmx6000m -XX:+UseG1GC -Djetty.home=${project_loc:com.sap.sailing.server}/../target/configuration/jetty -Djava.util.logging.config.file=${project_loc:com.sap.sailing.server}/../target/configuration/logging_debug.properties -Dkiwo.results=${project_loc:com.sap.sailing.kiworesultimport.test}/resources -Dpersistentcompetitors.clear=false -XX:+UseMembar -Dpolardata.source.url=https://www.sapsailing.com -Drestore.tracked.races=false"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>
<stringAttribute key="pde.version" value="3.3"/>
<stringAttribute key="profilingTraceType-ALLOCATION_TRACE" value="KEY_APPLICATION_FILTER%CTX_KEY%*%CTX_ENTRY%INCREASE_COUNT%CTX_KEY%8192%CTX_ENTRY%KEY_MIN_SIZE%CTX_KEY%32%CTX_ENTRY%KEY_MAX_SIZE%CTX_KEY%65536%CTX_ENTRY%KEY_INC_LINE_NRS%CTX_KEY%true%CTX_ENTRY%KEY_SESSION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ENABLEMENT%CTX_KEY%false%CTX_ENTRY%CLASS_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_USER_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_REQUEST_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_TENANT_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ADAPTIVE%CTX_KEY%false%CTX_ENTRY%"/>
@@ -493,6 +493,15 @@ public class Util {
return joinStrings(separator, Arrays.asList(strings));
}
public static String join(String separator, Object... objects) {
final String[] strings = new String[objects.length];
int i=0;
for (Object o : objects) {
strings[i++] = o.toString();
}
return joinStrings(separator, Arrays.asList(strings));
}
public static String joinStrings(String separator, Iterable<String> strings) {
StringBuilder result = new StringBuilder();
boolean first = true;
@@ -0,0 +1,23 @@
package com.sap.sse.util.impl;
import java.io.Serializable;
import java.util.UUID;
import java.util.logging.Logger;
public class UUIDHelper {
private static final Logger logger = Logger.getLogger(UUIDHelper.class.getName());
/**
* If the {@link Object#toString() string representation} of {@code serializableId} {@link UUID#fromString(String) parses}
* as a {@link UUID}, the resulting {@link UUID} is returned. Otherwise, the {@code serializableId} parameter's value
* is returned unchanged.
*/
public static Serializable tryUuidConversion(Serializable serializableId) {
try {
return UUID.fromString(serializableId.toString());
} catch (IllegalArgumentException iae) {
logger.fine("The serializable " + serializableId.toString() + " could not be converted to a UUID");
}
return serializableId;
}
}
@@ -29,7 +29,7 @@ import com.sap.sailing.android.shared.data.CheckinUrlInfo;
import com.sap.sailing.android.shared.data.LeaderboardInfo;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
import com.sap.sailing.server.gateway.deserialization.impl.Helpers;
import com.sap.sse.util.impl.UUIDHelper;
public class DatabaseHelper {
@@ -84,7 +84,7 @@ public class DatabaseHelper {
while (!mc.isAfterLast()) {
final String markName = mc.getString((mc.getColumnIndex(Mark.MARK_NAME)));
final String markIdAsString = mc.getString(mc.getColumnIndex(Mark.MARK_ID));
final Serializable markId = Helpers.tryUuidConversion(markIdAsString);
final Serializable markId = UUIDHelper.tryUuidConversion(markIdAsString);
MarkInfo markInfo = new MarkInfo(markId, markName,
mc.getString((mc.getColumnIndex(Mark.MARK_CLASS_NAME))),
checkinDigest);