Adjusted handling of the initially available mappings for marks to fix

bug 4008
This commit is contained in:
Steffen Schaefer committed 2016-12-21 15:48:58 +01:00
1 parent 386c25fbe3
commit cb0b10a7e1
2 files changed
+57 -16

No files matched your search

@@ -1,5 +1,6 @@
package com.sap.sailing.domain.racelogtracking.impl.fixtracker;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
@@ -160,6 +161,51 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
startTracking();
}
private void loadFixesForNewMappings(List<DeviceMappingWithRegattaLogEvent<WithID>> mappings, WithID item) {
TimeRange trackingTimeRange = getTrackingTimeRange();
if(item instanceof Mark) {
Mark mark = (Mark) item;
final boolean loadAllMappedFixes;
if(containsMappingThatIntersectsTimeRange(mappings, trackingTimeRange)) {
loadFixesInTimeRange(mappings, trackingTimeRange);
DynamicGPSFixTrack<Mark, GPSFix> track = trackedRace.getOrCreateTrack(mark);
// load all mapped fixes if there was no fix in the tracking TimeRange
loadAllMappedFixes = (track.getFirstRawFix() == null);
} else {
// There is no mapping that intersects the tracking TimeRange at all
// Loading all mapped fixes instead
loadAllMappedFixes = true;
}
if(loadAllMappedFixes) {
// either got an empty track of there is no mapping for the TimeRange of the race at all.
// try again without constraining the mapping interval by start/end of tracking to at
// least attempt to get fixes at all in case there were any within the device mapping interval specified
mappings.forEach(mapping -> loadFixes(mapping.getTimeRange(), mapping));
}
} else {
loadFixesInTimeRange(mappings, trackingTimeRange);
}
}
private void loadFixesInTimeRange(List<DeviceMappingWithRegattaLogEvent<WithID>> mappings, TimeRange trackingTimeRange) {
mappings.forEach(mapping -> loadFixes(trackingTimeRange.intersection(mapping.getTimeRange()), mapping));
}
/**
* Calls the given callback for every known mapping of the given item.
*
* @param callback the callback to call for every known mapping
*/
public boolean containsMappingThatIntersectsTimeRange(List<DeviceMappingWithRegattaLogEvent<WithID>> mappings, TimeRange timeRange) {
for (DeviceMappingWithRegattaLogEvent<WithID> mapping : mappings) {
if(timeRange.intersects(mapping.getTimeRange())) {
return true;
}
}
return false;
}
private void loadFixes(TimeRange timeRangeToLoad, DeviceMappingWithRegattaLogEvent<? extends WithID> mapping) {
if(timeRangeToLoad == null) {
return;
@@ -211,16 +257,8 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
try {
@SuppressWarnings("unchecked")
DeviceMapping<Mark> markMapping = (DeviceMapping<Mark>) mapping;
gpsFixStore.loadMarkTrack(track, markMapping, timeRangeToLoad.from(), timeRangeToLoad.to());
if (track.getFirstRawFix() == null) {
logger.fine("Loading mark positions from outside of start/end of tracking interval (" + timeRangeToLoad.from()
+ ".." + timeRangeToLoad.to() + ") because no fixes were found in that interval");
// got an empty track for the mark; try again without constraining the mapping interval
// by start/end of tracking to at least attempt to get fixes at all in case there were any
// within the device mapping interval specified
gpsFixStore.loadMarkTrack(track, markMapping, /* startOfTimeWindowToLoad */ null,
/* endOfTimeWindowToLoad */ null);
}
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
logger.log(Level.WARNING, "Could not load mark track " + mapping.getMappedTo());
}
@@ -355,10 +393,10 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
}
@Override
protected void mappingAdded(DeviceMappingWithRegattaLogEvent<WithID> mapping) {
protected void mappingsAdded(List<DeviceMappingWithRegattaLogEvent<WithID>> mappings, WithID item) {
// The listener is first added to not lose any fix after loading the initial fixes and adding the listener.
sensorFixStore.addListener(listener, mapping.getDevice());
loadFixes(getTrackingTimeRange().intersection(mapping.getTimeRange()), mapping);
mappings.forEach(mapping -> sensorFixStore.addListener(listener, mapping.getDevice()));
loadFixesForNewMappings(mappings, item);
}
@Override
@@ -277,15 +277,17 @@ public abstract class RegattaLogDeviceMappings<ItemT extends WithID> {
final List<DeviceMappingWithRegattaLogEvent<ItemT>> oldMappings = previousMappings.containsKey(item)
? previousMappings.get(item) : Collections.emptyList();
final List<DeviceMappingWithRegattaLogEvent<ItemT>> addedMappings= new ArrayList<>();
for (DeviceMappingWithRegattaLogEvent<ItemT> newMapping : newMappings.get(item)) {
DeviceMappingWithRegattaLogEvent<ItemT> oldMapping = findAndRemoveMapping(newMapping,
oldMappings);
if (oldMapping == null) {
mappingAddedInternal(newMapping);
addedMappings.add(newMapping);
} else if (!newMapping.getTimeRange().equals(oldMapping.getTimeRange())) {
mappingChangedInternal(oldMapping, newMapping);
}
}
mappingsAddedInternal(addedMappings, item);
oldMappings.forEach(this::mappingRemovedInternal);
}
}
@@ -310,12 +312,13 @@ public abstract class RegattaLogDeviceMappings<ItemT extends WithID> {
* Called when a {@link DeviceMapping} was added.
*
* @param mapping the new mapping
* @param item
*/
protected abstract void mappingAdded(DeviceMappingWithRegattaLogEvent<ItemT> mapping);
protected abstract void mappingsAdded(List<DeviceMappingWithRegattaLogEvent<ItemT>> mapping, ItemT item);
private void mappingAddedInternal(DeviceMappingWithRegattaLogEvent<ItemT> mapping) {
private void mappingsAddedInternal(List<DeviceMappingWithRegattaLogEvent<ItemT>> mapping, ItemT item) {
try {
mappingAdded(mapping);
mappingsAdded(mapping, item);
} catch(Exception e) {
logger.log(Level.SEVERE, "error while adding mapping " + mapping, e);
}