bridged the gap between device mapping events where "to" is inclusive, and TimeRange, where "to" is exclusive; TimePoint.plus|minus no longer wraps around but bumps

Change-Id: I97f30deb38d83872879c33971616bfcf18a5469a
This commit is contained in:
Axel Uhl committed 2016-12-23 23:10:05 +01:00
1 parent da9e5d20b3
commit d4479a3bc1
17 files changed
+121 -46

No files matched your search

@@ -7,7 +7,7 @@ import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
import com.sap.sse.common.TimePoint;
/**
* Closes the time range of a {@link RegattaLogDeviceMappingEvent}. This means that the {@link #getClosingTimePoint() timepoint} provided
* Closes the time range of a {@link RegattaLogDeviceMappingEvent}. This means that the {@link #getClosingTimePointInclusive() timepoint} provided
* by this event is substituted for the missing timepoint in the {@code DeviceMappingEvent} it refers to.
* @author Fredrik Teschke
*
@@ -15,8 +15,10 @@ import com.sap.sse.common.TimePoint;
public interface RegattaLogCloseOpenEndedDeviceMappingEvent extends RegattaLogEvent, Revokable {
/**
* Returns the timepoint that shall substitute the missing one in the corresponding {@link RegattaLogDeviceMappingEvent}.
* As with {@link RegattaLogDeviceMappingEvent#getToInclusive()}, this time point marks the <em>inclusive</em> end
* of the interval.
*/
TimePoint getClosingTimePoint();
TimePoint getClosingTimePointInclusive();
/**
* Returns the {@code id} of the event for which this event provides the closing timepoint.
@@ -9,15 +9,16 @@ import com.sap.sailing.domain.base.Mark;
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;
/**
* Event type for mapping {@link DeviceIdentifier devices} to {@code items} ({@link Competitor competitors} or {@link Mark marks}).
* <p>
* Not both {@link #getFrom()} and {@link #getTo()} may be {@code null} at the same time (which would be a mapping for "all times",
* Not both {@link #getFrom()} and {@link #getToInclusive()} may be {@code null} at the same time (which would be a mapping for "all times",
* as the semantics of somehow later limiting this range would become unclear
* <p>
* If one end of the time range enclosed by {@link #getFrom()} and {@link #getTo()} is open, this can be closed
* If one end of the time range enclosed by {@link #getFrom()} and {@link #getToInclusive()} is open, this can be closed
* by a {@link RegattaLogCloseOpenEndedDeviceMappingEvent}.
*
* @see RegattaLogDefinedMarkAnalyzer for rules by which {@link DeviceMapping}s are derived from these events.
@@ -29,15 +30,19 @@ public interface RegattaLogDeviceMappingEvent<ItemType extends WithID> extends R
/**
* The {@code return} value may be {@code null}, symbolizing an open range.
* In that case the device should be mapped to the item for any timepoint before that specified by {@link #getTo()}.
* In that case the device should be mapped to the item for any timepoint before that specified by {@link #getToInclusive()}.
*/
TimePoint getFrom();
/**
* The {@code return} value may be {@code null}, symbolizing an open range.
* In that case the device should be mapped to the item for any timepoint after that specified by {@link #getFrom()}.
* Otherwise, this marks the <em>inclusive</em> end of the interval, other than the {@link TimeRange#to()} semantics which
* uses an <em>exclusive</em> interval end. To bridge this gap, whenever mapping this event's from/to interval to a
* {@link TimeRange}, at least the resolution of the {@link TimePoint} representation must be added to the result of
* this method to make it into a valid end of a {@link TimeRange} that includes the time interval covered by this mapping.
*/
TimePoint getTo();
TimePoint getToInclusive();
/**
* Visitor patter implementation for event mapping handling differentiation.
@@ -15,23 +15,35 @@ RegattaLogDeviceMappingEvent<ItemType> {
private final ItemType mappedTo;
private final DeviceIdentifier device;
/**
* inclusive start time point
*/
private final TimePoint from;
private final TimePoint to;
/**
* inclusive end time point
*/
private final TimePoint toInclusive;
/**
* @param from inclusive
* @param toInclusive inclusive
*/
public RegattaLogDeviceMappingEventImpl(TimePoint createdAt, TimePoint logicalTimePoint,
AbstractLogEventAuthor author, Serializable id, ItemType mappedTo,
DeviceIdentifier device, TimePoint from, TimePoint to) {
DeviceIdentifier device, TimePoint from, TimePoint toInclusive) {
super(createdAt, logicalTimePoint, author, id);
this.mappedTo = mappedTo;
this.device = device;
this.from = from;
this.to = to;
this.toInclusive = toInclusive;
}
public RegattaLogDeviceMappingEventImpl(TimePoint logicalTimePoint,
AbstractLogEventAuthor author, ItemType mappedTo,
DeviceIdentifier device, TimePoint from, TimePoint to) {
this(now(), logicalTimePoint, author, randId(), mappedTo, device, from, to);
DeviceIdentifier device, TimePoint from, TimePoint toInclusive) {
this(now(), logicalTimePoint, author, randId(), mappedTo, device, from, toInclusive);
}
public ItemType getMappedTo() {
@@ -43,12 +55,12 @@ RegattaLogDeviceMappingEvent<ItemType> {
public TimePoint getFrom() {
return from;
}
public TimePoint getTo() {
return to;
public TimePoint getToInclusive() {
return toInclusive;
}
@Override
public String getShortInfo() {
return "device: " + device + ", mapped to: " + mappedTo + ", from: " + from + ", to: " + to;
return "device: " + device + ", mapped to: " + mappedTo + ", from: " + from + ", to: " + toInclusive;
}
}
@@ -33,7 +33,7 @@ public class RegattaLogCloseOpenEndedDeviceMappingEventImpl extends AbstractLogE
}
@Override
public TimePoint getClosingTimePoint() {
public TimePoint getClosingTimePointInclusive() {
return closingTimePoint;
}
@@ -15,13 +15,13 @@ public class RegattaLogDeviceCompetitorMappingEventImpl extends RegattaLogDevice
RegattaLogDeviceCompetitorMappingEvent {
public RegattaLogDeviceCompetitorMappingEventImpl(TimePoint createdAt, TimePoint logicalTimePoint,
AbstractLogEventAuthor author, Serializable pId, Competitor mappedTo, DeviceIdentifier device,
TimePoint from, TimePoint to) {
super(createdAt, logicalTimePoint, author, pId, mappedTo, device, from, to);
TimePoint from, TimePoint toInclusive) {
super(createdAt, logicalTimePoint, author, pId, mappedTo, device, from, toInclusive);
}
public RegattaLogDeviceCompetitorMappingEventImpl(TimePoint logicalTimePoint, AbstractLogEventAuthor author,
Competitor mappedTo, DeviceIdentifier device, TimePoint from, TimePoint to) {
super(logicalTimePoint, author, mappedTo, device, from, to);
Competitor mappedTo, DeviceIdentifier device, TimePoint from, TimePoint toInclusive) {
super(logicalTimePoint, author, mappedTo, device, from, toInclusive);
}
private static final long serialVersionUID = -1494030544804758753L;
@@ -51,8 +51,8 @@ public abstract class BaseRegattaLogDeviceMappingFinder<ItemT extends WithID>
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);
final TimePoint toInclusive = closingEvent != null ? closingEvent.getClosingTimePointInclusive() : event.getToInclusive();
final TimeRange mappingTimeRange = new TimeRangeImpl(from, toInclusive.plus(1) /* convert from inclusive to exclusive end */);
if (mappingTimeRange.includes(fixTimePoint)) {
if (closingEvent != null) {
log.revokeEvent(closingEvent.getAuthor(), closingEvent,
@@ -65,8 +65,8 @@ public abstract class BaseRegattaLogDeviceMappingFinder<ItemT extends WithID>
if (!endOfFirstHalf.before(from)) {
log.add(createDeviceMappingEvent(item, event.getAuthor(), from, endOfFirstHalf, event.getDevice()));
}
if (to == null || !to.before(startOfSecondHalf)) {
log.add(createDeviceMappingEvent(item, event.getAuthor(), startOfSecondHalf, to,
if (toInclusive == null || !toInclusive.before(startOfSecondHalf)) {
log.add(createDeviceMappingEvent(item, event.getAuthor(), startOfSecondHalf, toInclusive,
event.getDevice()));
}
}
@@ -74,6 +74,6 @@ public abstract class BaseRegattaLogDeviceMappingFinder<ItemT extends WithID>
}
protected abstract RegattaLogDeviceMappingEvent<ItemT> createDeviceMappingEvent(ItemT item,
AbstractLogEventAuthor author, TimePoint plus, TimePoint to, DeviceIdentifier deviceId);
AbstractLogEventAuthor author, TimePoint plus, TimePoint toInclusive, DeviceIdentifier deviceId);
}
@@ -25,8 +25,8 @@ public class RegattaLogDeviceCompetitorMappingFinder extends BaseRegattaLogDevic
@Override
protected RegattaLogDeviceCompetitorMappingEvent createDeviceMappingEvent(Competitor item, AbstractLogEventAuthor author,
TimePoint from, TimePoint to, DeviceIdentifier deviceId) {
TimePoint from, TimePoint toInclusive, DeviceIdentifier deviceId) {
final TimePoint now = MillisecondsTimePoint.now();
return new RegattaLogDeviceCompetitorMappingEventImpl(now, now, author, UUID.randomUUID(), item, deviceId, from, to);
return new RegattaLogDeviceCompetitorMappingEventImpl(now, now, author, UUID.randomUUID(), item, deviceId, from, toInclusive);
}
}
@@ -48,8 +48,8 @@ public class RegattaLogDeviceMappingFinder<ItemT extends WithID>
}
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),
TimePoint from, TimePoint toInclusive, Serializable originalEventId, RegattaLogDeviceMappingEvent<ItemT> event) {
return new DeviceMappingWithRegattaLogEventImpl<ItemT>(item, device, new TimeRangeImpl(from, toInclusive.plus(1) /* TimeRange uses exclusive end */),
Collections.singletonList(originalEventId), event);
}
@@ -95,16 +95,16 @@ public class RegattaLogDeviceMappingFinder<ItemT extends WithID>
List<DeviceMappingWithRegattaLogEvent<ItemT>> result = new ArrayList<>();
for (final RegattaLogDeviceMappingEvent<ItemT> event : events) {
TimePoint from = event.getFrom();
TimePoint to = event.getTo();
TimePoint toInclusive = event.getToInclusive();
TimePoint closingTimePoint = closingEvents.containsKey(event.getId()) ? closingEvents.get(event.getId())
.getClosingTimePoint() : null;
.getClosingTimePointInclusive() : null;
if (from == null) {
logger.severe("No start time set for DeviceMappingEvent with ID: " + event.getId());
}
if (to == null) {
to = closingTimePoint;
if (toInclusive == null) {
toInclusive = closingTimePoint;
}
result.add(createMapping(event.getDevice(), item, from, to, event.getId(), event));
result.add(createMapping(event.getDevice(), item, from, toInclusive, event.getId(), event));
}
return result;
}
@@ -46,7 +46,7 @@ public class RegattaLogOpenEndedDeviceMappingCloser extends
for (Serializable eventId : mapping.getOriginalRaceLogEventIds()) {
RegattaLogDeviceMappingEvent<?> event = (RegattaLogDeviceMappingEvent<?>) getLog().getEventById(eventId);
if (event.getFrom() == null || event.getTo() == null) {
if (event.getFrom() == null || event.getToInclusive() == null) {
result.add(createCloseEvent(MillisecondsTimePoint.now(), event.getId()));
}
}
@@ -66,7 +66,8 @@ public class DeviceMappingImpl<ItemType extends WithID> implements DeviceMapping
}
public static <T extends WithID> DeviceMapping<T> convertToDeviceMapping(RegattaLogDeviceMappingEvent<T> event) {
return new DeviceMappingImpl<T>(event.getMappedTo(), event.getDevice(), new TimeRangeImpl(event.getFrom(), event.getTo()),
return new DeviceMappingImpl<T>(event.getMappedTo(), event.getDevice(),
new TimeRangeImpl(event.getFrom(), event.getToInclusive().plus(1) /* TimeRange uses exclusive end */),
event.getId(), event.getClass());
}