fix for bug4040: computing update for storedURI/liveURI already in TracTrac connectivity params, keeping tracker ID and params ID equal

Change-Id: I8f86770286332a5198ab2ba57b83a52c67759008
This commit is contained in:
Axel Uhl committed 2017-01-26 11:55:46 +01:00
1 parent 8866211749
commit 9a8df602b4
10 files changed
+139 -263

No files matched your search

@@ -124,55 +124,21 @@ public interface DomainFactory {
* respond with the {@link RaceDefinition} when its {@link DomainFactory#getRaceID(IRace)} is called with the
* TracTrac {@link IEvent} as argument that is used for its tracking.
* <p>
*
* @param startOfTracking
* if <code>null</code>, all stored data from the "beginning of time" will be loaded that the event has
* to provide, particularly for the mark positions which are stored per event, not per race; otherwise,
* particularly the mark position loading will be constrained to this start time.
* @param endOfTracking
* if <code>null</code>, all stored data until the "end of time" will be loaded that the event has to
* provide, particularly for the mark positions which are stored per event, not per race; otherwise,
* particularly the mark position loading will be constrained to this end time.
* @param offsetToStartTimeOfSimulatedRace
* if non-<code>null</code>, the {@link Simulator} will be used with this duration as start offset
* @param windStore
* Provides the capability to obtain the {@link WindTrack}s for the different wind sources. A trivial
* implementation is {@link EmptyWindStore} which simply provides new, empty tracks. This is always
* available but loses track of the wind, e.g., during server restarts.
* @param preferReplayIfAvailable
* when a non-{@code null} {@code storedURI} and/or {@code liveURI} are provided and the {@link IRace}
* specifies something different and claims to be in replay mode ({@link IRace#getConnectionType} is
* {@code File}) then if this parameter is {@code true} the race will be loaded from the replay file
* instead of the {@code storedURI}/{@code liveURI} specified. This is particularly useful for restoring
* races if since the last connection the race was migrated to a replay file format.
*/
TracTracRaceTracker createRaceTracker(URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
WindStore windStore, String tracTracUsername, String tracTracPassword,
String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver,
RaceTrackingConnectivityParametersImpl connectivityParams, boolean preferReplayIfAvailable)
TracTracRaceTracker createRaceTracker(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore, TrackedRegattaRegistry trackedRegattaRegistry,
RaceLogResolver raceLogResolver, RaceTrackingConnectivityParametersImpl connectivityParams)
throws MalformedURLException, FileNotFoundException, URISyntaxException, CreateModelException, SubscriberInitializationException;
/**
* Same as {@link #createRaceTracker(URL, URI, URI, URI, TimePoint, TimePoint, WindStore, TrackedRegattaRegistry)},
* only that a predefined {@link Regatta} is used to hold the resulting races.
*
* @param offsetToStartTimeOfSimulatedRace
* if non-<code>null</code>, the {@link Simulator} will be used with this duration as start offset
* @param preferReplayIfAvailable
* when a non-{@code null} {@code storedURI} and/or {@code liveURI} are provided and the {@link IRace}
* specifies something different and claims to be in replay mode ({@link IRace#getConnectionType} is
* {@code File}) then if this parameter is {@code true} the race will be loaded from the replay file
* instead of the {@code storedURI}/{@code liveURI} specified. This is particularly useful for restoring
* races if since the last connection the race was migrated to a replay file format.
*/
RaceTracker createRaceTracker(Regatta regatta, URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
WindStore windStore, String tracTracUsername, String tracTracPassword,
String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver,
RaceTrackingConnectivityParametersImpl connectivityParams, boolean preferReplayIfAvailable)
RaceTracker createRaceTracker(Regatta regatta, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore, TrackedRegattaRegistry trackedRegattaRegistry,
RaceLogResolver raceLogResolver, RaceTrackingConnectivityParametersImpl connectivityParams)
throws MalformedURLException, FileNotFoundException, URISyntaxException, CreateModelException,
SubscriberInitializationException;
@@ -291,7 +257,7 @@ public interface DomainFactory {
URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility, boolean trackWind, boolean correctWindDirectionByMagneticDeclination,
boolean preferReplayIfAvailable);
boolean preferReplayIfAvailable) throws Exception;
/**
* Removes all knowledge about <code>tractracRace</code> which includes removing it from the race cache, from the
* {@link com.sap.sailing.domain.base.Regatta} and, if a {@link TrackedRace} for the corresponding
@@ -652,34 +652,19 @@ public class DomainFactoryImpl implements DomainFactory {
}
@Override
public TracTracRaceTracker createRaceTracker(URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm,
RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore, String tracTracUsername,
String tracTracPassword, String raceStatus, String raceVisibility,
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver,
RaceTrackingConnectivityParametersImpl connectivityParams, boolean preferReplayIfAvailable) throws MalformedURLException,
public TracTracRaceTracker createRaceTracker(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore, TrackedRegattaRegistry trackedRegattaRegistry,
RaceLogResolver raceLogResolver, RaceTrackingConnectivityParametersImpl connectivityParams) throws MalformedURLException,
FileNotFoundException, URISyntaxException, CreateModelException, SubscriberInitializationException {
return new TracTracRaceTrackerImpl(this, paramURL, liveURI, storedURI, courseDesignUpdateURI, startOfTracking,
endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm,
raceLogStore, regattaLogStore, windStore, tracTracUsername, tracTracPassword, raceStatus,
raceVisibility, trackedRegattaRegistry, raceLogResolver, connectivityParams, preferReplayIfAvailable);
return new TracTracRaceTrackerImpl(this, raceLogStore, regattaLogStore, windStore, trackedRegattaRegistry, raceLogResolver, connectivityParams);
}
@Override
public RaceTracker createRaceTracker(Regatta regatta, URL paramURL, URI liveURI, URI storedURI,
URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
RegattaLogStore regattaLogStore, WindStore windStore, String tracTracUsername,
String tracTracPassword, String raceStatus, String raceVisibility,
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver, RaceTrackingConnectivityParametersImpl connectivityParams,
boolean preferReplayIfAvailable)
public RaceTracker createRaceTracker(Regatta regatta, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore,
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver, RaceTrackingConnectivityParametersImpl connectivityParams)
throws MalformedURLException, FileNotFoundException, URISyntaxException, CreateModelException,
SubscriberInitializationException {
return new TracTracRaceTrackerImpl(regatta, this, paramURL, liveURI, storedURI, courseDesignUpdateURI,
startOfTracking, endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore,
regattaLogStore, windStore, tracTracUsername, tracTracPassword, raceStatus,
raceVisibility, trackedRegattaRegistry, raceLogResolver, connectivityParams, preferReplayIfAvailable);
return new TracTracRaceTrackerImpl(regatta, this, raceLogStore, regattaLogStore, windStore, trackedRegattaRegistry,
raceLogResolver, connectivityParams);
}
@Override
@@ -697,7 +682,7 @@ public class DomainFactoryImpl implements DomainFactory {
URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking,
long delayToLiveInMillis, Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
RegattaLogStore regattaLogStore, String tracTracUsername, String tracTracPassword, String raceStatus,
String raceVisibility, boolean trackWind, boolean correctWindDirectionByMagneticDeclination, boolean preferReplayIfAvailable) {
String raceVisibility, boolean trackWind, boolean correctWindDirectionByMagneticDeclination, boolean preferReplayIfAvailable) throws Exception {
return new RaceTrackingConnectivityParametersImpl(paramURL, liveURI, storedURI, courseDesignUpdateURI,
startOfTracking, endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore,
regattaLogStore, this, tracTracUsername, tracTracPassword, raceStatus, raceVisibility, trackWind, correctWindDirectionByMagneticDeclination,
@@ -5,6 +5,7 @@ import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.logging.Logger;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.base.Regatta;
@@ -17,11 +18,14 @@ import com.sap.sailing.domain.tracking.impl.AbstractRaceTrackingConnectivityPara
import com.sap.sailing.domain.tractracadapter.DomainFactory;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.tractrac.model.lib.api.ModelLocator;
import com.tractrac.model.lib.api.event.CreateModelException;
import com.tractrac.model.lib.api.event.IRace;
import com.tractrac.subscription.lib.api.SubscriberInitializationException;
public class RaceTrackingConnectivityParametersImpl extends AbstractRaceTrackingConnectivityParameters {
private static final Logger logger = Logger.getLogger(RaceTrackingConnectivityParametersImpl.class.getName());
public static final String TYPE = "TRAC_TRAC";
private final URL paramURL;
@@ -41,6 +45,7 @@ public class RaceTrackingConnectivityParametersImpl extends AbstractRaceTracking
private final String raceVisibility;
private final boolean useInternalMarkPassingAlgorithm;
private final boolean preferReplayIfAvailable;
private final IRace tractracRace;
/**
* @param preferReplayIfAvailable
@@ -52,13 +57,25 @@ public class RaceTrackingConnectivityParametersImpl extends AbstractRaceTracking
*/
public RaceTrackingConnectivityParametersImpl(URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
DomainFactory domainFactory, String tracTracUsername, String tracTracPassword, String raceStatus,
String raceVisibility, boolean trackWind, boolean correctWindDirectionByMagneticDeclination, boolean preferReplayIfAvailable) {
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm,
RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, DomainFactory domainFactory,
String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility,
boolean trackWind, boolean correctWindDirectionByMagneticDeclination, boolean preferReplayIfAvailable)
throws Exception {
super(trackWind, correctWindDirectionByMagneticDeclination);
this.paramURL = paramURL;
this.liveURI = liveURI;
this.storedURI = storedURI;
this.tractracRace = ModelLocator.getEventFactory().createRace(new URI(paramURL.toString()));
if (preferReplayIfAvailable && isReplayRace(tractracRace) &&
(!Util.equalsWithNull(liveURI, tractracRace.getLiveURI()) || !Util.equalsWithNull(storedURI, tractracRace.getStoredURI()))) {
logger.info("Replay format available and preferred for race " + tractracRace.getName()
+ "; using storedURI " + tractracRace.getStoredURI() + " instead of " + storedURI
+ " and liveURI " + tractracRace.getLiveURI() + " instead of " + liveURI);
this.liveURI = tractracRace.getLiveURI();
this.storedURI = tractracRace.getStoredURI();
} else {
this.liveURI = liveURI;
this.storedURI = storedURI;
}
this.courseDesignUpdateURI = courseDesignUpdateURI;
this.startOfTracking = startOfTracking;
this.endOfTracking = endOfTracking;
@@ -75,6 +92,15 @@ public class RaceTrackingConnectivityParametersImpl extends AbstractRaceTracking
this.preferReplayIfAvailable = preferReplayIfAvailable;
}
private boolean isReplayRace(IRace tractracRace) {
// TODO bug 4037: change into tractracRace.getConnectionType() == File once TracAPI 3.3.2 is available
return tractracRace.getStoredURI() != null && tractracRace.getStoredURI().toString().toLowerCase().endsWith(".mtb");
}
public IRace getTractracRace() {
return tractracRace;
}
@Override
public String getTypeIdentifier() {
return TYPE;
@@ -84,20 +110,15 @@ public class RaceTrackingConnectivityParametersImpl extends AbstractRaceTracking
public RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore,
RaceLogResolver raceLogResolver) throws MalformedURLException, FileNotFoundException, URISyntaxException,
CreateModelException, SubscriberInitializationException {
RaceTracker tracker = domainFactory.createRaceTracker(paramURL, liveURI, storedURI, courseDesignUpdateURI,
startOfTracking, endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore,
regattaLogStore, windStore, tracTracUsername, tracTracPassword, raceStatus,
raceVisibility, trackedRegattaRegistry, raceLogResolver, this, preferReplayIfAvailable);
RaceTracker tracker = domainFactory.createRaceTracker(raceLogStore, regattaLogStore, windStore, trackedRegattaRegistry, raceLogResolver, this);
return tracker;
}
@Override
public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry,
WindStore windStore, RaceLogResolver raceLogResolver) throws Exception {
RaceTracker tracker = domainFactory.createRaceTracker(regatta, paramURL, liveURI, storedURI,
courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm,
raceLogStore, regattaLogStore, windStore, tracTracUsername, tracTracPassword, raceStatus,
raceVisibility, trackedRegattaRegistry, raceLogResolver, this, preferReplayIfAvailable);
RaceTracker tracker = domainFactory.createRaceTracker(regatta, raceLogStore, regattaLogStore, windStore,
trackedRegattaRegistry, raceLogResolver, this);
return tracker;
}
@@ -159,4 +180,7 @@ public class RaceTrackingConnectivityParametersImpl extends AbstractRaceTracking
return useInternalMarkPassingAlgorithm;
}
public boolean isPreferReplayIfAvailable() {
return preferReplayIfAvailable;
}
}
@@ -53,8 +53,6 @@ import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.util.impl.ThreadFactoryWithPriority;
import com.tractrac.model.lib.api.ModelLocator;
import com.tractrac.model.lib.api.event.CreateModelException;
import com.tractrac.model.lib.api.event.ICompetitor;
import com.tractrac.model.lib.api.event.IEvent;
import com.tractrac.model.lib.api.event.IRace;
@@ -238,62 +236,19 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
* respond with the {@link RaceDefinition} when its {@link DomainFactory#getRaceID(com.tractrac.model.lib.api.event.IRace)} is called with the
* TracTrac {@link IEvent} as argument that is used for its tracking.
* <p>
* @param startOfTracking
* if <code>null</code>, all stored data from the "beginning of time" will be loaded that the event has
* to provide, particularly for the mark positions which are stored per event, not per race; otherwise,
* particularly the mark position loading will be constrained to this start time.
* @param endOfTracking
* if <code>null</code>, all stored data until the "end of time" will be loaded that the event has to
* provide, particularly for the mark positions which are stored per event, not per race; otherwise,
* particularly the mark position loading will be constrained to this end time.
* @param windStore
* Provides the capability to obtain the {@link WindTrack}s for the different wind sources. A trivial
* implementation is {@link EmptyWindStore} which simply provides new, empty tracks. This is always
* available but loses track of the wind, e.g., during server restarts.
* @param trackedRegattaRegistry
* used to create the {@link TrackedRegatta} for the domain event
* @param preferReplayIfAvailable
* when a non-{@code null} {@code storedURI} and/or {@code liveURI} are provided and the {@link IRace}
* specifies something different and claims to be in replay mode ({@link IRace#getConnectionType} is
* {@code File}) then if this parameter is {@code true} the race will be loaded from the replay file
* instead of the {@code storedURI}/{@code liveURI} specified. This is particularly useful for restoring
* races if since the last connection the race was migrated to a replay file format.
*/
protected TracTracRaceTrackerImpl(DomainFactory domainFactory, URL paramURL, URI liveURI, URI storedURI,
URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
WindStore windStore, String tracTracUsername, String tracTracPassword,
String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver, RaceTrackingConnectivityParametersImpl connectivityParams,
boolean preferReplayIfAvailable)
throws URISyntaxException, MalformedURLException, FileNotFoundException, CreateModelException,
SubscriberInitializationException {
this(ModelLocator.getEventFactory().createRace(new URI(paramURL.toString())), domainFactory, paramURL, liveURI,
storedURI, courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis,
offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore,
windStore, tracTracUsername,
tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry, raceLogResolver, connectivityParams, preferReplayIfAvailable);
}
/**
* @param preferReplayIfAvailable
* when a non-{@code null} {@code storedURI} and/or {@code liveURI} are provided and the {@link IRace}
* specifies something different and claims to be in replay mode ({@link IRace#getConnectionType} is
* {@code File}) then if this parameter is {@code true} the race will be loaded from the replay file
* instead of the {@code storedURI}/{@code liveURI} specified. This is particularly useful for restoring
* races if since the last connection the race was migrated to a replay file format.
*/
private TracTracRaceTrackerImpl(IRace tractracRace, DomainFactory domainFactory, URL paramURL, URI liveURI,
URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking,
long delayToLiveInMillis, Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
RegattaLogStore regattaLogStore, WindStore windStore, String tracTracUsername,
String tracTracPassword, String raceStatus, String raceVisibility,
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver, RaceTrackingConnectivityParametersImpl connectivityParams,
boolean preferReplayIfAvailable) throws URISyntaxException, MalformedURLException,
FileNotFoundException, SubscriberInitializationException {
this(tractracRace, /* regatta */ null, domainFactory, paramURL, liveURI, storedURI, courseDesignUpdateURI, startOfTracking,
endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, windStore,
tracTracUsername, tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry,
raceLogResolver, connectivityParams, preferReplayIfAvailable);
TracTracRaceTrackerImpl(DomainFactory domainFactory, RaceLogStore raceLogStore,
RegattaLogStore regattaLogStore, WindStore windStore, TrackedRegattaRegistry trackedRegattaRegistry,
RaceLogResolver raceLogResolver, RaceTrackingConnectivityParametersImpl connectivityParams)
throws URISyntaxException, MalformedURLException, FileNotFoundException, SubscriberInitializationException {
this(/* regatta */ null, domainFactory, raceLogStore, regattaLogStore, windStore, trackedRegattaRegistry,
raceLogResolver, connectivityParams);
}
/**
@@ -302,72 +257,31 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
* create a default {@link Regatta} with only a single default {@link Series} and {@link Fleet} which may not always
* be what you want.
*
* @param preferReplayIfAvailable
* when a non-{@code null} {@code storedURI} and/or {@code liveURI} are provided and the {@link IRace}
* specifies something different and claims to be in replay mode ({@link IRace#getConnectionType} is
* {@code File}) then if this parameter is {@code true} the race will be loaded from the replay file
* instead of the {@code storedURI}/{@code liveURI} specified. This is particularly useful for restoring
* races if since the last connection the race was migrated to a replay file format.
*/
protected TracTracRaceTrackerImpl(Regatta regatta, DomainFactory domainFactory, URL paramURL, URI liveURI,
URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking,
long delayToLiveInMillis, Duration offsetToStartTimeOfSimulatedRace, boolean ignoreTracTracMarkPassings, RaceLogStore raceLogStore,
RegattaLogStore regattaLogStore, WindStore windStore, String tracTracUsername,
String tracTracPassword, String raceStatus, String raceVisibility,
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver, RaceTrackingConnectivityParametersImpl connectivityParams,
boolean preferReplayIfAvailable) throws URISyntaxException,
MalformedURLException, FileNotFoundException, CreateModelException, SubscriberInitializationException {
this(ModelLocator.getEventFactory().createRace(new URI(paramURL.toString())), regatta, domainFactory, paramURL,
liveURI, storedURI, courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis,
offsetToStartTimeOfSimulatedRace, ignoreTracTracMarkPassings, raceLogStore, regattaLogStore, windStore,
tracTracUsername,
tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry, raceLogResolver, connectivityParams, preferReplayIfAvailable);
}
private boolean isReplayRace(IRace tractracRace) {
// TODO bug 4037: change into tractracRace.getConnectionType() == File once TracAPI 3.3.2 is available
return tractracRace.getStoredURI() != null && tractracRace.getStoredURI().toString().toLowerCase().endsWith(".mtb");
}
/**
* @param regatta
* if <code>null</code>, then <code>domainFactory.getOrCreateRegatta(tractracEvent)</code> will be used
* to obtain a default regatta
* @param offsetToStartTimeOfSimulatedRace
* if not <code>null</code>, the connector will adjust the time stamps of all events received such that
* the first mark passing for the first waypoint will be set to "now." It will delay the forwarding of
* all events received such that they seem to be sent in "real-time" +
* <code>offsetToStartTimeOfSimulatedRace</code> So, more or less the time points attached to the events
* sent to the receivers will again approximate the wall time.
* @param preferReplayIfAvailable
* when a non-{@code null} {@code storedURI} and/or {@code liveURI} are provided and the {@link IRace}
* specifies something different and claims to be in replay mode ({@link IRace#getConnectionType} is
* {@code File}) then if this parameter is {@code true} the race will be loaded from the replay file
* instead of the {@code storedURI}/{@code liveURI} specified. This is particularly useful for restoring
* races if since the last connection the race was migrated to a replay file format.
*/
private TracTracRaceTrackerImpl(IRace tractracRace, final Regatta regatta, DomainFactory domainFactory,
URL paramURL, URI liveURI, URI storedURI, URI tracTracUpdateURI, TimePoint startOfTracking,
TimePoint endOfTracking, long delayToLiveInMillis, Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm,
RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore,
String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility,
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver, RaceTrackingConnectivityParametersImpl connectivityParams,
boolean preferReplayIfAvailable) throws URISyntaxException, MalformedURLException,
FileNotFoundException, SubscriberInitializationException {
TracTracRaceTrackerImpl(final Regatta regatta, DomainFactory domainFactory, RaceLogStore raceLogStore,
RegattaLogStore regattaLogStore, WindStore windStore, TrackedRegattaRegistry trackedRegattaRegistry,
RaceLogResolver raceLogResolver, RaceTrackingConnectivityParametersImpl connectivityParams)
throws URISyntaxException, MalformedURLException, FileNotFoundException, SubscriberInitializationException {
super(connectivityParams);
final URL paramURL = connectivityParams.getParamURL();
final URI liveURI = connectivityParams.getLiveURI();
final URI storedURI = connectivityParams.getStoredURI();
final URI tracTracUpdateURI = connectivityParams.getCourseDesignUpdateURI();
final TimePoint startOfTracking = connectivityParams.getStartOfTracking();
final TimePoint endOfTracking = connectivityParams.getEndOfTracking();
final long delayToLiveInMillis = connectivityParams.getDelayToLiveInMillis();
final Duration offsetToStartTimeOfSimulatedRace = connectivityParams.getOffsetToStartTimeOfSimulatedRace();
final boolean useInternalMarkPassingAlgorithm = connectivityParams.isUseInternalMarkPassingAlgorithm();
final String tracTracUsername = connectivityParams.getTracTracUsername();
final String tracTracPassword = connectivityParams.getTracTracPassword();
final String raceStatus = connectivityParams.getRaceStatus();
final String raceVisibility = connectivityParams.getRaceVisibility();
this.trackedRegattaRegistry = trackedRegattaRegistry;
this.tractracRace = tractracRace;
this.tractracRace = connectivityParams.getTractracRace();
this.tractracEvent = tractracRace.getEvent();
if (preferReplayIfAvailable && isReplayRace(tractracRace)) {
if (!Util.equalsWithNull(liveURI, tractracRace.getLiveURI())
|| !Util.equalsWithNull(storedURI, tractracRace.getStoredURI())) {
logger.info("Replay format available and preferred for race " + tractracRace.getName()
+ "; using storedURI " + tractracRace.getStoredURI() + " instead of " + storedURI
+ " and liveURI " + tractracRace.getLiveURI() + " instead of " + liveURI);
liveURI = tractracRace.getLiveURI();
storedURI = tractracRace.getStoredURI();
}
}
this.id = createID(paramURL, liveURI, storedURI);
isLiveTracking = liveURI != null;
this.race = null; // no race received yet
@@ -383,17 +297,21 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
}
// check if there is a directory configured where stored data files can be cached
// only cache files for races in REPLAY state
final URI effectifeStoredURI; // may be altered by legacy caching mechanism; won't affect this tracker's ID
if ( (raceStatus != null && raceStatus.equals(TracTracConnectionConstants.REPLAY_STATUS)) ||
(raceVisibility != null && raceVisibility.equals(TracTracConnectionConstants.REPLAY_VISIBILITY)) ) {
storedURI = checkForCachedStoredData(storedURI);
effectifeStoredURI = checkForCachedStoredData(storedURI);
} else {
effectifeStoredURI = storedURI;
}
logger.info("Starting race tracker: " + tractracRace.getName() + " " + paramURL + " " + liveURI + " "
+ storedURI + " startOfTracking:" + (startOfTracking != null ? startOfTracking.asMillis() : "n/a") + " endOfTracking:" + (endOfTracking != null ? endOfTracking.asMillis() : "n/a"));
+ effectifeStoredURI + " startOfTracking:"
+ (startOfTracking != null ? startOfTracking.asMillis() : "n/a") + " endOfTracking:"
+ (endOfTracking != null ? endOfTracking.asMillis() : "n/a"));
// Initialize data controller using live and stored data sources
ISubscriberFactory subscriberFactory = SubscriptionLocator.getSusbcriberFactory();
eventSubscriber = subscriberFactory.createEventSubscriber(tractracEvent, liveURI, storedURI);
eventSubscriber = subscriberFactory.createEventSubscriber(tractracEvent, liveURI, effectifeStoredURI);
eventSubscriber.subscribeCompetitors(new ICompetitorsListener() {
@Override
public void updateCompetitor(ICompetitor competitor) {
@@ -432,7 +350,7 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
});
// Start live and stored data streams
final Regatta effectiveRegatta;
raceSubscriber = subscriberFactory.createRaceSubscriber(tractracRace, liveURI, storedURI);
raceSubscriber = subscriberFactory.createRaceSubscriber(tractracRace, liveURI, effectifeStoredURI);
raceSubscriber.subscribeConnectionStatus(this);
// Try to find a pre-associated event based on the Race ID
if (regatta == null) {