added RaceLog events for RaceLog-based tracking

This commit is contained in:
Fredrik Teschke committed 2014-02-10 09:08:01 +01:00
1 parent 1d3ab7704f
commit 971a0405a2
55 files changed
+2062 -223

No files matched your search

@@ -81,7 +81,7 @@ import com.sap.sailing.domain.common.impl.WindSourceWithAdditionalID;
import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
import com.sap.sailing.domain.devices.NoCorrespondingServiceRegisteredException;
import com.sap.sailing.domain.devices.DeviceIdentifier;
import com.sap.sailing.domain.devices.TypeBasedServiceFinder;
import com.sap.sailing.domain.devices.TypeBasedServiceFinderFactory;
import com.sap.sailing.domain.leaderboard.DelayedLeaderboardCorrections;
@@ -124,6 +124,11 @@ import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
import com.sap.sailing.domain.racelog.impl.CompetitorResultsImpl;
import com.sap.sailing.domain.racelog.impl.RaceLogEventAuthorImpl;
import com.sap.sailing.domain.racelog.impl.RaceLogImpl;
import com.sap.sailing.domain.racelog.tracking.CreateRaceEvent;
import com.sap.sailing.domain.racelog.tracking.DenoteForTrackingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceCompetitorMappingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceMarkMappingEvent;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
import com.sap.sailing.domain.tracking.Wind;
import com.sap.sailing.domain.tracking.WindTrack;
@@ -1143,6 +1148,16 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
return loadRaceLogRaceLogProtestStartTimeEvent(createdAt, author, logicalTimePoint, id, passId, competitors, dbObject);
} else if (eventClass.equals(RaceLogWindFixEvent.class.getSimpleName())) {
return loadRaceLogRaceLogWindFixEvent(createdAt, author, logicalTimePoint, id, passId, competitors, dbObject);
} else if (eventClass.equals(DeviceCompetitorMappingEvent.class.getSimpleName())) {
return loadRaceLogDeviceCompetitorMappingEvent(createdAt, author, logicalTimePoint, id, passId, competitors, dbObject);
} else if (eventClass.equals(DeviceMarkMappingEvent.class.getSimpleName())) {
return loadRaceLogDeviceMarkMappingEvent(createdAt, author, logicalTimePoint, id, passId, competitors, dbObject);
} else if (eventClass.equals(DenoteForTrackingEvent.class.getSimpleName())) {
return loadRaceLogDenoteForTrackingEvent(createdAt, author, logicalTimePoint, id, passId, competitors, dbObject);
} else if (eventClass.equals(CreateRaceEvent.class.getSimpleName())) {
return loadRaceLogCreateRaceEvent(createdAt, author, logicalTimePoint, id, passId, competitors, dbObject);
} else if (eventClass.equals(RevokeEvent.class.getSimpleName())) {
return loadRaceLogRevokeEvent(createdAt, author, logicalTimePoint, id, passId, competitors, dbObject);
}
throw new IllegalStateException(String.format("Unknown RaceLogEvent type %s", eventClass));
@@ -1154,6 +1169,47 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
return raceLogEventFactory.createWindFixEvent(createdAt, author, logicalTimePoint, id, competitors, passId, wind);
}
private RaceLogEvent loadRaceLogDeviceCompetitorMappingEvent(TimePoint createdAt, RaceLogEventAuthor author, TimePoint logicalTimePoint,
Serializable id, Integer passId, List<Competitor> competitors, DBObject dbObject) {
//TODO
DeviceIdentifier device = null;
Competitor mappedTo = DomainFactory.INSTANCE.getExistingCompetitorById(
(Serializable) dbObject.get(FieldNames.COMPETITOR_ID.name()));
TimePoint from = loadTimePoint(dbObject, FieldNames.RACE_LOG_FROM);
TimePoint to = loadTimePoint(dbObject, FieldNames.RACE_LOG_TO);
return raceLogEventFactory.createDeviceCompetitorMappingEvent(createdAt, author, logicalTimePoint, id, device, mappedTo, passId, from, to);
}
private RaceLogEvent loadRaceLogDeviceMarkMappingEvent(TimePoint createdAt, RaceLogEventAuthor author, TimePoint logicalTimePoint,
Serializable id, Integer passId, List<Competitor> competitors, DBObject dbObject) {
//TODO
DeviceIdentifier device = null;
Mark mappedTo = DomainFactory.INSTANCE.getOrCreateMark(
(Serializable) dbObject.get(FieldNames.MARK_ID.name()), null);
TimePoint from = loadTimePoint(dbObject, FieldNames.RACE_LOG_FROM);
TimePoint to = loadTimePoint(dbObject, FieldNames.RACE_LOG_TO);
return raceLogEventFactory.createDeviceMarkMappingEvent(createdAt, author, logicalTimePoint, id, device, mappedTo, passId, from, to);
}
private RaceLogEvent loadRaceLogDenoteForTrackingEvent(TimePoint createdAt, RaceLogEventAuthor author, TimePoint logicalTimePoint,
Serializable id, Integer passId, List<Competitor> competitors, DBObject dbObject) {
String raceName = (String) dbObject.get(FieldNames.RACE_NAME.name());
BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass((String) dbObject.get(FieldNames.BOAT_CLASS_NAME.name()));
return raceLogEventFactory.createDenoteForTrackingEvent(createdAt, author, logicalTimePoint, id, passId, raceName, boatClass);
}
private RaceLogEvent loadRaceLogCreateRaceEvent(TimePoint createdAt, RaceLogEventAuthor author, TimePoint logicalTimePoint,
Serializable id, Integer passId, List<Competitor> competitors, DBObject dbObject) {
return raceLogEventFactory.createCreateRaceEvent(createdAt, author, logicalTimePoint, id, passId);
}
private RaceLogEvent loadRaceLogRevokeEvent(TimePoint createdAt, RaceLogEventAuthor author, TimePoint logicalTimePoint,
Serializable id, Integer passId, List<Competitor> competitors, DBObject dbObject) {
Serializable revokedEventId = Helpers.tryUuidConversion(
(Serializable) dbObject.get(FieldNames.RACE_LOG_REVOKED_EVENT_ID.name()));
return raceLogEventFactory.createRevokeEvent(createdAt, author, logicalTimePoint, id, passId, revokedEventId);
}
private RaceLogEvent loadRaceLogRaceLogProtestStartTimeEvent(TimePoint createdAt, RaceLogEventAuthor author,
TimePoint logicalTimePoint, Serializable id, Integer passId, List<Competitor> competitors, DBObject dbObject) {
TimePoint protestStartTime = loadTimePoint(dbObject, FieldNames.RACE_LOG_PROTEST_START_TIME);
@@ -75,7 +75,7 @@ public enum FieldNames {
WAYPOINT_PASSINGINSTRUCTIONS, CONTROLPOINT, CONTROLPOINT_CLASS, MARK_ID, MARK_COLOR, MARK_NAME, MARK_PATTERN, MARK_SHAPE, MARK_TYPE,
CONTROLPOINT_VALUE, CONTROLPOINTWITHTWOMARKS_ID, CONTROLPOINTWITHTWOMARKS_NAME, CONTROLPOINTWITHTWOMARKS_LEFT, CONTROLPOINTWITHTWOMARKS_RIGHT,
RACE_LOG_POSITIONED_COMPETITORS, RACE_LOG_PATHFINDER_ID, RACE_LOG_GATE_LINE_OPENING_TIME, RACE_LOG_GOLF_DOWN_TIME, RACE_LOG_START_PROCEDURE_TYPE,
RACE_LOG_PROTEST_START_TIME, RACE_LOG_COURSE_DESIGN_NAME,
RACE_LOG_PROTEST_START_TIME, RACE_LOG_COURSE_DESIGN_NAME, RACE_LOG_REVOKED_EVENT_ID, RACE_LOG_FROM, RACE_LOG_TO,
/** @deprecated Replaced by WAYPOINT_PASSINGINSTRUCTIONS, still used to migrate old races*/ @Deprecated WAYPOINT_PASSINGSIDE,
/** @deprecated Replaced by CONTROLPOINTWITHTWOMARKS_ID, still used to migrate old races*/ @Deprecated GATE_ID,
/** @deprecated Replaced by CONTROLPOINTWITHTWOMARKS_NAME, still used to migrate old races*/ @Deprecated GATE_NAME,
@@ -48,6 +48,7 @@ import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.common.impl.Util;
import com.sap.sailing.domain.common.impl.Util.Triple;
import com.sap.sailing.domain.devices.DeviceIdentifier;
import com.sap.sailing.domain.devices.TypeBasedServiceFinderFactory;
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
import com.sap.sailing.domain.leaderboard.Leaderboard;
@@ -73,6 +74,11 @@ import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.racelog.RaceLogStartProcedureChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
import com.sap.sailing.domain.racelog.tracking.CreateRaceEvent;
import com.sap.sailing.domain.racelog.tracking.DenoteForTrackingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceCompetitorMappingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceMarkMappingEvent;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
import com.sap.sailing.domain.tracking.Positioned;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRegatta;
@@ -677,6 +683,46 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogWindFix(event));
return result;
}
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, DeviceCompetitorMappingEvent event) {
BasicDBObject result = new BasicDBObject();
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogDeviceCompetitorMappingEvent(event));
return result;
}
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, DeviceMarkMappingEvent event) {
BasicDBObject result = new BasicDBObject();
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogDeviceMarkMappingEvent(event));
return result;
}
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, DenoteForTrackingEvent event) {
BasicDBObject result = new BasicDBObject();
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogDenoteForTrackingEvent(event));
return result;
}
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, CreateRaceEvent event) {
BasicDBObject result = new BasicDBObject();
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogCreateRaceEvent(event));
return result;
}
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RevokeEvent event) {
BasicDBObject result = new BasicDBObject();
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogRevokeEvent(event));
return result;
}
private Object storeRaceLogWindFix(RaceLogWindFixEvent event) {
DBObject result = new BasicDBObject();
@@ -715,14 +761,54 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
return result;
}
private DBObject storeRaceLogStartTimeEvent(RaceLogStartTimeEvent startTimeEvent) {
private Object storeRaceLogDeviceCompetitorMappingEvent(DeviceCompetitorMappingEvent event) {
DBObject result = new BasicDBObject();
storeRaceLogEventProperties(startTimeEvent, result);
storeRaceLogEventProperties(event, result);
result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RaceLogStartTimeEvent.class.getSimpleName());
storeTimePoint(startTimeEvent.getStartTime(), result, FieldNames.RACE_LOG_EVENT_START_TIME);
result.put(FieldNames.RACE_LOG_EVENT_NEXT_STATUS.name(), startTimeEvent.getNextStatus().name());
result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), DeviceCompetitorMappingEvent.class.getSimpleName());
//TODO
result.put(FieldNames.COMPETITOR_ID.name(), event.getMappedTo().getId());
storeTimePoint(event.getFrom(), result, FieldNames.RACE_LOG_FROM);
storeTimePoint(event.getTo(), result, FieldNames.RACE_LOG_TO);
return result;
}
private Object storeRaceLogDeviceMarkMappingEvent(DeviceMarkMappingEvent event) {
DBObject result = new BasicDBObject();
storeRaceLogEventProperties(event, result);
result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), DeviceMarkMappingEvent.class.getSimpleName());
//TODO
result.put(FieldNames.MARK_ID.name(), event.getMappedTo().getId());
storeTimePoint(event.getFrom(), result, FieldNames.RACE_LOG_FROM);
storeTimePoint(event.getTo(), result, FieldNames.RACE_LOG_TO);
return result;
}
private Object storeRaceLogDenoteForTrackingEvent(DenoteForTrackingEvent event) {
DBObject result = new BasicDBObject();
storeRaceLogEventProperties(event, result);
result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), DenoteForTrackingEvent.class.getSimpleName());
result.put(FieldNames.RACE_NAME.name(), event.getRaceName());
result.put(FieldNames.BOAT_CLASS_NAME.name(), event.getBoatClass().getName());
return result;
}
private Object storeRaceLogCreateRaceEvent(CreateRaceEvent event) {
DBObject result = new BasicDBObject();
storeRaceLogEventProperties(event, result);
result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), CreateRaceEvent.class.getSimpleName());
return result;
}
private Object storeRaceLogRevokeEvent(RevokeEvent event) {
DBObject result = new BasicDBObject();
storeRaceLogEventProperties(event, result);
result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RevokeEvent.class.getSimpleName());
result.put(FieldNames.RACE_LOG_REVOKED_EVENT_ID.name(), event.getRevokedEventId());
return result;
}
@@ -737,6 +823,17 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
result.put(FieldNames.RACE_LOG_EVENT_FLAG_DISPLAYED.name(), String.valueOf(flagEvent.isDisplayed()));
return result;
}
private DBObject storeRaceLogStartTimeEvent(RaceLogStartTimeEvent startTimeEvent) {
DBObject result = new BasicDBObject();
storeRaceLogEventProperties(startTimeEvent, result);
result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RaceLogStartTimeEvent.class.getSimpleName());
storeTimePoint(startTimeEvent.getStartTime(), result, FieldNames.RACE_LOG_EVENT_START_TIME);
result.put(FieldNames.RACE_LOG_EVENT_NEXT_STATUS.name(), startTimeEvent.getNextStatus().name());
return result;
}
private void storeRaceLogEventProperties(RaceLogEvent event, DBObject result) {
// for compatibility reasons we reuse the field name of Timed
@@ -20,6 +20,11 @@ import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.racelog.RaceLogStartProcedureChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
import com.sap.sailing.domain.racelog.tracking.CreateRaceEvent;
import com.sap.sailing.domain.racelog.tracking.DenoteForTrackingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceCompetitorMappingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceMarkMappingEvent;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
public class MongoRaceLogStoreVisitor implements RaceLogEventVisitor {
@@ -119,4 +124,34 @@ public class MongoRaceLogStoreVisitor implements RaceLogEventVisitor {
storeEventInCollection(object);
}
@Override
public void visit(DeviceCompetitorMappingEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
storeEventInCollection(object);
}
@Override
public void visit(DeviceMarkMappingEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
storeEventInCollection(object);
}
@Override
public void visit(DenoteForTrackingEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
storeEventInCollection(object);
}
@Override
public void visit(CreateRaceEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
storeEventInCollection(object);
}
@Override
public void visit(RevokeEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
storeEventInCollection(object);
}
}
@@ -0,0 +1,31 @@
package com.sap.sailing.domain.racelog.tracking.analyzing.test;
import org.junit.Before;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
import com.sap.sailing.domain.racelog.RaceLogEventFactory;
import com.sap.sailing.domain.racelog.impl.RaceLogEventAuthorImpl;
import com.sap.sailing.domain.racelog.impl.RaceLogImpl;
public abstract class AbstractRaceLogTrackingTest {
protected RaceLog log;
protected final RaceLogEventAuthor author = new RaceLogEventAuthorImpl("author0", 0);
protected final RaceLogEventAuthor author1 = new RaceLogEventAuthorImpl("author1", 1);
protected final TimePoint now = MillisecondsTimePoint.now();
protected final RaceLogEventFactory factory = RaceLogEventFactory.INSTANCE;
public AbstractRaceLogTrackingTest() {
super();
}
@Before
public void setup() {
log = new RaceLogImpl("log");
}
}
@@ -0,0 +1,67 @@
package com.sap.sailing.domain.racelog.tracking.analyzing.test;
import java.util.List;
import junit.framework.Assert;
import org.junit.Test;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.impl.CompetitorImpl;
import com.sap.sailing.domain.base.impl.MarkImpl;
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.devices.DeviceIdentifier;
import com.sap.sailing.domain.devices.SmartphoneImeiIdentifier;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
import com.sap.sailing.domain.racelog.tracking.DeviceMapping;
import com.sap.sailing.domain.racelog.tracking.analyzing.impl.DeviceCompetitorMappingFinder;
public class MappingAnalyzerTest extends AbstractRaceLogTrackingTest {
private final Competitor competitor = new CompetitorImpl("comp", "Comp", null, null, null);
private final Competitor competitor2 = new CompetitorImpl("comp2", "Comp2", null, null, null);
private final Mark mark = new MarkImpl("mark");
private final DeviceIdentifier device = new SmartphoneImeiIdentifier("imei");
private List<DeviceMapping<Competitor>> getMappings() {
return new DeviceCompetitorMappingFinder(log).analyze().get(competitor);
}
private void addMapping(RaceLogEventAuthor author, long from, long to, Competitor item) {
RaceLogEvent mapping = factory.createDeviceCompetitorMappingEvent(now, author, device, item, 0,
new MillisecondsTimePoint(from), new MillisecondsTimePoint(to));
log.add(mapping);
}
private void addMapping(RaceLogEventAuthor author, long from, long to, Mark item) {
RaceLogEvent mapping = factory.createDeviceMarkMappingEvent(now, author, device, item, 0,
new MillisecondsTimePoint(from), new MillisecondsTimePoint(to));
log.add(mapping);
}
@Test
public void isCorrectMappingGenerate() {
addMapping(author, 10, 40, competitor);
addMapping(author, 10, 40, competitor2);
addMapping(author, 20, 30, competitor2);
addMapping(author, 50, 90, competitor);
Assert.assertEquals(2, getMappings().size());
addMapping(author, 5, 100, competitor);
addMapping(author, 15, 90, mark);
Assert.assertEquals(1, getMappings().size());
addMapping(author, 110, 150, competitor);
Assert.assertEquals(2, getMappings().size());
addMapping(author, 0, 50, competitor);
Assert.assertEquals(3, getMappings().size());
addMapping(author, 60, 70, competitor);
Assert.assertEquals(5, getMappings().size());
addMapping(author, 140, 160, competitor);
Assert.assertEquals(6, getMappings().size());
}
}
@@ -0,0 +1,53 @@
package com.sap.sailing.domain.racelog.tracking.analyzing.test;
import junit.framework.Assert;
import org.junit.Test;
import com.sap.sailing.domain.common.impl.Util;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
public class RevokeEventTest extends AbstractRaceLogTrackingTest {
@Test
public void revokedEventIsExcluded() {
RaceLogEvent event = factory.createDeviceCompetitorMappingEvent(now, author, null, null, 0, null, null);
RevokeEvent revokeEvent = factory.createRevokeEvent(now.plus(1), author, 0, event.getId());
log.add(event);
log.add(revokeEvent);
log.lockForRead();
Assert.assertFalse(Util.contains(log.getUnrevokedEvents(), event));
log.unlockAfterRead();
}
@Test
public void eventRevokedByAuthorWithLowerPrioIsNotExcluded() {
RaceLogEvent event = factory.createDeviceCompetitorMappingEvent(now, author, null, null, 0, null, null);
RevokeEvent revokeEvent = factory.createRevokeEvent(now.plus(1), author1, 0, event.getId());
log.add(event);
log.add(revokeEvent);
log.lockForRead();
Assert.assertTrue(Util.contains(log.getUnrevokedEvents(), event));
log.unlockAfterRead();
}
@Test
public void revokingRevokeEventIsNotHarmful() {
RaceLogEvent event = factory.createDeviceCompetitorMappingEvent(now, author, null, null, 0, null, null);
RevokeEvent revokeEvent = factory.createRevokeEvent(now.plus(1), author, 0, event.getId());
RevokeEvent revokeEvent2 = factory.createRevokeEvent(now.plus(2), author, 2, revokeEvent.getId());
log.add(event);
log.add(revokeEvent);
log.lockForRead();
Assert.assertFalse(Util.contains(log.getUnrevokedEvents(), event));
Assert.assertFalse(Util.contains(log.getUnrevokedEvents(), revokeEvent));
Assert.assertFalse(Util.contains(log.getUnrevokedEvents(), revokeEvent2));
log.unlockAfterRead();
}
}
@@ -27,6 +27,10 @@ Export-Package: com.sap.sailing.domain.base,
com.sap.sailing.domain.racelog.state.racingprocedure.impl,
com.sap.sailing.domain.racelog.state.racingprocedure.rrs26,
com.sap.sailing.domain.racelog.state.racingprocedure.rrs26.impl,
com.sap.sailing.domain.racelog.tracking,
com.sap.sailing.domain.racelog.tracking.analyzing.impl,
com.sap.sailing.domain.racelog.tracking.events,
com.sap.sailing.domain.racelog.tracking.impl,
com.sap.sailing.domain.tracking,
com.sap.sailing.domain.tracking.impl,
com.sap.sailing.util.impl
@@ -1,10 +1,13 @@
package com.sap.sailing.domain.racelog;
import java.io.Serializable;
import java.util.HashSet;
import java.util.NavigableSet;
import java.util.UUID;
import com.sap.sailing.domain.common.WithID;
import com.sap.sailing.domain.racelog.impl.RaceLogEventComparator;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
import com.sap.sailing.domain.tracking.Track;
/**
@@ -98,4 +101,26 @@ public interface RaceLog extends Track<RaceLogEvent>, WithID {
* in this race log yet
*/
boolean load(RaceLogEvent event);
/**
* Search for the event by its {@code id}, which will perform poorly for a large number
* of events, as they are ordered by {@link TimePoint}.
* @param id
* @return
*/
RaceLogEvent getEventById(Serializable id);
/**
* Check, whether the {@code revokeEvent} actually revokes the event it specifies by its
* {@link RevokeEvent#getRevokedEventId()}.
* @param revokeEvent
* @return
*/
boolean isEventRevokedBy(RevokeEvent revokeEvent);
/**
* Get a {@link NavigableSet} of unrevoked events.
* @return
*/
NavigableSet<RaceLogEvent> getUnrevokedEvents();
}
@@ -3,13 +3,21 @@ package com.sap.sailing.domain.racelog;
import java.io.Serializable;
import java.util.List;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseBase;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
import com.sap.sailing.domain.devices.DeviceIdentifier;
import com.sap.sailing.domain.racelog.impl.RaceLogEventFactoryImpl;
import com.sap.sailing.domain.racelog.tracking.CreateRaceEvent;
import com.sap.sailing.domain.racelog.tracking.DenoteForTrackingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceCompetitorMappingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceMarkMappingEvent;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
import com.sap.sailing.domain.tracking.Wind;
public interface RaceLogEventFactory {
@@ -88,4 +96,17 @@ public interface RaceLogEventFactory {
RaceLogWindFixEvent createWindFixEvent(TimePoint logicalTimePoint, RaceLogEventAuthor author,
Serializable id, List<Competitor> competitors, int passId, Wind wind);
DeviceCompetitorMappingEvent createDeviceCompetitorMappingEvent(TimePoint logicalTimePoint, RaceLogEventAuthor author,
DeviceIdentifier device, Competitor mappedTo, int passId, TimePoint from, TimePoint to);
DeviceMarkMappingEvent createDeviceMarkMappingEvent(TimePoint logicalTimePoint, RaceLogEventAuthor author,
DeviceIdentifier device, Mark mappedTo, int passId, TimePoint from, TimePoint to);
DenoteForTrackingEvent createDenoteForTrackingEvent(TimePoint logicalTimePoint, RaceLogEventAuthor author, int passId,
String raceName, BoatClass boatClass);
CreateRaceEvent createCreateRaceEvent(TimePoint logicalTimePoint, RaceLogEventAuthor author, int passId);
RevokeEvent createRevokeEvent(TimePoint logicalTimePoint, RaceLogEventAuthor author, int passId, Serializable revokedEventId);
}
@@ -3,13 +3,21 @@ package com.sap.sailing.domain.racelog;
import java.io.Serializable;
import java.util.List;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseBase;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
import com.sap.sailing.domain.devices.DeviceIdentifier;
import com.sap.sailing.domain.racelog.impl.RaceLogEventRestoreFactoryImpl;
import com.sap.sailing.domain.racelog.tracking.CreateRaceEvent;
import com.sap.sailing.domain.racelog.tracking.DenoteForTrackingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceCompetitorMappingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceMarkMappingEvent;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
import com.sap.sailing.domain.tracking.Wind;
public interface RaceLogEventRestoreFactory extends RaceLogEventFactory {
@@ -56,4 +64,19 @@ public interface RaceLogEventRestoreFactory extends RaceLogEventFactory {
RaceLogWindFixEvent createWindFixEvent(TimePoint createdAt, RaceLogEventAuthor author, TimePoint logicalTimePoint,
Serializable id, List<Competitor> competitors, Integer passId, Wind wind);
DeviceCompetitorMappingEvent createDeviceCompetitorMappingEvent(TimePoint createdAt, RaceLogEventAuthor author,
TimePoint logicalTimePoint, Serializable pId, DeviceIdentifier device, Competitor mappedTo, int passId, TimePoint from, TimePoint to);
DeviceMarkMappingEvent createDeviceMarkMappingEvent(TimePoint createdAt, RaceLogEventAuthor author,
TimePoint logicalTimePoint, Serializable pId, DeviceIdentifier device, Mark mappedTo, int passId, TimePoint from, TimePoint to);
DenoteForTrackingEvent createDenoteForTrackingEvent(TimePoint createdAt, RaceLogEventAuthor author,
TimePoint logicalTimePoint, Serializable pId, int passId, String raceName, BoatClass boatClass);
CreateRaceEvent createCreateRaceEvent(TimePoint createdAt, RaceLogEventAuthor author,
TimePoint logicalTimePoint, Serializable pId, int passId);
RevokeEvent createRevokeEvent(TimePoint createdAt, RaceLogEventAuthor author,
TimePoint logicalTimePoint, Serializable pId, int passId, Serializable revokedEventId);
}
@@ -1,5 +1,11 @@
package com.sap.sailing.domain.racelog;
import com.sap.sailing.domain.racelog.tracking.CreateRaceEvent;
import com.sap.sailing.domain.racelog.tracking.DenoteForTrackingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceCompetitorMappingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceMarkMappingEvent;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
public interface RaceLogEventVisitor {
public void visit(RaceLogFlagEvent event);
@@ -27,4 +33,14 @@ public interface RaceLogEventVisitor {
public void visit(RaceLogProtestStartTimeEvent event);
public void visit(RaceLogWindFixEvent event);
public void visit(DeviceCompetitorMappingEvent event);
public void visit(DeviceMarkMappingEvent event);
public void visit(DenoteForTrackingEvent event);
public void visit(CreateRaceEvent event);
public void visit(RevokeEvent event);
}
@@ -14,6 +14,11 @@ import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.racelog.RaceLogStartProcedureChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
import com.sap.sailing.domain.racelog.tracking.CreateRaceEvent;
import com.sap.sailing.domain.racelog.tracking.DenoteForTrackingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceCompetitorMappingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceMarkMappingEvent;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
/**
* Base class implementing {@link RaceLogEventVisitor}. Every method is implemented as a no-op.
@@ -84,5 +89,30 @@ public abstract class BaseRaceLogEventVisitor implements RaceLogEventVisitor {
public void visit(RaceLogWindFixEvent event) {
}
@Override
public void visit(DeviceCompetitorMappingEvent event) {
}
@Override
public void visit(DeviceMarkMappingEvent event) {
}
@Override
public void visit(DenoteForTrackingEvent event) {
}
@Override
public void visit(CreateRaceEvent event) {
}
@Override
public void visit(RevokeEvent event) {
}
}
@@ -1,202 +1,219 @@
package com.sap.sailing.domain.racelog.impl;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
/**
* Wrapper for a {@link RaceLog} which will ignore all calls trying to add an {@link RaceLogEvent}. All other
* functionality redirects to the wrapper {@link RaceLog}.
*/
public class NoAddingRaceLogWrapper implements RaceLog {
private static final long serialVersionUID = -5145744179072564993L;
private static final Logger logger = Logger.getLogger(NoAddingRaceLogWrapper.class.getSimpleName());
private final RaceLog innerRaceLog;
public NoAddingRaceLogWrapper(RaceLog innerRaceLog) {
this.innerRaceLog = innerRaceLog;
}
@Override
public boolean add(RaceLogEvent event) {
logger.log(Level.FINEST, "add() called; event will not be added.");
return false;
}
@Override
public Iterable<RaceLogEvent> add(RaceLogEvent event, UUID clientId) {
logger.log(Level.FINEST, "add() called; event will not be added.");
return Collections.emptyList();
}
@Override
public void addListener(RaceLogEventVisitor listener) {
innerRaceLog.addListener(listener);
}
@Override
public void removeListener(RaceLogEventVisitor listener) {
innerRaceLog.removeListener(listener);
}
@Override
public void addAllListeners(HashSet<RaceLogEventVisitor> listeners) {
innerRaceLog.addAllListeners(listeners);
}
@Override
public HashSet<RaceLogEventVisitor> removeAllListeners() {
return innerRaceLog.removeAllListeners();
}
@Override
public Iterable<RaceLogEventVisitor> getAllListeners() {
return innerRaceLog.getAllListeners();
}
@Override
public void lockForRead() {
innerRaceLog.lockForRead();
}
@Override
public void unlockAfterRead() {
innerRaceLog.unlockAfterRead();
}
@Override
public Iterable<RaceLogEvent> getFixes() {
return innerRaceLog.getFixes();
}
@Override
public Iterable<RaceLogEvent> getRawFixes() {
return innerRaceLog.getRawFixes();
}
@Override
public RaceLogEvent getLastFixAtOrBefore(TimePoint timePoint) {
return innerRaceLog.getLastFixAtOrBefore(timePoint);
}
@Override
public RaceLogEvent getLastFixBefore(TimePoint timePoint) {
return innerRaceLog.getLastFixBefore(timePoint);
}
@Override
public RaceLogEvent getLastRawFixAtOrBefore(TimePoint timePoint) {
return innerRaceLog.getLastRawFixAtOrBefore(timePoint);
}
@Override
public RaceLogEvent getFirstFixAtOrAfter(TimePoint timePoint) {
return innerRaceLog.getFirstFixAtOrAfter(timePoint);
}
@Override
public RaceLogEvent getFirstRawFixAtOrAfter(TimePoint timePoint) {
return innerRaceLog.getFirstRawFixAtOrAfter(timePoint);
}
@Override
public RaceLogEvent getLastRawFixBefore(TimePoint timePoint) {
return innerRaceLog.getLastRawFixBefore(timePoint);
}
@Override
public RaceLogEvent getFirstRawFixAfter(TimePoint timePoint) {
return innerRaceLog.getFirstRawFixAfter(timePoint);
}
@Override
public RaceLogEvent getFirstFixAfter(TimePoint timePoint) {
return innerRaceLog.getFirstFixAfter(timePoint);
}
@Override
public RaceLogEvent getFirstRawFix() {
return innerRaceLog.getFirstRawFix();
}
@Override
public RaceLogEvent getLastRawFix() {
return innerRaceLog.getLastRawFix();
}
@Override
public Iterator<RaceLogEvent> getFixesIterator(TimePoint startingAt, boolean inclusive) {
return innerRaceLog.getFixesIterator(startingAt, inclusive);
}
@Override
public Iterator<RaceLogEvent> getRawFixesIterator(TimePoint startingAt, boolean inclusive) {
return innerRaceLog.getRawFixesIterator(startingAt, inclusive);
}
@Override
public Serializable getId() {
return innerRaceLog;
}
@Override
public int getCurrentPassId() {
return innerRaceLog.getCurrentPassId();
}
@Override
public boolean isEmpty() {
return innerRaceLog.isEmpty();
}
@Override
public Iterable<RaceLogEvent> getRawFixesDescending() {
return innerRaceLog.getRawFixesDescending();
}
@Override
public Iterable<RaceLogEvent> getFixesDescending() {
return innerRaceLog.getFixesDescending();
}
@Override
public Iterable<RaceLogEvent> getRawFixes(UUID clientId) {
return innerRaceLog.getRawFixes(clientId);
}
@Override
public boolean load(RaceLogEvent event) {
return innerRaceLog.load(event);
}
@Override
public Iterator<RaceLogEvent> getFixesDescendingIterator(TimePoint startingAt, boolean inclusive) {
return innerRaceLog.getFixesDescendingIterator(startingAt, inclusive);
}
@Override
public Iterator<RaceLogEvent> getRawFixesDescendingIterator(TimePoint startingAt, boolean inclusive) {
return innerRaceLog.getRawFixesDescendingIterator(startingAt, inclusive);
}
@Override
public Iterable<RaceLogEvent> getEventsToDeliver(UUID clientId) {
return innerRaceLog.getEventsToDeliver(clientId);
}
@Override
public Iterable<RaceLogEvent> getFixes(TimePoint from, boolean fromInclusive, TimePoint to, boolean toInclusive) {
return innerRaceLog.getFixes(from, fromInclusive, to, toInclusive);
}
}
package com.sap.sailing.domain.racelog.impl;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.NavigableSet;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
/**
* Wrapper for a {@link RaceLog} which will ignore all calls trying to add an {@link RaceLogEvent}. All other
* functionality redirects to the wrapper {@link RaceLog}.
*/
public class NoAddingRaceLogWrapper implements RaceLog {
private static final long serialVersionUID = -5145744179072564993L;
private static final Logger logger = Logger.getLogger(NoAddingRaceLogWrapper.class.getSimpleName());
private final RaceLog innerRaceLog;
public NoAddingRaceLogWrapper(RaceLog innerRaceLog) {
this.innerRaceLog = innerRaceLog;
}
@Override
public boolean add(RaceLogEvent event) {
logger.log(Level.FINEST, "add() called; event will not be added.");
return false;
}
@Override
public Iterable<RaceLogEvent> add(RaceLogEvent event, UUID clientId) {
logger.log(Level.FINEST, "add() called; event will not be added.");
return Collections.emptyList();
}
@Override
public void addListener(RaceLogEventVisitor listener) {
innerRaceLog.addListener(listener);
}
@Override
public void removeListener(RaceLogEventVisitor listener) {
innerRaceLog.removeListener(listener);
}
@Override
public void addAllListeners(HashSet<RaceLogEventVisitor> listeners) {
innerRaceLog.addAllListeners(listeners);
}
@Override
public HashSet<RaceLogEventVisitor> removeAllListeners() {
return innerRaceLog.removeAllListeners();
}
@Override
public Iterable<RaceLogEventVisitor> getAllListeners() {
return innerRaceLog.getAllListeners();
}
@Override
public void lockForRead() {
innerRaceLog.lockForRead();
}
@Override
public void unlockAfterRead() {
innerRaceLog.unlockAfterRead();
}
@Override
public Iterable<RaceLogEvent> getFixes() {
return innerRaceLog.getFixes();
}
@Override
public Iterable<RaceLogEvent> getRawFixes() {
return innerRaceLog.getRawFixes();
}
@Override
public RaceLogEvent getLastFixAtOrBefore(TimePoint timePoint) {
return innerRaceLog.getLastFixAtOrBefore(timePoint);
}
@Override
public RaceLogEvent getLastFixBefore(TimePoint timePoint) {
return innerRaceLog.getLastFixBefore(timePoint);
}
@Override
public RaceLogEvent getLastRawFixAtOrBefore(TimePoint timePoint) {
return innerRaceLog.getLastRawFixAtOrBefore(timePoint);
}
@Override
public RaceLogEvent getFirstFixAtOrAfter(TimePoint timePoint) {
return innerRaceLog.getFirstFixAtOrAfter(timePoint);
}
@Override
public RaceLogEvent getFirstRawFixAtOrAfter(TimePoint timePoint) {
return innerRaceLog.getFirstRawFixAtOrAfter(timePoint);
}
@Override
public RaceLogEvent getLastRawFixBefore(TimePoint timePoint) {
return innerRaceLog.getLastRawFixBefore(timePoint);
}
@Override
public RaceLogEvent getFirstRawFixAfter(TimePoint timePoint) {
return innerRaceLog.getFirstRawFixAfter(timePoint);
}
@Override
public RaceLogEvent getFirstFixAfter(TimePoint timePoint) {
return innerRaceLog.getFirstFixAfter(timePoint);
}
@Override
public RaceLogEvent getFirstRawFix() {
return innerRaceLog.getFirstRawFix();
}
@Override
public RaceLogEvent getLastRawFix() {
return innerRaceLog.getLastRawFix();
}
@Override
public Iterator<RaceLogEvent> getFixesIterator(TimePoint startingAt, boolean inclusive) {
return innerRaceLog.getFixesIterator(startingAt, inclusive);
}
@Override
public Iterator<RaceLogEvent> getRawFixesIterator(TimePoint startingAt, boolean inclusive) {
return innerRaceLog.getRawFixesIterator(startingAt, inclusive);
}
@Override
public Serializable getId() {
return innerRaceLog;
}
@Override
public int getCurrentPassId() {
return innerRaceLog.getCurrentPassId();
}
@Override
public boolean isEmpty() {
return innerRaceLog.isEmpty();
}
@Override
public Iterable<RaceLogEvent> getRawFixesDescending() {
return innerRaceLog.getRawFixesDescending();
}
@Override
public Iterable<RaceLogEvent> getFixesDescending() {
return innerRaceLog.getFixesDescending();
}
@Override
public Iterable<RaceLogEvent> getRawFixes(UUID clientId) {
return innerRaceLog.getRawFixes(clientId);
}
@Override
public boolean load(RaceLogEvent event) {
return innerRaceLog.load(event);
}
@Override
public Iterator<RaceLogEvent> getFixesDescendingIterator(TimePoint startingAt, boolean inclusive) {
return innerRaceLog.getFixesDescendingIterator(startingAt, inclusive);
}
@Override
public Iterator<RaceLogEvent> getRawFixesDescendingIterator(TimePoint startingAt, boolean inclusive) {
return innerRaceLog.getRawFixesDescendingIterator(startingAt, inclusive);
}
@Override
public Iterable<RaceLogEvent> getEventsToDeliver(UUID clientId) {
return innerRaceLog.getEventsToDeliver(clientId);
}
@Override
public Iterable<RaceLogEvent> getFixes(TimePoint from, boolean fromInclusive, TimePoint to, boolean toInclusive) {
return innerRaceLog.getFixes(from, fromInclusive, to, toInclusive);
}
@Override
public RaceLogEvent getEventById(Serializable id) {
return innerRaceLog.getEventById(id);
}
@Override
public boolean isEventRevokedBy(RevokeEvent revokeEvent) {
return innerRaceLog.isEventRevokedBy(revokeEvent);
}
@Override
public NavigableSet<RaceLogEvent> getUnrevokedEvents() {
return innerRaceLog.getUnrevokedEvents();
}
}
@@ -15,6 +15,11 @@ import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.racelog.RaceLogStartProcedureChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
import com.sap.sailing.domain.racelog.tracking.CreateRaceEvent;
import com.sap.sailing.domain.racelog.tracking.DenoteForTrackingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceCompetitorMappingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceMarkMappingEvent;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
public class RaceLogChangedVisitor implements RaceLogEventVisitor {
@@ -83,4 +88,29 @@ public class RaceLogChangedVisitor implements RaceLogEventVisitor {
listener.eventAdded(event);
}
@Override
public void visit(DeviceCompetitorMappingEvent event) {
listener.eventAdded(event);
}
@Override
public void visit(DeviceMarkMappingEvent event) {
listener.eventAdded(event);
}
@Override
public void visit(DenoteForTrackingEvent event) {
listener.eventAdded(event);
}
@Override
public void visit(CreateRaceEvent event) {
listener.eventAdded(event);
}
@Override
public void visit(RevokeEvent event) {
listener.eventAdded(event);
}
}
@@ -5,13 +5,16 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseBase;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
import com.sap.sailing.domain.devices.DeviceIdentifier;
import com.sap.sailing.domain.racelog.CompetitorResults;
import com.sap.sailing.domain.racelog.RaceLogCourseAreaChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogCourseDesignChangedEvent;
@@ -27,6 +30,16 @@ import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.racelog.RaceLogStartProcedureChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
import com.sap.sailing.domain.racelog.tracking.CreateRaceEvent;
import com.sap.sailing.domain.racelog.tracking.DenoteForTrackingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceCompetitorMappingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceMarkMappingEvent;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
import com.sap.sailing.domain.racelog.tracking.events.CreateRaceEventImpl;
import com.sap.sailing.domain.racelog.tracking.events.DenoteForTrackingEventImpl;
import com.sap.sailing.domain.racelog.tracking.events.DeviceCompetitorMappingEventImpl;
import com.sap.sailing.domain.racelog.tracking.events.DeviceMarkMappingEventImpl;
import com.sap.sailing.domain.racelog.tracking.events.RevokeEventImpl;
import com.sap.sailing.domain.tracking.Wind;
public class RaceLogEventFactoryImpl implements RaceLogEventFactory {
@@ -200,4 +213,34 @@ public class RaceLogEventFactoryImpl implements RaceLogEventFactory {
return new RaceLogWindFixEventImpl(MillisecondsTimePoint.now(), author, logicalTimePoint, id, competitors, passId, wind);
}
@Override
public DeviceCompetitorMappingEvent createDeviceCompetitorMappingEvent(TimePoint logicalTimePoint, RaceLogEventAuthor author,
DeviceIdentifier device, Competitor mappedTo, int passId, TimePoint from, TimePoint to) {
return new DeviceCompetitorMappingEventImpl(MillisecondsTimePoint.now(), author, logicalTimePoint, UUID.randomUUID(),
passId, mappedTo, device, from, to);
}
@Override
public DeviceMarkMappingEvent createDeviceMarkMappingEvent(TimePoint logicalTimePoint, RaceLogEventAuthor author,
DeviceIdentifier device, Mark mappedTo, int passId, TimePoint from, TimePoint to) {
return new DeviceMarkMappingEventImpl(MillisecondsTimePoint.now(), author, logicalTimePoint, UUID.randomUUID(),
passId, mappedTo, device, from, to);
}
@Override
public DenoteForTrackingEvent createDenoteForTrackingEvent(TimePoint logicalTimePoint, RaceLogEventAuthor author, int passId,
String raceName, BoatClass boatClass) {
return new DenoteForTrackingEventImpl(MillisecondsTimePoint.now(), author, logicalTimePoint, UUID.randomUUID(), passId, raceName, boatClass);
}
@Override
public CreateRaceEvent createCreateRaceEvent(TimePoint logicalTimePoint, RaceLogEventAuthor author, int passId) {
return new CreateRaceEventImpl(MillisecondsTimePoint.now(), author, logicalTimePoint, UUID.randomUUID(), passId);
}
@Override
public RevokeEvent createRevokeEvent(TimePoint logicalTimePoint, RaceLogEventAuthor author, int passId, Serializable revokedEventId) {
return new RevokeEventImpl(MillisecondsTimePoint.now(), author, logicalTimePoint, UUID.randomUUID(), passId, revokedEventId);
}
}
@@ -3,12 +3,15 @@ package com.sap.sailing.domain.racelog.impl;
import java.io.Serializable;
import java.util.List;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseBase;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
import com.sap.sailing.domain.devices.DeviceIdentifier;
import com.sap.sailing.domain.racelog.CompetitorResults;
import com.sap.sailing.domain.racelog.RaceLogCourseAreaChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogCourseDesignChangedEvent;
@@ -25,6 +28,16 @@ import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.racelog.RaceLogStartProcedureChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
import com.sap.sailing.domain.racelog.tracking.CreateRaceEvent;
import com.sap.sailing.domain.racelog.tracking.DenoteForTrackingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceCompetitorMappingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceMarkMappingEvent;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
import com.sap.sailing.domain.racelog.tracking.events.CreateRaceEventImpl;
import com.sap.sailing.domain.racelog.tracking.events.DenoteForTrackingEventImpl;
import com.sap.sailing.domain.racelog.tracking.events.DeviceCompetitorMappingEventImpl;
import com.sap.sailing.domain.racelog.tracking.events.DeviceMarkMappingEventImpl;
import com.sap.sailing.domain.racelog.tracking.events.RevokeEventImpl;
import com.sap.sailing.domain.tracking.Wind;
public class RaceLogEventRestoreFactoryImpl extends RaceLogEventFactoryImpl implements RaceLogEventRestoreFactory {
@@ -109,5 +122,35 @@ public class RaceLogEventRestoreFactoryImpl extends RaceLogEventFactoryImpl impl
return new RaceLogWindFixEventImpl(createdAt, author, logicalTimePoint, id, competitors, passId, wind);
}
@Override
public DeviceCompetitorMappingEvent createDeviceCompetitorMappingEvent(TimePoint createdAt, RaceLogEventAuthor author,
TimePoint logicalTimePoint, Serializable pId, DeviceIdentifier device, Competitor mappedTo, int passId, TimePoint from, TimePoint to) {
return new DeviceCompetitorMappingEventImpl(createdAt, author, logicalTimePoint, pId, passId, mappedTo, device, from, to);
}
@Override
public DeviceMarkMappingEvent createDeviceMarkMappingEvent(TimePoint createdAt, RaceLogEventAuthor author,
TimePoint logicalTimePoint, Serializable pId, DeviceIdentifier device, Mark mappedTo, int passId, TimePoint from,
TimePoint to) {
return new DeviceMarkMappingEventImpl(createdAt, author, logicalTimePoint, pId, passId, mappedTo, device, from, to);
}
@Override
public DenoteForTrackingEvent createDenoteForTrackingEvent(TimePoint createdAt, RaceLogEventAuthor author,
TimePoint logicalTimePoint, Serializable pId, int passId, String raceName, BoatClass boatClass) {
return new DenoteForTrackingEventImpl(createdAt, author, logicalTimePoint, pId, passId, raceName, boatClass);
}
@Override
public CreateRaceEvent createCreateRaceEvent(TimePoint createdAt, RaceLogEventAuthor author, TimePoint logicalTimePoint,
Serializable pId, int passId) {
return new CreateRaceEventImpl(createdAt, author, logicalTimePoint, pId, passId);
}
@Override
public RevokeEvent createRevokeEvent(TimePoint createdAt, RaceLogEventAuthor author, TimePoint logicalTimePoint,
Serializable pId, int passId, Serializable revokedEventId) {
return new RevokeEventImpl(createdAt, author, logicalTimePoint, pId, passId, revokedEventId);
}
}
@@ -17,6 +17,7 @@ import com.sap.sailing.domain.base.Timed;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
import com.sap.sailing.domain.tracking.Track;
import com.sap.sailing.domain.tracking.impl.PartialNavigableSetView;
import com.sap.sailing.domain.tracking.impl.TrackImpl;
@@ -40,6 +41,7 @@ public class RaceLogImpl extends TrackImpl<RaceLogEvent> implements RaceLog {
private static final long serialVersionUID = -176745401321893502L;
private static final String DefaultLockName = RaceLogImpl.class.getName() + ".lock";
private final static Logger logger = Logger.getLogger(RaceLogImpl.class.getName());
private final Set<Serializable> revokedEventIds = new HashSet<Serializable>();
/**
* Clients can use the {@link #add(RaceLogEvent, UUID)} method
@@ -108,6 +110,7 @@ public class RaceLogImpl extends TrackImpl<RaceLogEvent> implements RaceLog {
// FIXME with out-of-order delivery would destroy currentPassId; need to check at least the createdAt time
// point
setCurrentPassId(Math.max(event.getPassId(), this.currentPassId));
revokeIfNecessary(event);
notifyListenersAboutReceive(event);
} else {
logger.warning(String.format("%s (%s) was not added to race log %s. Ignoring", event, event.getClass().getName(), getId()));
@@ -127,12 +130,30 @@ public class RaceLogImpl extends TrackImpl<RaceLogEvent> implements RaceLog {
if (isAdded) {
logger.finer(String.format("%s (%s) was loaded into log.", event, event.getClass().getName()));
setCurrentPassId(Math.max(event.getPassId(), this.currentPassId));
revokeIfNecessary(event);
} else {
logger.warning(String
.format("%s (%s) was not loaded into log. Ignoring", event, event.getClass().getName()));
}
return isAdded;
}
private void revokeIfNecessary(RaceLogEvent newEvent) {
if (newEvent instanceof RevokeEvent) {
RevokeEvent revokeEvent = (RevokeEvent) newEvent;
lockForRead();
RaceLogEvent revokedEvent = getEventById(revokeEvent.getRevokedEventId());
unlockAfterRead();
if (! (revokedEvent instanceof RevokeEvent) && isEventRevokedBy(revokeEvent)) {
lockForWrite();
revokedEventIds.add(revokeEvent.getRevokedEventId());
unlockAfterWrite();
} else {
logger.log(Level.FINE, "Not revoking event " + revokedEvent);
}
}
}
@Override
public Iterable<RaceLogEvent> add(RaceLogEvent event, UUID clientId) {
@@ -148,6 +169,7 @@ public class RaceLogImpl extends TrackImpl<RaceLogEvent> implements RaceLog {
// FIXME with out-of-order delivery would destroy currentPassId; need to check at least the createdAt time
// point
setCurrentPassId(Math.max(event.getPassId(), this.currentPassId));
revokeIfNecessary(event);
notifyListenersAboutReceive(event);
} else {
logger.warning(String.format("%s (%s) was not added to log. Ignoring", event, event.getClass().getName()));
@@ -278,4 +300,30 @@ public class RaceLogImpl extends TrackImpl<RaceLogEvent> implements RaceLog {
edtc.addAll(result);
return result;
}
@Override
public RaceLogEvent getEventById(Serializable id) {
for (RaceLogEvent e : getRawFixes()) {
if (e.getId().equals(id)) return e;
}
return null;
}
@Override
public boolean isEventRevokedBy(RevokeEvent revokeEvent) {
lockForRead();
RaceLogEvent revokedEvent = getEventById(revokeEvent.getRevokedEventId());
unlockAfterRead();
return getInternalRawFixes().comparator().compare(revokeEvent, revokedEvent) > 0;
}
@Override
public NavigableSet<RaceLogEvent> getUnrevokedEvents() {
return new PartialNavigableSetView<RaceLogEvent>(super.getInternalFixes()) {
@Override
protected boolean isValid(RaceLogEvent e) {
return ! (e instanceof RevokeEvent) && ! revokedEventIds.contains(e.getId());
}
};
}
}
@@ -0,0 +1,15 @@
package com.sap.sailing.domain.racelog.tracking;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.tracking.events.DeviceCompetitorMappingEventImpl;
/**
* Closes the phase during which {@link DeviceCompetitorMappingEventImpl}s actually result
* in competitors being added, and indicates that the server should create a {@link TrackedRace}
* using the information in this {@link RaceLog}.
*
* @author Fredrik Teschke
*
*/
public interface CreateRaceEvent extends RaceLogEvent {
}
@@ -0,0 +1,19 @@
package com.sap.sailing.domain.racelog.tracking;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
/**
* The existence of this event in a {@link RaceLog} indicates that the necessary data
* for creating this race will be accumulated in this RaceLog. Once it is present, the
* actual {@link TrackedRace} can then be created from this information, and fixes for
* competitors and marks that arrive through {@link RacingEventService#storeGPSFix}
* for which a corresponding {@link DeviceMappingEvent} exists will be added to the race.
* @author Fredrik Teschke
*
*/
public interface DenoteForTrackingEvent extends RaceLogEvent {
String getRaceName();
BoatClass getBoatClass();
}
@@ -0,0 +1,7 @@
package com.sap.sailing.domain.racelog.tracking;
import com.sap.sailing.domain.base.Competitor;
public interface DeviceCompetitorMappingEvent extends DeviceMappingEvent<Competitor> {
}
@@ -0,0 +1,12 @@
package com.sap.sailing.domain.racelog.tracking;
import com.sap.sailing.domain.base.Timed;
import com.sap.sailing.domain.common.TimeRange;
import com.sap.sailing.domain.common.WithID;
import com.sap.sailing.domain.devices.DeviceIdentifier;
public interface DeviceMapping<ItemType extends WithID> extends Timed {
ItemType getMappedTo();
DeviceIdentifier getDevice();
TimeRange getTimeRange();
}
@@ -0,0 +1,14 @@
package com.sap.sailing.domain.racelog.tracking;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.WithID;
import com.sap.sailing.domain.devices.DeviceIdentifier;
import com.sap.sailing.domain.racelog.RaceLogEvent;
public interface DeviceMappingEvent<ItemType extends WithID> extends RaceLogEvent {
ItemType getMappedTo();
DeviceIdentifier getDevice();
TimePoint getFrom();
TimePoint getTo();
}
@@ -0,0 +1,7 @@
package com.sap.sailing.domain.racelog.tracking;
import com.sap.sailing.domain.base.Mark;
public interface DeviceMarkMappingEvent extends DeviceMappingEvent<Mark> {
}
@@ -0,0 +1,18 @@
package com.sap.sailing.domain.racelog.tracking;
import java.io.Serializable;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
/**
* The event referenced by {@link #getRevokedEventId()} should be revoked, that is to say the {@link RaceLog}
* should ignore it in {@link RaceLog#getUnrevokedEvents()}.
*
* A {@link RevokeEvent} cannot itself be revoked. Instead, e.g. the original event should be resubmitted.
* @author Fredrik Teschke
*
*/
public interface RevokeEvent extends RaceLogEvent {
Serializable getRevokedEventId();
}
@@ -0,0 +1,18 @@
package com.sap.sailing.domain.racelog.tracking.analyzing.impl;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.tracking.DeviceCompetitorMappingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceMappingEvent;
public class DeviceCompetitorMappingFinder extends DeviceMappingFinder<Competitor> {
public DeviceCompetitorMappingFinder(RaceLog raceLog) {
super(raceLog);
}
@Override
protected boolean isValidMapping(DeviceMappingEvent<?> mapping) {
return mapping instanceof DeviceCompetitorMappingEvent;
}
}
@@ -0,0 +1,118 @@
package com.sap.sailing.domain.racelog.tracking.analyzing.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.TimeRange;
import com.sap.sailing.domain.common.WithID;
import com.sap.sailing.domain.common.impl.TimeRangeImpl;
import com.sap.sailing.domain.devices.DeviceIdentifier;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.analyzing.impl.RaceLogAnalyzer;
import com.sap.sailing.domain.racelog.tracking.DeviceMapping;
import com.sap.sailing.domain.racelog.tracking.DeviceMappingEvent;
import com.sap.sailing.domain.racelog.tracking.impl.DeviceMappingImpl;
import com.sap.sailing.domain.tracking.impl.TimedComparator;
public abstract class DeviceMappingFinder<ItemT extends WithID> extends RaceLogAnalyzer<Map<ItemT, List<DeviceMapping<ItemT>>>> {
public DeviceMappingFinder(RaceLog raceLog) {
super(raceLog);
}
protected abstract boolean isValidMapping(DeviceMappingEvent<?> mapping);
protected DeviceMapping<ItemT> getMapping(DeviceMappingEvent<ItemT> event) {
return new DeviceMappingImpl<ItemT>(event.getMappedTo(), event.getDevice(),
new TimeRangeImpl(event.getFrom(), event.getTo()));
}
protected DeviceMapping<ItemT> getMapping(DeviceIdentifier device, ItemT item,
TimePoint from, TimePoint to) {
return new DeviceMappingImpl<ItemT>(item, device, new TimeRangeImpl(from, to));
}
private List<DeviceMapping<ItemT>> getItemSet(
Map<ItemT, List<DeviceMapping<ItemT>>> map, ItemT item) {
List<DeviceMapping<ItemT>> list = map.get(item);
if (list == null) {
list = new ArrayList<DeviceMapping<ItemT>>();
map.put(item, list);
}
return list;
}
/**
* If an overlap in time is found between the this mapping, and one already found, the new mapping overrides
* the one in the initialSet for the time of the overlap.
* @param initial
* @param toBeAdded
* @return
*/
private List<DeviceMapping<ItemT>> getOverlapFreeMappings(List<DeviceMapping<ItemT>> initial,
DeviceMapping<ItemT> toBeAdded) {
TimeRange timeRange = toBeAdded.getTimeRange();
ItemT item = toBeAdded.getMappedTo();
DeviceIdentifier device = toBeAdded.getDevice();
List<DeviceMapping<ItemT>> result = new ArrayList<DeviceMapping<ItemT>>();
result.add(toBeAdded);
for (DeviceMapping<ItemT> otherMapping : initial) {
TimeRange otherTimeRange = otherMapping.getTimeRange();
if (otherTimeRange.intersects(timeRange)) {
/*
* one of the following can be true (--- is timeRange of toBeAdded, xxx is timeRange of otherMapping)
* xxxxxxxxxxxx timeRange of the otherMapping
*
* -------------- case 1: overwrite otherMapping completely
* xxx----xxxxx case 2: keep two parts of otherMapping (combination of 3 & 4)
* --------xxxxx case 3: keep only right part of otherMapping
* xxx---------- case 4: keep only left part of otherMapping
*/
if (otherTimeRange.liesWithin(timeRange)) {
//case 1: just ignore the other mapping, as it is completely overwritten by the new one
} else {
if (otherTimeRange.startsBefore(timeRange)) {
//case 4
result.add(getMapping(device, item, otherTimeRange.from(), timeRange.from().minus(1)));
}
if (otherTimeRange.endsAfter(timeRange)) {
//case 3
result.add(getMapping(device, item, timeRange.to().plus(1), otherTimeRange.to()));
}
}
} else {
//no overlap between these mappings, can just add the other one
result.add(otherMapping);
}
}
return result;
}
@Override
protected Map<ItemT, List<DeviceMapping<ItemT>>> performAnalysis() {
Map<ItemT, List<DeviceMapping<ItemT>>> result = new HashMap<ItemT, List<DeviceMapping<ItemT>>>();
/* iterate over events in order
* events with higher importance (later, higher author prio) are located towards the end, and should
* therefore override those before
*/
for (RaceLogEvent e : raceLog.getUnrevokedEvents()) {
if (e instanceof DeviceMappingEvent && isValidMapping(((DeviceMappingEvent<?>) e))) {
@SuppressWarnings("unchecked")
DeviceMappingEvent<ItemT> mappingEvent = (DeviceMappingEvent<ItemT>) e;
ItemT item = mappingEvent.getMappedTo();
List<DeviceMapping<ItemT>> mappings = getOverlapFreeMappings(getItemSet(result, item), getMapping(mappingEvent));
Collections.sort(mappings, new TimedComparator());
result.put(item, getOverlapFreeMappings(getItemSet(result, item), getMapping(mappingEvent)));
}
}
return result;
}
}
@@ -0,0 +1,18 @@
package com.sap.sailing.domain.racelog.tracking.analyzing.impl;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.tracking.DeviceMappingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceMarkMappingEvent;
public class DeviceMarkMappingFinder extends DeviceMappingFinder<Mark> {
public DeviceMarkMappingFinder(RaceLog raceLog) {
super(raceLog);
}
@Override
protected boolean isValidMapping(DeviceMappingEvent<?> mapping) {
return mapping instanceof DeviceMarkMappingEvent;
}
}
@@ -0,0 +1,26 @@
package com.sap.sailing.domain.racelog.tracking.analyzing.impl;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.analyzing.impl.RaceLogAnalyzer;
import com.sap.sailing.domain.racelog.tracking.DenoteForTrackingEvent;
public class RaceInformationFinder extends RaceLogAnalyzer<Pair<String, BoatClass>> {
public RaceInformationFinder(RaceLog raceLog) {
super(raceLog);
}
@Override
protected Pair<String, BoatClass> performAnalysis() {
for (RaceLogEvent event : getAllEvents()) {
if (event instanceof DenoteForTrackingEvent) {
DenoteForTrackingEvent e = (DenoteForTrackingEvent) event;
return new Pair<String, BoatClass>(e.getRaceName(), e.getBoatClass());
}
}
return null;
}
}
@@ -0,0 +1,45 @@
package com.sap.sailing.domain.racelog.tracking.events;
import java.io.Serializable;
import java.util.Collections;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.WithID;
import com.sap.sailing.domain.devices.DeviceIdentifier;
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
import com.sap.sailing.domain.racelog.impl.RaceLogEventImpl;
import com.sap.sailing.domain.racelog.tracking.DeviceMappingEvent;
public abstract class AbstractDeviceMappingEventImpl<ItemType extends WithID> extends RaceLogEventImpl implements
DeviceMappingEvent<ItemType> {
private static final long serialVersionUID = -8439653251231710356L;
private final ItemType mappedTo;
private final DeviceIdentifier device;
private final TimePoint from;
private final TimePoint to;
public AbstractDeviceMappingEventImpl(TimePoint createdAt, RaceLogEventAuthor author,
TimePoint logicalTimePoint, Serializable pId, int pPassId, ItemType mappedTo,
DeviceIdentifier device, TimePoint from, TimePoint to) {
super(createdAt, author, logicalTimePoint, pId, Collections.<Competitor>emptyList(), pPassId);
this.mappedTo = mappedTo;
this.device = device;
this.from = from;
this.to = to;
}
public ItemType getMappedTo() {
return mappedTo;
}
public DeviceIdentifier getDevice() {
return device;
}
public TimePoint getFrom() {
return from;
}
public TimePoint getTo() {
return to;
}
}
@@ -0,0 +1,28 @@
package com.sap.sailing.domain.racelog.tracking.events;
import java.io.Serializable;
import java.util.Collections;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
import com.sap.sailing.domain.racelog.impl.RaceLogEventImpl;
import com.sap.sailing.domain.racelog.tracking.CreateRaceEvent;
public class CreateRaceEventImpl extends RaceLogEventImpl implements
CreateRaceEvent {
private static final long serialVersionUID = 6017954368580125221L;
public CreateRaceEventImpl(TimePoint createdAt, RaceLogEventAuthor author,
TimePoint logicalTimePoint, Serializable pId, int pPassId) {
super(createdAt, author, logicalTimePoint, pId, Collections.<Competitor>emptyList(), pPassId);
}
@Override
public void accept(RaceLogEventVisitor visitor) {
visitor.visit(this);
}
}
@@ -0,0 +1,45 @@
package com.sap.sailing.domain.racelog.tracking.events;
import java.io.Serializable;
import java.util.Collections;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
import com.sap.sailing.domain.racelog.impl.RaceLogEventImpl;
import com.sap.sailing.domain.racelog.tracking.DenoteForTrackingEvent;
public class DenoteForTrackingEventImpl extends RaceLogEventImpl implements
DenoteForTrackingEvent {
private static final long serialVersionUID = 6937741283401976385L;
private final String raceName;
private final BoatClass boatClass;
public DenoteForTrackingEventImpl(TimePoint createdAt,
RaceLogEventAuthor author, TimePoint logicalTimePoint,
Serializable pId, int pPassId,
String raceName, BoatClass boatClass) {
super(createdAt, author, logicalTimePoint, pId, Collections.<Competitor>emptyList(), pPassId);
this.raceName = raceName;
this.boatClass = boatClass;
}
@Override
public void accept(RaceLogEventVisitor visitor) {
visitor.visit(this);
}
@Override
public String getRaceName() {
return raceName;
}
@Override
public BoatClass getBoatClass() {
return boatClass;
}
}
@@ -0,0 +1,25 @@
package com.sap.sailing.domain.racelog.tracking.events;
import java.io.Serializable;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.devices.DeviceIdentifier;
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
import com.sap.sailing.domain.racelog.tracking.DeviceCompetitorMappingEvent;
public class DeviceCompetitorMappingEventImpl extends AbstractDeviceMappingEventImpl<Competitor>
implements DeviceCompetitorMappingEvent {
public DeviceCompetitorMappingEventImpl(TimePoint createdAt, RaceLogEventAuthor author, TimePoint logicalTimePoint,
Serializable pId, int pPassId, Competitor mappedTo, DeviceIdentifier device, TimePoint from, TimePoint to) {
super(createdAt, author, logicalTimePoint, pId, pPassId, mappedTo, device, from, to);
}
private static final long serialVersionUID = -1494030544804758753L;
@Override
public void accept(RaceLogEventVisitor visitor) {
visitor.visit(this);
}
}
@@ -0,0 +1,25 @@
package com.sap.sailing.domain.racelog.tracking.events;
import java.io.Serializable;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.devices.DeviceIdentifier;
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
import com.sap.sailing.domain.racelog.tracking.DeviceMarkMappingEvent;
public class DeviceMarkMappingEventImpl extends AbstractDeviceMappingEventImpl<Mark>
implements DeviceMarkMappingEvent {
public DeviceMarkMappingEventImpl(TimePoint createdAt, RaceLogEventAuthor author, TimePoint logicalTimePoint,
Serializable pId, int pPassId, Mark mappedTo, DeviceIdentifier device, TimePoint from, TimePoint to) {
super(createdAt, author, logicalTimePoint, pId, pPassId, mappedTo, device, from, to);
}
private static final long serialVersionUID = -1494030544804758753L;
@Override
public void accept(RaceLogEventVisitor visitor) {
visitor.visit(this);
}
}
@@ -0,0 +1,33 @@
package com.sap.sailing.domain.racelog.tracking.events;
import java.io.Serializable;
import java.util.Collections;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
import com.sap.sailing.domain.racelog.impl.RaceLogEventImpl;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
public class RevokeEventImpl extends RaceLogEventImpl implements RevokeEvent {
private static final long serialVersionUID = -30864810737555657L;
private final Serializable revokedEventId;
public RevokeEventImpl(TimePoint createdAt, RaceLogEventAuthor author, TimePoint logicalTimePoint,
Serializable pId, int pPassId, Serializable revokedEventId) {
super(createdAt, author, logicalTimePoint, pId, Collections.<Competitor>emptyList(), pPassId);
this.revokedEventId = revokedEventId;
}
@Override
public void accept(RaceLogEventVisitor visitor) {
visitor.visit(this);
}
@Override
public Serializable getRevokedEventId() {
return revokedEventId;
}
}
@@ -0,0 +1,41 @@
package com.sap.sailing.domain.racelog.tracking.impl;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.TimeRange;
import com.sap.sailing.domain.common.WithID;
import com.sap.sailing.domain.devices.DeviceIdentifier;
import com.sap.sailing.domain.racelog.tracking.DeviceMapping;
public class DeviceMappingImpl<ItemType extends WithID> implements DeviceMapping<ItemType> {
private static final long serialVersionUID = -4602948402371623654L;
private final ItemType mappedTo;
private final DeviceIdentifier device;
private final TimeRange timeRange;
public DeviceMappingImpl(ItemType mappedTo, DeviceIdentifier device, TimeRange timeRange) {
this.mappedTo = mappedTo;
this.device = device;
this.timeRange = timeRange;
}
@Override
public DeviceIdentifier getDevice() {
return device;
}
@Override
public TimeRange getTimeRange() {
return timeRange;
}
@Override
public ItemType getMappedTo() {
return mappedTo;
}
@Override
public TimePoint getTimePoint() {
return timeRange.from();
}
}
@@ -19,6 +19,11 @@ import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.racelog.RaceLogStartProcedureChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
import com.sap.sailing.domain.racelog.tracking.CreateRaceEvent;
import com.sap.sailing.domain.racelog.tracking.DenoteForTrackingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceCompetitorMappingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceMarkMappingEvent;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
public class RaceColumnRaceLogReplicator implements RaceLogEventVisitor, Serializable {
private static final long serialVersionUID = 4752330236765192592L;
@@ -102,4 +107,29 @@ public class RaceColumnRaceLogReplicator implements RaceLogEventVisitor, Seriali
public void visit(RaceLogWindFixEvent event) {
notifyOnAdd(event);
}
@Override
public void visit(DeviceCompetitorMappingEvent event) {
notifyOnAdd(event);
}
@Override
public void visit(DeviceMarkMappingEvent event) {
notifyOnAdd(event);
}
@Override
public void visit(DenoteForTrackingEvent event) {
notifyOnAdd(event);
}
@Override
public void visit(CreateRaceEvent event) {
notifyOnAdd(event);
}
@Override
public void visit(RevokeEvent event) {
notifyOnAdd(event);
}
}
@@ -0,0 +1,20 @@
package com.sap.sailing.domain.devices;
public class SingleTypeBasedServiceFinderImpl<ServiceType> implements
TypeBasedServiceFinder<ServiceType> {
private final ServiceType service;
private final String type;
public SingleTypeBasedServiceFinderImpl(ServiceType service, String type) {
this.service = service;
this.type = type;
}
@Override
public ServiceType findService(String type)
throws NoCorrespondingServiceRegisteredException {
if (type.equals(this.type)) return service;
throw new NoCorrespondingServiceRegisteredException("Only one service registered", type);
}
}
@@ -1,6 +1,9 @@
package com.sap.sailing.mongodb.test;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -15,14 +18,18 @@ import org.junit.Test;
import com.mongodb.DBObject;
import com.mongodb.MongoException;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.common.impl.Util;
import com.sap.sailing.domain.common.impl.Util.Triple;
import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.domain.devices.DeviceIdentifier;
import com.sap.sailing.domain.devices.SmartphoneImeiIdentifier;
import com.sap.sailing.domain.persistence.PersistenceFactory;
import com.sap.sailing.domain.persistence.impl.DomainObjectFactoryImpl;
import com.sap.sailing.domain.persistence.impl.FieldNames;
@@ -30,13 +37,17 @@ import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
import com.sap.sailing.domain.racelog.RaceLogCourseAreaChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
import com.sap.sailing.domain.racelog.RaceLogEventFactory;
import com.sap.sailing.domain.racelog.RaceLogEventRestoreFactory;
import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.racelog.RaceLogPassChangeEvent;
import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
import com.sap.sailing.domain.racelog.impl.RaceLogEventAuthorImpl;
import com.sap.sailing.domain.racelog.tracking.DenoteForTrackingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceCompetitorMappingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceMarkMappingEvent;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
public class StoreAndLoadRaceLogEventsTest extends AbstractMongoDBTest {
@@ -44,7 +55,7 @@ public class StoreAndLoadRaceLogEventsTest extends AbstractMongoDBTest {
.getMongoObjectFactory(getMongoService());
protected DomainObjectFactoryImpl domainFactory = (DomainObjectFactoryImpl) PersistenceFactory.INSTANCE
.getDomainObjectFactory(getMongoService(), DomainFactory.INSTANCE);
protected RaceLogEventFactory eventFactory = RaceLogEventFactory.INSTANCE;
protected RaceLogEventRestoreFactory eventFactory = RaceLogEventRestoreFactory.INSTANCE;
protected RaceLogIdentifier logIdentifier;
@@ -156,6 +167,72 @@ public class StoreAndLoadRaceLogEventsTest extends AbstractMongoDBTest {
assertEquals(startTime, actualEvent.getStartTime());
}
@Test
public void testStoreAndLoadDeviceCompetitorMappingEvent() {
DeviceIdentifier device = new SmartphoneImeiIdentifier("a");
Competitor mappedTo = DomainFactory.INSTANCE.getOrCreateCompetitor("abc", "abc", null, null, null);
TimePoint from = new MillisecondsTimePoint(20);
TimePoint to = new MillisecondsTimePoint(30);
DeviceCompetitorMappingEvent expectedEvent = eventFactory.createDeviceCompetitorMappingEvent(
expectedEventTime, author, expectedEventTime, expectedId, device, mappedTo, expectedPassId, from, to);
DBObject dbObject = mongoFactory.storeRaceLogEntry(logIdentifier, expectedEvent);
DeviceCompetitorMappingEvent actualEvent = loadEvent(dbObject);
assertBaseFields(expectedEvent, actualEvent);
assertEquals(device, actualEvent.getDevice());
assertEquals(from, actualEvent.getFrom());
assertEquals(to, actualEvent.getTo());
assertEquals(mappedTo, actualEvent.getMappedTo());
}
@Test
public void testStoreAndLoadDeviceMarkMappingEvent() {
DeviceIdentifier device = new SmartphoneImeiIdentifier("a");
Mark mappedTo = DomainFactory.INSTANCE.getOrCreateMark("abc", "abc");
TimePoint from = new MillisecondsTimePoint(20);
TimePoint to = new MillisecondsTimePoint(30);
DeviceMarkMappingEvent expectedEvent = eventFactory.createDeviceMarkMappingEvent(
expectedEventTime, author, expectedEventTime, expectedId, device, mappedTo, expectedPassId, from, to);
DBObject dbObject = mongoFactory.storeRaceLogEntry(logIdentifier, expectedEvent);
DeviceMarkMappingEvent actualEvent = loadEvent(dbObject);
assertBaseFields(expectedEvent, actualEvent);
assertEquals(device, actualEvent.getDevice());
assertEquals(from, actualEvent.getFrom());
assertEquals(to, actualEvent.getTo());
assertEquals(mappedTo, actualEvent.getMappedTo());
}
@Test
public void testStoreAndLoadDenoteForTrackingEvent() {
String raceName = "race";
BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
DenoteForTrackingEvent expectedEvent = eventFactory.createDenoteForTrackingEvent(
expectedEventTime, author, expectedEventTime, expectedId, expectedPassId, raceName, boatClass);
DBObject dbObject = mongoFactory.storeRaceLogEntry(logIdentifier, expectedEvent);
DenoteForTrackingEvent actualEvent = loadEvent(dbObject);
assertBaseFields(expectedEvent, actualEvent);
assertEquals(boatClass, actualEvent.getBoatClass());
assertEquals(raceName, actualEvent.getRaceName());
}
@Test
public void testStoreAndLoadRevokeEvent() {
UUID revokedEventId = UUID.randomUUID();
RevokeEvent expectedEvent = eventFactory.createRevokeEvent(
expectedEventTime, author, expectedEventTime, expectedId, expectedPassId, revokedEventId);
DBObject dbObject = mongoFactory.storeRaceLogEntry(logIdentifier, expectedEvent);
RevokeEvent actualEvent = loadEvent(dbObject);
assertBaseFields(expectedEvent, actualEvent);
assertEquals(revokedEventId, actualEvent.getRevokedEventId());
}
/**
* Will always wait a couple of milliseconds to ensure that {@link RaceLogEvent#getCreatedAt()} has passed.
*/
@@ -32,6 +32,11 @@ public class RaceLogEventSerializerTest {
private JsonSerializer<RaceLogEvent> startProcedureTypeChangedEventSerializer;
private JsonSerializer<RaceLogEvent> protestStartTimeEventSerializer;
private JsonSerializer<RaceLogEvent> windFixEventSerializer;
private JsonSerializer<RaceLogEvent> deviceCompetitorMappingEventSerializer;
private JsonSerializer<RaceLogEvent> deviceMarkMappingEventSerializer;
private JsonSerializer<RaceLogEvent> denoteForTrackingEventSerializer;
private JsonSerializer<RaceLogEvent> createRaceEventSerializer;
private JsonSerializer<RaceLogEvent> revokeEventSerializer;
private RaceLogEventFactory factory;
private RaceLogEventAuthor author = new RaceLogEventAuthorImpl("Test Author", 1);
@@ -52,12 +57,19 @@ public class RaceLogEventSerializerTest {
startProcedureTypeChangedEventSerializer = mock(JsonSerializer.class);
protestStartTimeEventSerializer = mock(JsonSerializer.class);
windFixEventSerializer = mock(JsonSerializer.class);
deviceCompetitorMappingEventSerializer = mock(JsonSerializer.class);
deviceMarkMappingEventSerializer = mock(JsonSerializer.class);
denoteForTrackingEventSerializer = mock(JsonSerializer.class);
createRaceEventSerializer = mock(JsonSerializer.class);
revokeEventSerializer = mock(JsonSerializer.class);
serializer = new RaceLogEventSerializer(flagEventSerializer, startTimeSerializer, raceStatusSerializer,
courseAreaChangedEventSerializer, passChangedSerializer, courseDesignChangedEventSerializer,
finishPositioningListChangedEventSerializer, finishPositioningConfirmedEventSerializer,
pathfinderEventSerializer, gateLineOpeningTimeEventSerializer,
startProcedureTypeChangedEventSerializer, protestStartTimeEventSerializer, windFixEventSerializer);
startProcedureTypeChangedEventSerializer, protestStartTimeEventSerializer, windFixEventSerializer,
deviceCompetitorMappingEventSerializer, deviceMarkMappingEventSerializer, denoteForTrackingEventSerializer,
createRaceEventSerializer, revokeEventSerializer);
factory = RaceLogEventFactory.INSTANCE;
}
@@ -165,5 +177,45 @@ public class RaceLogEventSerializerTest {
serializer.serialize(event);
verify(windFixEventSerializer).serialize(event);
}
@Test
public void testDeviceCompetitorMappingSerializer() {
// we use the real event type here because we do not want to re-implement the dispatching.
RaceLogEvent event = factory.createDeviceCompetitorMappingEvent(null, author, null, null, 0, null, null);
serializer.serialize(event);
verify(deviceCompetitorMappingEventSerializer).serialize(event);
}
@Test
public void testDeviceMarkMappingSerializer() {
// we use the real event type here because we do not want to re-implement the dispatching.
RaceLogEvent event = factory.createDeviceMarkMappingEvent(null, author, null, null, 0, null, null);
serializer.serialize(event);
verify(deviceMarkMappingEventSerializer).serialize(event);
}
@Test
public void testDenoteForTrackingSerializer() {
// we use the real event type here because we do not want to re-implement the dispatching.
RaceLogEvent event = factory.createDenoteForTrackingEvent(null, author, 0, "", null);
serializer.serialize(event);
verify(denoteForTrackingEventSerializer).serialize(event);
}
@Test
public void testCreateRaceSerializer() {
// we use the real event type here because we do not want to re-implement the dispatching.
RaceLogEvent event = factory.createCreateRaceEvent(null, author, 0);
serializer.serialize(event);
verify(createRaceEventSerializer).serialize(event);
}
@Test
public void testRevokeEventSerializer() {
// we use the real event type here because we do not want to re-implement the dispatching.
RaceLogEvent event = factory.createRevokeEvent(null, author, 0, null);
serializer.serialize(event);
verify(revokeEventSerializer).serialize(event);
}
}
@@ -0,0 +1,25 @@
package com.sap.sailing.server.gateway.deserialization.racelog.impl;
import java.io.Serializable;
import java.util.List;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
public class RaceLogCreateRaceEventDeserializer extends BaseRaceLogEventDeserializer {
public RaceLogCreateRaceEventDeserializer(JsonDeserializer<Competitor> competitorDeserializer) {
super(competitorDeserializer);
}
@Override
protected RaceLogEvent deserialize(JSONObject object, Serializable id, TimePoint createdAt, RaceLogEventAuthor author, TimePoint timePoint, int passId, List<Competitor> competitors)
throws JsonDeserializationException {
return factory.createCreateRaceEvent(createdAt, author, timePoint, id, passId);
}
}
@@ -0,0 +1,32 @@
package com.sap.sailing.server.gateway.deserialization.racelog.impl;
import java.io.Serializable;
import java.util.List;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogDenoteForTrackingEventSerializer;
public class RaceLogDenoteForTrackingEventDeserializer extends BaseRaceLogEventDeserializer {
public RaceLogDenoteForTrackingEventDeserializer(JsonDeserializer<Competitor> competitorDeserializer) {
super(competitorDeserializer);
}
@Override
protected RaceLogEvent deserialize(JSONObject object, Serializable id, TimePoint createdAt, RaceLogEventAuthor author, TimePoint timePoint, int passId, List<Competitor> competitors)
throws JsonDeserializationException {
String raceName = (String) object.get(RaceLogDenoteForTrackingEventSerializer.FIELD_RACE_NAME);
BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass(
(String) object.get(RaceLogDenoteForTrackingEventSerializer.FIELD_BOAT_CLASS));
return factory.createDenoteForTrackingEvent(createdAt, author, timePoint, id, passId, raceName, boatClass);
}
}
@@ -0,0 +1,32 @@
package com.sap.sailing.server.gateway.deserialization.racelog.impl;
import java.io.Serializable;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.devices.DeviceIdentifier;
import com.sap.sailing.domain.devices.TypeBasedServiceFinder;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
import com.sap.sailing.server.gateway.serialization.devices.DeviceIdentifierJsonSerializationHandler;
public class RaceLogDeviceCompetitorMappingEventDeserializer extends
RaceLogDeviceMappingEventDeserializer<Competitor> {
public RaceLogDeviceCompetitorMappingEventDeserializer(
JsonDeserializer<Competitor> competitorDeserializer,
TypeBasedServiceFinder<DeviceIdentifierJsonSerializationHandler> deviceServiceFinder) {
super(competitorDeserializer, deviceServiceFinder);
}
@Override
protected RaceLogEvent furtherDeserialize(Serializable itemId, TimePoint from, TimePoint to,
DeviceIdentifier device, Serializable id, TimePoint createdAt,
RaceLogEventAuthor author, TimePoint timePoint, int passId) {
Competitor mappedTo = DomainFactory.INSTANCE.getExistingCompetitorById(itemId);
return factory.createDeviceCompetitorMappingEvent(createdAt, author, timePoint, id, device,
mappedTo, passId, from, to);
}
}
@@ -0,0 +1,50 @@
package com.sap.sailing.server.gateway.deserialization.racelog.impl;
import java.io.Serializable;
import java.util.List;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.WithID;
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.devices.DeviceIdentifier;
import com.sap.sailing.domain.devices.TypeBasedServiceFinder;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
import com.sap.sailing.server.gateway.serialization.devices.DeviceIdentifierJsonSerializationHandler;
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogDeviceMappingEventSerializer;
public abstract class RaceLogDeviceMappingEventDeserializer<ItemT extends WithID>
extends BaseRaceLogEventDeserializer {
protected final TypeBasedServiceFinder<DeviceIdentifierJsonSerializationHandler> deviceServiceFinder;
public RaceLogDeviceMappingEventDeserializer(
JsonDeserializer<Competitor> competitorDeserializer,
TypeBasedServiceFinder<DeviceIdentifierJsonSerializationHandler> deviceServiceFinder) {
super(competitorDeserializer);
this.deviceServiceFinder = deviceServiceFinder;
}
protected abstract RaceLogEvent furtherDeserialize(Serializable itemId, TimePoint from, TimePoint to,
DeviceIdentifier device, Serializable id, TimePoint createdAt, RaceLogEventAuthor author, TimePoint timePoint, int passId);
@Override
protected RaceLogEvent deserialize(JSONObject object, Serializable id,
TimePoint createdAt, RaceLogEventAuthor author,
TimePoint timePoint, int passId, List<Competitor> competitors)
throws JsonDeserializationException {
String deviceType = (String) object.get(RaceLogDeviceMappingEventSerializer.FIELD_DEVICE_TYPE);
DeviceIdentifier device = deviceServiceFinder.findService(deviceType).deserialize(
(JSONObject) object.get(RaceLogDeviceMappingEventSerializer.FIELD_DEVICE_ID));
Serializable itemId = (Serializable) object.get(RaceLogDeviceMappingEventSerializer.FIELD_ITEM);
long fromMillis = Long.parseLong((String) object.get(RaceLogDeviceMappingEventSerializer.FIELD_FROM_MILLIS));
long toMillis = Long.parseLong((String) object.get(RaceLogDeviceMappingEventSerializer.FIELD_TO_MILLIS));
TimePoint from = new MillisecondsTimePoint(fromMillis);
TimePoint to = new MillisecondsTimePoint(toMillis);
return furtherDeserialize(itemId, from, to, device, id, createdAt, author, timePoint, passId);
}
}
@@ -0,0 +1,33 @@
package com.sap.sailing.server.gateway.deserialization.racelog.impl;
import java.io.Serializable;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.devices.DeviceIdentifier;
import com.sap.sailing.domain.devices.TypeBasedServiceFinder;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
import com.sap.sailing.server.gateway.serialization.devices.DeviceIdentifierJsonSerializationHandler;
public class RaceLogDeviceMarkMappingEventDeserializer extends
RaceLogDeviceMappingEventDeserializer<Mark> {
public RaceLogDeviceMarkMappingEventDeserializer(
JsonDeserializer<Competitor> competitorDeserializer,
TypeBasedServiceFinder<DeviceIdentifierJsonSerializationHandler> deviceServiceFinder) {
super(competitorDeserializer, deviceServiceFinder);
}
@Override
protected RaceLogEvent furtherDeserialize(Serializable itemId, TimePoint from, TimePoint to,
DeviceIdentifier device, Serializable id, TimePoint createdAt,
RaceLogEventAuthor author, TimePoint timePoint, int passId) {
Mark mappedTo = DomainFactory.INSTANCE.getOrCreateMark(itemId, null);
return factory.createDeviceMarkMappingEvent(createdAt, author, timePoint, id, device,
mappedTo, passId, from, to);
}
}
@@ -4,6 +4,9 @@ import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.devices.SingleTypeBasedServiceFinderImpl;
import com.sap.sailing.domain.devices.SmartphoneImeiIdentifier;
import com.sap.sailing.domain.devices.TypeBasedServiceFinder;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
@@ -15,9 +18,15 @@ import com.sap.sailing.server.gateway.deserialization.coursedata.impl.WaypointDe
import com.sap.sailing.server.gateway.deserialization.impl.CompetitorJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.PositionJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.WindJsonDeserializer;
import com.sap.sailing.server.gateway.serialization.devices.DeviceIdentifierJsonSerializationHandler;
import com.sap.sailing.server.gateway.serialization.devices.SmartphoneImeiJsonSerializationHandler;
import com.sap.sailing.server.gateway.serialization.racelog.impl.BaseRaceLogEventSerializer;
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogCourseAreaChangedEventSerializer;
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogCourseDesignChangedEventSerializer;
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogCreateRaceEventSerializer;
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogDenoteForTrackingEventSerializer;
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogDeviceCompetitorMappingEventSerializer;
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogDeviceMarkMappingEventSerializer;
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogFinishPositioningConfirmedEventSerializer;
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogFinishPositioningListChangedEventSerializer;
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogFlagEventSerializer;
@@ -26,14 +35,22 @@ import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogPassChan
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogPathfinderEventSerializer;
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogProtestStartTimeEventSerializer;
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogRaceStatusEventSerializer;
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogRevokeEventSerializer;
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogStartProcedureChangedEventSerializer;
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogStartTimeEventSerializer;
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogWindFixEventSerializer;
public class RaceLogEventDeserializer implements JsonDeserializer<RaceLogEvent> {
public static RaceLogEventDeserializer create(SharedDomainFactory domainFactory) {
JsonDeserializer<Competitor> competitorDeserializer = new CompetitorJsonDeserializer(domainFactory, null, /* boatDeserializer */ null);
public static RaceLogEventDeserializer create(SharedDomainFactory domainFactory) {
return create(domainFactory,
new SingleTypeBasedServiceFinderImpl<DeviceIdentifierJsonSerializationHandler>(
new SmartphoneImeiJsonSerializationHandler(), SmartphoneImeiIdentifier.TYPE));
}
public static RaceLogEventDeserializer create(SharedDomainFactory domainFactory,
TypeBasedServiceFinder<DeviceIdentifierJsonSerializationHandler> deviceServiceFinder) {
JsonDeserializer<Competitor> competitorDeserializer = new CompetitorJsonDeserializer(domainFactory, null, /* boatDeserializer */ null);
return new RaceLogEventDeserializer(
new RaceLogFlagEventDeserializer(competitorDeserializer),
new RaceLogStartTimeEventDeserializer(competitorDeserializer),
@@ -53,7 +70,12 @@ public class RaceLogEventDeserializer implements JsonDeserializer<RaceLogEvent>
new RaceLogProtestStartTimeEventDeserializer(competitorDeserializer),
new RaceLogWindFixEventDeserializer(competitorDeserializer,
new WindJsonDeserializer(
new PositionJsonDeserializer())));
new PositionJsonDeserializer())),
new RaceLogDeviceCompetitorMappingEventDeserializer(competitorDeserializer, deviceServiceFinder),
new RaceLogDeviceMarkMappingEventDeserializer(competitorDeserializer, deviceServiceFinder),
new RaceLogDenoteForTrackingEventDeserializer(competitorDeserializer),
new RaceLogCreateRaceEventDeserializer(competitorDeserializer),
new RaceLogRevokeEventDeserializer(competitorDeserializer));
}
protected final JsonDeserializer<RaceLogEvent> flagEventDeserializer;
@@ -69,6 +91,11 @@ public class RaceLogEventDeserializer implements JsonDeserializer<RaceLogEvent>
protected final JsonDeserializer<RaceLogEvent> startProcedureChangedEventDeserializer;
protected final JsonDeserializer<RaceLogEvent> protestStartTimeEventDeserializer;
protected final JsonDeserializer<RaceLogEvent> windFixEventDeserializer;
protected final JsonDeserializer<RaceLogEvent> deviceCompetitorMappingEventDeserializer;
protected final JsonDeserializer<RaceLogEvent> deviceMarkMappingEventDeserializer;
protected final JsonDeserializer<RaceLogEvent> denoteForTrackingEventDeserializer;
protected final JsonDeserializer<RaceLogEvent> createRaceEventDeserializer;
protected final JsonDeserializer<RaceLogEvent> revokeEventDeserializer;
public RaceLogEventDeserializer(JsonDeserializer<RaceLogEvent> flagEventDeserializer,
JsonDeserializer<RaceLogEvent> startTimeEventDeserializer,
@@ -82,7 +109,12 @@ public class RaceLogEventDeserializer implements JsonDeserializer<RaceLogEvent>
JsonDeserializer<RaceLogEvent> gateLineOpeningTimeEventDeserializer,
JsonDeserializer<RaceLogEvent> startProcedureChangedEventDeserializer,
JsonDeserializer<RaceLogEvent> protestStartTimeEventDeserializer,
JsonDeserializer<RaceLogEvent> windFixEventDeserializer) {
JsonDeserializer<RaceLogEvent> windFixEventDeserializer,
JsonDeserializer<RaceLogEvent> deviceCompetitorMappingEventDeserializer,
JsonDeserializer<RaceLogEvent> deviceMarkMappingEventDeserializer,
JsonDeserializer<RaceLogEvent> denoteForTrackingEventDeserializer,
JsonDeserializer<RaceLogEvent> createRaceEventDeserializer,
JsonDeserializer<RaceLogEvent> revokeEventDeserializer) {
this.flagEventDeserializer = flagEventDeserializer;
this.startTimeEventDeserializer = startTimeEventDeserializer;
this.raceStatusEventDeserializer = raceStatusEventDeserializer;
@@ -96,6 +128,11 @@ public class RaceLogEventDeserializer implements JsonDeserializer<RaceLogEvent>
this.startProcedureChangedEventDeserializer = startProcedureChangedEventDeserializer;
this.protestStartTimeEventDeserializer = protestStartTimeEventDeserializer;
this.windFixEventDeserializer = windFixEventDeserializer;
this.deviceCompetitorMappingEventDeserializer = deviceCompetitorMappingEventDeserializer;
this.deviceMarkMappingEventDeserializer = deviceMarkMappingEventDeserializer;
this.denoteForTrackingEventDeserializer = denoteForTrackingEventDeserializer;
this.createRaceEventDeserializer = createRaceEventDeserializer;
this.revokeEventDeserializer = revokeEventDeserializer;
}
protected JsonDeserializer<RaceLogEvent> getDeserializer(JSONObject object) throws JsonDeserializationException {
@@ -127,6 +164,16 @@ public class RaceLogEventDeserializer implements JsonDeserializer<RaceLogEvent>
return protestStartTimeEventDeserializer;
} else if (type.equals(RaceLogWindFixEventSerializer.VALUE_CLASS)) {
return windFixEventDeserializer;
} else if (type.equals(RaceLogDeviceCompetitorMappingEventSerializer.VALUE_CLASS)) {
return deviceCompetitorMappingEventDeserializer;
} else if (type.equals(RaceLogDeviceMarkMappingEventSerializer.VALUE_CLASS)) {
return deviceMarkMappingEventDeserializer;
} else if (type.equals(RaceLogDenoteForTrackingEventSerializer.VALUE_CLASS)) {
return denoteForTrackingEventDeserializer;
} else if (type.equals(RaceLogCreateRaceEventSerializer.VALUE_CLASS)) {
return createRaceEventDeserializer;
} else if (type.equals(RaceLogRevokeEventSerializer.VALUE_CLASS)) {
return revokeEventDeserializer;
}
throw new JsonDeserializationException(String.format("There is no deserializer defined for event type %s.",
@@ -0,0 +1,30 @@
package com.sap.sailing.server.gateway.deserialization.racelog.impl;
import java.io.Serializable;
import java.util.List;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
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;
public class RaceLogRevokeEventDeserializer extends BaseRaceLogEventDeserializer {
public RaceLogRevokeEventDeserializer(JsonDeserializer<Competitor> competitorDeserializer) {
super(competitorDeserializer);
}
@Override
protected RaceLogEvent deserialize(JSONObject object, Serializable id, TimePoint createdAt, RaceLogEventAuthor author, TimePoint timePoint, int passId, List<Competitor> competitors)
throws JsonDeserializationException {
Serializable revokedEventId = Helpers.tryUuidConversion(
(Serializable) object.get(RaceLogRevokeEventSerializer.FIELD_REVOKED_EVENT_ID));
return factory.createRevokeEvent(createdAt, author, timePoint, id, passId, revokedEventId);
}
}
@@ -0,0 +1,27 @@
package com.sap.sailing.server.gateway.serialization.devices;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.devices.DeviceIdentifier;
import com.sap.sailing.domain.devices.SmartphoneImeiIdentifier;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.impl.SmartphoneImeiIdentifierJsonDeserializer;
import com.sap.sailing.server.gateway.serialization.impl.SmartphoneImeiIdentifierJsonSerializer;
public class SmartphoneImeiJsonSerializationHandler implements DeviceIdentifierJsonSerializationHandler {
private final SmartphoneImeiIdentifierJsonSerializer serializer = new SmartphoneImeiIdentifierJsonSerializer();
private final SmartphoneImeiIdentifierJsonDeserializer deserializer = new SmartphoneImeiIdentifierJsonDeserializer();
@Override
public JSONObject serialize(DeviceIdentifier object)
throws IllegalArgumentException {
return serializer.serialize((SmartphoneImeiIdentifier) object);
}
@Override
public DeviceIdentifier deserialize(JSONObject json)
throws JsonDeserializationException {
return deserializer.deserialize(json);
}
}
@@ -0,0 +1,20 @@
package com.sap.sailing.server.gateway.serialization.racelog.impl;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.racelog.tracking.CreateRaceEvent;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
public class RaceLogCreateRaceEventSerializer extends BaseRaceLogEventSerializer {
public static final String VALUE_CLASS = CreateRaceEvent.class.getSimpleName();
public RaceLogCreateRaceEventSerializer(
JsonSerializer<Competitor> competitorSerializer) {
super(competitorSerializer);
}
@Override
protected String getClassFieldValue() {
return VALUE_CLASS;
}
}
@@ -0,0 +1,36 @@
package com.sap.sailing.server.gateway.serialization.racelog.impl;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.tracking.DenoteForTrackingEvent;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
public class RaceLogDenoteForTrackingEventSerializer extends BaseRaceLogEventSerializer {
public static final String VALUE_CLASS = DenoteForTrackingEvent.class.getSimpleName();
public static final String FIELD_RACE_NAME = "raceName";
public static final String FIELD_BOAT_CLASS = "boatClass";
public RaceLogDenoteForTrackingEventSerializer(
JsonSerializer<Competitor> competitorSerializer) {
super(competitorSerializer);
}
@Override
protected String getClassFieldValue() {
return VALUE_CLASS;
}
@Override
public JSONObject serialize(RaceLogEvent object) {
DenoteForTrackingEvent event = (DenoteForTrackingEvent) object;
JSONObject result = super.serialize(event);
result.put(FIELD_RACE_NAME, event.getRaceName());
result.put(FIELD_BOAT_CLASS, event.getBoatClass().getName());
return result;
}
}
@@ -0,0 +1,22 @@
package com.sap.sailing.server.gateway.serialization.racelog.impl;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.devices.TypeBasedServiceFinder;
import com.sap.sailing.domain.racelog.tracking.DeviceCompetitorMappingEvent;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
import com.sap.sailing.server.gateway.serialization.devices.DeviceIdentifierJsonSerializationHandler;
public class RaceLogDeviceCompetitorMappingEventSerializer extends RaceLogDeviceMappingEventSerializer<Competitor> {
public static final String VALUE_CLASS = DeviceCompetitorMappingEvent.class.getSimpleName();
public RaceLogDeviceCompetitorMappingEventSerializer(
JsonSerializer<Competitor> competitorSerializer,
TypeBasedServiceFinder<DeviceIdentifierJsonSerializationHandler> deviceServiceFinder) {
super(competitorSerializer, deviceServiceFinder);
}
@Override
protected String getClassFieldValue() {
return VALUE_CLASS;
}
}
@@ -0,0 +1,39 @@
package com.sap.sailing.server.gateway.serialization.racelog.impl;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.WithID;
import com.sap.sailing.domain.devices.TypeBasedServiceFinder;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceMappingEvent;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
import com.sap.sailing.server.gateway.serialization.devices.DeviceIdentifierJsonSerializationHandler;
public abstract class RaceLogDeviceMappingEventSerializer<ItemT extends WithID> extends BaseRaceLogEventSerializer {
private final TypeBasedServiceFinder<DeviceIdentifierJsonSerializationHandler> deviceServiceFinder;
public static final String FIELD_ITEM = "item";
public static final String FIELD_DEVICE_ID = "deviceId";
public static final String FIELD_DEVICE_TYPE = "deviceType";
public static final String FIELD_FROM_MILLIS = "fromMillis";
public static final String FIELD_TO_MILLIS = "toMillis";
public RaceLogDeviceMappingEventSerializer(JsonSerializer<Competitor> competitorSerializer,
TypeBasedServiceFinder<DeviceIdentifierJsonSerializationHandler> deviceServiceFinder) {
super(competitorSerializer);
this.deviceServiceFinder = deviceServiceFinder;
}
@Override
public JSONObject serialize(RaceLogEvent object) {
@SuppressWarnings("unchecked")
DeviceMappingEvent<ItemT> event = (DeviceMappingEvent<ItemT>) object;
JSONObject result = super.serialize(event);
String deviceType = event.getDevice().getIdentifierType();
result.put(FIELD_ITEM, event.getMappedTo().getId());
result.put(FIELD_DEVICE_TYPE, deviceType);
result.put(FIELD_DEVICE_ID, deviceServiceFinder.findService(deviceType).serialize(event.getDevice()));
return result;
}
}
@@ -0,0 +1,22 @@
package com.sap.sailing.server.gateway.serialization.racelog.impl;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.devices.TypeBasedServiceFinder;
import com.sap.sailing.domain.racelog.tracking.DeviceMarkMappingEvent;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
import com.sap.sailing.server.gateway.serialization.devices.DeviceIdentifierJsonSerializationHandler;
public class RaceLogDeviceMarkMappingEventSerializer extends RaceLogDeviceMappingEventSerializer<Competitor> {
public static final String VALUE_CLASS = DeviceMarkMappingEvent.class.getSimpleName();
public RaceLogDeviceMarkMappingEventSerializer(
JsonSerializer<Competitor> competitorSerializer,
TypeBasedServiceFinder<DeviceIdentifierJsonSerializationHandler> deviceServiceFinder) {
super(competitorSerializer, deviceServiceFinder);
}
@Override
protected String getClassFieldValue() {
return VALUE_CLASS;
}
}
@@ -3,6 +3,9 @@ package com.sap.sailing.server.gateway.serialization.racelog.impl;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.devices.SingleTypeBasedServiceFinderImpl;
import com.sap.sailing.domain.devices.SmartphoneImeiIdentifier;
import com.sap.sailing.domain.devices.TypeBasedServiceFinder;
import com.sap.sailing.domain.racelog.RaceLogCourseAreaChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogCourseDesignChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogEvent;
@@ -18,18 +21,30 @@ import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.racelog.RaceLogStartProcedureChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
import com.sap.sailing.domain.racelog.tracking.CreateRaceEvent;
import com.sap.sailing.domain.racelog.tracking.DenoteForTrackingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceCompetitorMappingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceMarkMappingEvent;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
import com.sap.sailing.server.gateway.serialization.coursedata.impl.ControlPointJsonSerializer;
import com.sap.sailing.server.gateway.serialization.coursedata.impl.CourseBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.coursedata.impl.GateJsonSerializer;
import com.sap.sailing.server.gateway.serialization.coursedata.impl.MarkJsonSerializer;
import com.sap.sailing.server.gateway.serialization.coursedata.impl.WaypointJsonSerializer;
import com.sap.sailing.server.gateway.serialization.devices.DeviceIdentifierJsonSerializationHandler;
import com.sap.sailing.server.gateway.serialization.devices.SmartphoneImeiJsonSerializationHandler;
import com.sap.sailing.server.gateway.serialization.impl.PositionJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.WindJsonSerializer;
public class RaceLogEventSerializer implements JsonSerializer<RaceLogEvent>, RaceLogEventVisitor {
public static JsonSerializer<RaceLogEvent> create(JsonSerializer<Competitor> competitorSerializer) {
public static JsonSerializer<RaceLogEvent> create(JsonSerializer<Competitor> competitorSerializer) {
return create(competitorSerializer,
new SingleTypeBasedServiceFinderImpl<DeviceIdentifierJsonSerializationHandler>(
new SmartphoneImeiJsonSerializationHandler(), SmartphoneImeiIdentifier.TYPE));
}
public static JsonSerializer<RaceLogEvent> create(JsonSerializer<Competitor> competitorSerializer,
TypeBasedServiceFinder<DeviceIdentifierJsonSerializationHandler> deviceServiceFinder) {
return new RaceLogEventSerializer(
new RaceLogFlagEventSerializer(competitorSerializer),
new RaceLogStartTimeEventSerializer(competitorSerializer),
@@ -50,7 +65,12 @@ public class RaceLogEventSerializer implements JsonSerializer<RaceLogEvent>, Rac
new RaceLogProtestStartTimeEventSerializer(competitorSerializer),
new RaceLogWindFixEventSerializer(competitorSerializer,
new WindJsonSerializer(
new PositionJsonSerializer())));
new PositionJsonSerializer())),
new RaceLogDeviceCompetitorMappingEventSerializer(competitorSerializer, deviceServiceFinder),
new RaceLogDeviceMarkMappingEventSerializer(competitorSerializer, deviceServiceFinder),
new RaceLogDenoteForTrackingEventSerializer(competitorSerializer),
new RaceLogCreateRaceEventSerializer(competitorSerializer),
new RaceLogRevokeEventSerializer(competitorSerializer));
}
private final JsonSerializer<RaceLogEvent> flagEventSerializer;
@@ -66,6 +86,11 @@ public class RaceLogEventSerializer implements JsonSerializer<RaceLogEvent>, Rac
private final JsonSerializer<RaceLogEvent> startProcedureChangedEventSerializer;
private final JsonSerializer<RaceLogEvent> protestStartTimeEventSerializer;
private final JsonSerializer<RaceLogEvent> windFixEventSerializer;
private final JsonSerializer<RaceLogEvent> deviceCompetitorMappingSerializer;
private final JsonSerializer<RaceLogEvent> deviceMarkMappingSerializer;
private final JsonSerializer<RaceLogEvent> denoteForTrackingSerializer;
private final JsonSerializer<RaceLogEvent> createRaceSerializer;
private final JsonSerializer<RaceLogEvent> revokeSerializer;
private JsonSerializer<RaceLogEvent> chosenSerializer;
@@ -82,7 +107,12 @@ public class RaceLogEventSerializer implements JsonSerializer<RaceLogEvent>, Rac
JsonSerializer<RaceLogEvent> gateLineOpeningTimeEventSerializer,
JsonSerializer<RaceLogEvent> startProcedureChangedEventSerializer,
JsonSerializer<RaceLogEvent> protestStartTimeEventSerializer,
JsonSerializer<RaceLogEvent> windFixEventSerializer) {
JsonSerializer<RaceLogEvent> windFixEventSerializer,
JsonSerializer<RaceLogEvent> deviceCompetitorMappingSerializer,
JsonSerializer<RaceLogEvent> deviceMarkMappingSerializer,
JsonSerializer<RaceLogEvent> denoteForTrackingSerializer,
JsonSerializer<RaceLogEvent> createRaceSerializer,
JsonSerializer<RaceLogEvent> revokeSerializer) {
this.flagEventSerializer = flagEventSerializer;
this.startTimeSerializer = startTimeSerializer;
this.raceStatusSerializer = raceStatusSerializer;
@@ -96,6 +126,11 @@ public class RaceLogEventSerializer implements JsonSerializer<RaceLogEvent>, Rac
this.startProcedureChangedEventSerializer = startProcedureChangedEventSerializer;
this.protestStartTimeEventSerializer = protestStartTimeEventSerializer;
this.windFixEventSerializer = windFixEventSerializer;
this.deviceCompetitorMappingSerializer = deviceCompetitorMappingSerializer;
this.deviceMarkMappingSerializer = deviceMarkMappingSerializer;
this.denoteForTrackingSerializer = denoteForTrackingSerializer;
this.createRaceSerializer = createRaceSerializer;
this.revokeSerializer = revokeSerializer;
this.chosenSerializer = null;
}
@@ -180,5 +215,28 @@ public class RaceLogEventSerializer implements JsonSerializer<RaceLogEvent>, Rac
public void visit(RaceLogWindFixEvent event) {
chosenSerializer = windFixEventSerializer;
}
@Override
public void visit(DeviceCompetitorMappingEvent event) {
chosenSerializer = deviceCompetitorMappingSerializer;
}
@Override
public void visit(DeviceMarkMappingEvent event) {
chosenSerializer = deviceMarkMappingSerializer;
}
@Override
public void visit(DenoteForTrackingEvent event) {
chosenSerializer = denoteForTrackingSerializer;
}
@Override
public void visit(CreateRaceEvent event) {
chosenSerializer = createRaceSerializer;
}
@Override
public void visit(RevokeEvent event) {
chosenSerializer = revokeSerializer;
}
}
@@ -0,0 +1,34 @@
package com.sap.sailing.server.gateway.serialization.racelog.impl;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
public class RaceLogRevokeEventSerializer extends BaseRaceLogEventSerializer {
public static final String VALUE_CLASS = RevokeEvent.class.getSimpleName();
public static final String FIELD_REVOKED_EVENT_ID = "revokedEventId";
public RaceLogRevokeEventSerializer(
JsonSerializer<Competitor> competitorSerializer) {
super(competitorSerializer);
}
@Override
protected String getClassFieldValue() {
return VALUE_CLASS;
}
@Override
public JSONObject serialize(RaceLogEvent object) {
RevokeEvent event = (RevokeEvent) object;
JSONObject result = super.serialize(event);
result.put(FIELD_REVOKED_EVENT_ID, event.getRevokedEventId().toString());
return result;
}
}