Moved GPSFixTracker code to RaceLogSensorFixTracker (applied visitor pattern previously introduced)

This commit is contained in:
Papick Garcia Taboada committed 2016-06-07 16:21:17 +02:00
1 parent c98fa523d8
commit d091e2ee44
22 files changed
+484 -513

No files matched your search

@@ -0,0 +1,79 @@
package com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.TimeRange;
import com.sap.sse.common.WithID;
import com.sap.sse.common.impl.TimeRangeImpl;
/**
* Extracts the {@link DeviceMapping}s with the appropriate {@link TimeRange}s from the {@link RaceLog}.
* Based on the {@link RegattaLogDeviceMappingEvent}s found in the {@code RaceLog} for the tracked {@code items}
* ({@code Competitor}s and {@code Marks}), the actual mappings are created.
* <p>
* Mappings can be defined with an open-ended time range (e.g. track this from now on), which should then be
* closed by a corresponding {@link RegattaLogCloseOpenEndedDeviceMappingEvent}.
* <p>
* The process of removing conflicts between mappings to ensure that only one mapping was active for
* one tracked item has been removed. Instead, every {@code DeviceMappingEvent} now results directly in one
* {@code DeviceMapping}, the only changes being introduced by closing open time ranges in cases where an
* according {@code CloseOpenEndedDeviceMappingEvent} exists.
*/
public abstract class BaseRegattaLogDeviceMappingFinder<ItemT extends WithID>
extends RegattaLogDeviceMappingFinder<ItemT> {
public BaseRegattaLogDeviceMappingFinder(RegattaLog log) {
super(log);
}
/**
* By revoking existing mappings for {@code item} and replacing them by mappings that exclude {@code fixTimePoint},
* any fix at {@code fixTimePoint} will no longer be linked to {@code item}. If a mapping is limited to the exact
* fix time point, the mapping is only revoked and not replaced. If one boundary is exactly the fix time point, the
* interval is revoked and replaced by a single interval with that border adjusted so it excludes the fix.
*/
public void removeTimePointFromMapping(ItemT item, TimePoint fixTimePoint) throws NotRevokableException {
Map<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>> events = new HashMap<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>>();
Map<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent> closingEvents = new HashMap<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent>();
findUnrevokedMappingAndClosingEvents(events, closingEvents);
for (final RegattaLogDeviceMappingEvent<ItemT> event : events.get(item)) {
final TimePoint from = event.getFrom();
final RegattaLogCloseOpenEndedDeviceMappingEvent closingEvent = closingEvents.get(event.getId());
final TimePoint to = closingEvent != null ? closingEvent.getClosingTimePoint() : event.getTo();
final TimeRange mappingTimeRange = new TimeRangeImpl(from, to);
if (mappingTimeRange.includes(fixTimePoint)) {
if (closingEvent != null) {
log.revokeEvent(closingEvent.getAuthor(), closingEvent,
"removing single time point " + fixTimePoint + " from mapping for " + item);
}
log.revokeEvent(event.getAuthor(), event,
"removing single time point " + fixTimePoint + " from mapping for " + item);
final TimePoint endOfFirstHalf = fixTimePoint.minus(1);
final TimePoint startOfSecondHalf = fixTimePoint.plus(1);
if (!endOfFirstHalf.before(from)) {
log.add(createDeviceMappingEvent(item, event.getAuthor(), from, endOfFirstHalf, event.getDevice()));
}
if (!to.before(startOfSecondHalf)) {
log.add(createDeviceMappingEvent(item, event.getAuthor(), startOfSecondHalf, to,
event.getDevice()));
}
}
}
}
protected abstract RegattaLogDeviceMappingEvent<ItemT> createDeviceMappingEvent(ItemT item,
AbstractLogEventAuthor author, TimePoint plus, TimePoint to, DeviceIdentifier deviceId);
}
@@ -1,33 +0,0 @@
package com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl;
import java.util.UUID;
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorBravoMappingEventImpl;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
public class RegattaLogDeviceCompetitorBravoMappingFinder extends RegattaLogDeviceMappingFinder<Competitor> {
public RegattaLogDeviceCompetitorBravoMappingFinder(RegattaLog log) {
super(log);
}
@Override
protected boolean isValidMapping(RegattaLogDeviceMappingEvent<?> mapping) {
// TODO use more concrete type or interface to delimit valid mappings
return mapping instanceof RegattaLogDeviceCompetitorSensorDataMappingEvent;
}
@Override
protected RegattaLogDeviceCompetitorSensorDataMappingEvent createDeviceMappingEvent(Competitor item, AbstractLogEventAuthor author,
TimePoint from, TimePoint to, DeviceIdentifier deviceId) {
final TimePoint now = MillisecondsTimePoint.now();
return new RegattaLogDeviceCompetitorBravoMappingEventImpl(now, now, author, UUID.randomUUID(), item, deviceId, from, to);
}
}
@@ -12,7 +12,7 @@ import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
public class RegattaLogDeviceCompetitorMappingFinder extends RegattaLogDeviceMappingFinder<Competitor> {
public class RegattaLogDeviceCompetitorMappingFinder extends BaseRegattaLogDeviceMappingFinder<Competitor> {
public RegattaLogDeviceCompetitorMappingFinder(RegattaLog log) {
super(log);
@@ -0,0 +1,18 @@
package com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
import com.sap.sse.common.WithID;
public class RegattaLogDeviceCompetitorSensordataMappingFinder extends RegattaLogDeviceMappingFinder<WithID> {
public RegattaLogDeviceCompetitorSensordataMappingFinder(RegattaLog log) {
super(log);
}
@Override
protected boolean isValidMapping(RegattaLogDeviceMappingEvent<?> mapping) {
return mapping instanceof RegattaLogDeviceMappingEvent;
}
}
@@ -8,16 +8,15 @@ import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
import com.sap.sailing.domain.racelogtracking.impl.DeviceMappingImpl;
import com.sap.sailing.domain.racelogtracking.DeviceMappingWithRegattaLogEvent;
import com.sap.sailing.domain.racelogtracking.impl.DeviceMappingWithRegattaLogEventImpl;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.TimeRange;
import com.sap.sse.common.WithID;
@@ -36,7 +35,8 @@ import com.sap.sse.common.impl.TimeRangeImpl;
* {@code DeviceMapping}, the only changes being introduced by closing open time ranges in cases where an
* according {@code CloseOpenEndedDeviceMappingEvent} exists.
*/
public abstract class RegattaLogDeviceMappingFinder<ItemT extends WithID> extends RegattaLogAnalyzer<Map<ItemT, List<DeviceMapping<ItemT>>>> {
public abstract class RegattaLogDeviceMappingFinder<ItemT extends WithID>
extends RegattaLogAnalyzer<Map<ItemT, List<DeviceMappingWithRegattaLogEvent<ItemT>>>> {
private static Logger logger = Logger.getLogger(RegattaLogDeviceMappingFinder.class.getName());
public RegattaLogDeviceMappingFinder(RegattaLog log) {
@@ -47,10 +47,10 @@ public abstract class RegattaLogDeviceMappingFinder<ItemT extends WithID> extend
return mapping instanceof RegattaLogDeviceMappingEvent;
}
protected DeviceMapping<ItemT> createMapping(DeviceIdentifier device, ItemT item,
TimePoint from, TimePoint to, Serializable originalEventId, Class<?> type) {
return new DeviceMappingImpl<ItemT>(item, device, new TimeRangeImpl(from, to),
Collections.singletonList(originalEventId), type);
protected DeviceMappingWithRegattaLogEvent<ItemT> createMapping(DeviceIdentifier device, ItemT item,
TimePoint from, TimePoint to, Serializable originalEventId, RegattaLogDeviceMappingEvent<ItemT> event) {
return new DeviceMappingWithRegattaLogEventImpl<ItemT>(item, device, new TimeRangeImpl(from, to),
Collections.singletonList(originalEventId), event);
}
private List<RegattaLogDeviceMappingEvent<ItemT>> getMappingEventsForItem(Map<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>> map, ItemT item) {
@@ -63,18 +63,18 @@ public abstract class RegattaLogDeviceMappingFinder<ItemT extends WithID> extend
}
@Override
protected Map<ItemT, List<DeviceMapping<ItemT>>> performAnalysis() {
Map<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>> events = new HashMap<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>>();
Map<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent> closingEvents = new HashMap<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent>();
protected Map<ItemT, List<DeviceMappingWithRegattaLogEvent<ItemT>>> performAnalysis() {
Map<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>> events = new HashMap<>();
Map<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent> closingEvents = new HashMap<>();
findUnrevokedMappingAndClosingEvents(events, closingEvents);
Map<ItemT, List<DeviceMapping<ItemT>>> mappings = new HashMap<ItemT, List<DeviceMapping<ItemT>>>();
Map<ItemT, List<DeviceMappingWithRegattaLogEvent<ItemT>>> mappings = new HashMap<>();
for (ItemT item : events.keySet()) {
mappings.put(item, closeOpenRanges(events.get(item), item, closingEvents));
}
return mappings;
}
private void findUnrevokedMappingAndClosingEvents(Map<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>> events,
protected void findUnrevokedMappingAndClosingEvents(Map<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>> events,
Map<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent> closingEvents) {
for (RegattaLogEvent e : getLog().getUnrevokedEvents()) {
if (e instanceof RegattaLogDeviceMappingEvent && isValidMapping(((RegattaLogDeviceMappingEvent<?>) e))) {
@@ -89,9 +89,10 @@ public abstract class RegattaLogDeviceMappingFinder<ItemT extends WithID> extend
}
}
private List<DeviceMapping<ItemT>> closeOpenRanges(List<RegattaLogDeviceMappingEvent<ItemT>> events, ItemT item,
private List<DeviceMappingWithRegattaLogEvent<ItemT>> closeOpenRanges(
List<RegattaLogDeviceMappingEvent<ItemT>> events, ItemT item,
Map<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent> closingEvents) {
List<DeviceMapping<ItemT>> result = new ArrayList<DeviceMapping<ItemT>>();
List<DeviceMappingWithRegattaLogEvent<ItemT>> result = new ArrayList<>();
for (final RegattaLogDeviceMappingEvent<ItemT> event : events) {
TimePoint from = event.getFrom();
TimePoint to = event.getTo();
@@ -103,42 +104,9 @@ public abstract class RegattaLogDeviceMappingFinder<ItemT extends WithID> extend
if (to == null) {
to = closingTimePoint;
}
result.add(createMapping(event.getDevice(), item, from, to, event.getId(), event.getClass()));
result.add(createMapping(event.getDevice(), item, from, to, event.getId(), event));
}
return result;
}
/**
* By revoking existing mappings for {@code item} and replacing them by mappings that exclude {@code fixTimePoint}, any
* fix at {@code fixTimePoint} will no longer be linked to {@code item}. If a mapping is limited to the exact fix time point,
* the mapping is only revoked and not replaced. If one boundary is exactly the fix time point, the interval is revoked and
* replaced by a single interval with that border adjusted so it excludes the fix.
*/
public void removeTimePointFromMapping(ItemT item, TimePoint fixTimePoint) throws NotRevokableException {
Map<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>> events = new HashMap<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>>();
Map<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent> closingEvents = new HashMap<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent>();
findUnrevokedMappingAndClosingEvents(events, closingEvents);
for (final RegattaLogDeviceMappingEvent<ItemT> event : events.get(item)) {
final TimePoint from = event.getFrom();
final RegattaLogCloseOpenEndedDeviceMappingEvent closingEvent = closingEvents.get(event.getId());
final TimePoint to = closingEvent!= null ? closingEvent.getClosingTimePoint() : event.getTo();
final TimeRange mappingTimeRange = new TimeRangeImpl(from, to);
if (mappingTimeRange.includes(fixTimePoint)) {
if (closingEvent != null) {
log.revokeEvent(closingEvent.getAuthor(), closingEvent, "removing single time point "+fixTimePoint+" from mapping for "+item);
}
log.revokeEvent(event.getAuthor(), event, "removing single time point "+fixTimePoint+" from mapping for "+item);
final TimePoint endOfFirstHalf = fixTimePoint.minus(1);
final TimePoint startOfSecondHalf = fixTimePoint.plus(1);
if (!endOfFirstHalf.before(from)) {
log.add(createDeviceMappingEvent(item, event.getAuthor(), from, endOfFirstHalf, event.getDevice()));
}
if (!to.before(startOfSecondHalf)) {
log.add(createDeviceMappingEvent(item, event.getAuthor(), startOfSecondHalf, to, event.getDevice()));
}
}
}
}
protected abstract RegattaLogDeviceMappingEvent<ItemT> createDeviceMappingEvent(ItemT item, AbstractLogEventAuthor author, TimePoint plus, TimePoint to, DeviceIdentifier deviceId);
}
@@ -12,7 +12,7 @@ import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
public class RegattaLogDeviceMarkMappingFinder extends RegattaLogDeviceMappingFinder<Mark> {
public class RegattaLogDeviceMarkMappingFinder extends BaseRegattaLogDeviceMappingFinder<Mark> {
public RegattaLogDeviceMarkMappingFinder(RegattaLog log) {
super(log);
@@ -0,0 +1,20 @@
package com.sap.sailing.domain.racelogtracking;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
import com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl.RegattaLogDeviceMappingFinder;
import com.sap.sse.common.TimeRange;
import com.sap.sse.common.Timed;
import com.sap.sse.common.WithID;
/**
* @see RegattaLogDeviceMappingFinder {@code DeviceMappings} are derived from {@code DeviceMappingEvents}. The
* {@link Timed} interface is to be implemented as providing the {@link TimeRange#from()} time point as the answer
* to {@link Timed#getTimePoint()}.
*
* This instance provides access to the originating event.
*
*/
public interface DeviceMappingWithRegattaLogEvent<ItemType extends WithID> extends DeviceMapping<ItemType> {
RegattaLogDeviceMappingEvent<ItemType> getRegattaLogEvent();
}
@@ -0,0 +1,34 @@
package com.sap.sailing.domain.racelogtracking.impl;
import java.io.Serializable;
import java.util.List;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.domain.racelogtracking.DeviceMappingWithRegattaLogEvent;
import com.sap.sse.common.TimeRange;
import com.sap.sse.common.WithID;
public class DeviceMappingWithRegattaLogEventImpl<ItemType extends WithID> extends DeviceMappingImpl<ItemType>
implements DeviceMappingWithRegattaLogEvent<ItemType> {
private static final long serialVersionUID = 1495968054831506408L;
private final RegattaLogDeviceMappingEvent<ItemType> event;
public DeviceMappingWithRegattaLogEventImpl(ItemType mappedTo, DeviceIdentifier device, TimeRange timeRange,
RegattaLogDeviceMappingEvent<ItemType> event) {
super(mappedTo, device, timeRange, event.getClass());
this.event = event;
}
public DeviceMappingWithRegattaLogEventImpl(ItemType mappedTo, DeviceIdentifier device, TimeRange timeRange,
List<Serializable> originalRaceLogEventIds, RegattaLogDeviceMappingEvent<ItemType> event) {
super(mappedTo, device, timeRange, originalRaceLogEventIds, event.getClass());
this.event = event;
}
@Override
public RegattaLogDeviceMappingEvent<ItemType> getRegattaLogEvent() {
return event;
}
}