Merge branch 'master' into bug5165

This commit is contained in:
Axel Uhl
2020-01-10 20:31:52 +01:00
115 changed files with 859 additions and 286 deletions
@@ -14,4 +14,5 @@ public interface RaceLogServletConstants {
static final String PARAMS_COURSE_AREA_FILTER = "courseArea";
static final String PARAMS_TRACK_WIND = "trackWind";
static final String PARAMS_CORRECT_WIND_DIRECTION_BY_MAGNETIC_DECLINATION = "correctWindDirectionByMagneticDeclination";
static final String PARAMS_TRACKED_RACE_NAME = "trackedRaceName";
}
@@ -0,0 +1,18 @@
package com.sap.sailing.domain.common.tracking;
/**
* Identifies the tracking technology used for a TrackedRace.
*/
public enum TrackingConnectorType {
TracTrac("https://www.tractrac.com/"), SwissTiming(null), RaceLog(null);
private final String defaultUrl;
private TrackingConnectorType(String defaultUrl) {
this.defaultUrl = defaultUrl;
}
public String getDefaultUrl() {
return defaultUrl;
}
}
@@ -129,7 +129,7 @@ public class AbstractGPSFixStoreTest extends RaceLogTrackingTestHelper {
/* endDate */null, null, null, "a", null, /* registrationLinkSecret */ UUID.randomUUID().toString()));
return new DynamicTrackedRaceImpl(regatta, raceDefinition, Collections.<Sideline> emptyList(),
EmptyWindStore.INSTANCE, 0, 0, 0, /* useMarkPassingCalculator */ false, OneDesignRankingMetric::new,
mock(RaceLogAndTrackedRaceResolver.class), null);
mock(RaceLogAndTrackedRaceResolver.class), /* trackingConnectorInfo */ null);
}
protected void testNumberOfRawFixes(Track<?> track, long expected) {
@@ -108,7 +108,7 @@ public class RaceLogFixTrackerManagerTest {
/* registrationLinkSecret */ UUID.randomUUID().toString()));
trackedRace = new DynamicTrackedRaceImpl(regatta, race, Collections.<Sideline> emptyList(),
EmptyWindStore.INSTANCE, 0, 0, 0, /* useMarkPassingCalculator */ false, OneDesignRankingMetric::new,
mock(RaceLogAndTrackedRaceResolver.class), null);
mock(RaceLogAndTrackedRaceResolver.class), /* trackingConnectorInfo */ null);
}
/**
@@ -173,7 +173,7 @@ public class SensorFixStoreAndLoadTest {
/* registrationLinkSecret */ UUID.randomUUID().toString()));
trackedRace = new DynamicTrackedRaceImpl(regatta, race, Collections.<Sideline> emptyList(),
EmptyWindStore.INSTANCE, 0, 0, 0, /* useMarkPassingCalculator */ false, OneDesignRankingMetric::new,
mock(RaceLogAndTrackedRaceResolver.class), null);
mock(RaceLogAndTrackedRaceResolver.class), /* trackingConnectorInfo */ null);
}
private void dropPersistedData() {
@@ -84,7 +84,7 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
/* useMarkPassingCalculator */ false,
OneDesignRankingMetric::new, mock(RaceLogAndTrackedRaceResolver.class), null);
OneDesignRankingMetric::new, mock(RaceLogAndTrackedRaceResolver.class), /* trackingConnectorInfo */ null);
MillisecondsTimePoint startOfRaceInRaceLog = new MillisecondsTimePoint(10000);
MillisecondsTimePoint endOfRaceInRaceLog = new MillisecondsTimePoint(20000);
@@ -162,7 +162,7 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
/* useMarkPassingCalculator */ false,
OneDesignRankingMetric::new, mock(RaceLogAndTrackedRaceResolver.class), null);
OneDesignRankingMetric::new, mock(RaceLogAndTrackedRaceResolver.class), /* trackingConnectorInfo */ null);
trackedRace.attachRaceLog(raceLog);
final TimePoint[] oldAndNewStartTimeNotifiedByRace = new TimePoint[2];
trackedRace.addListener(new AbstractRaceChangeListener() {
@@ -206,7 +206,7 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
/* useMarkPassingCalculator */ false,
OneDesignRankingMetric::new, mock(RaceLogAndTrackedRaceResolver.class), null);
OneDesignRankingMetric::new, mock(RaceLogAndTrackedRaceResolver.class), /* trackingConnectorInfo */ null);
final TimePoint[] oldAndNewStartTimeNotifiedByRace = new TimePoint[2];
trackedRace.addListener(new AbstractRaceChangeListener() {
@Override
@@ -254,7 +254,7 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
/* useMarkPassingCalculator */ false,
OneDesignRankingMetric::new, mock(RaceLogAndTrackedRaceResolver.class), null);
OneDesignRankingMetric::new, mock(RaceLogAndTrackedRaceResolver.class), /* trackingConnectorInfo */ null);
trackedRace.attachRaceLog(raceLog);
trackedRace.attachRegattaLog(regattaLog);
final TimePoint[] newStartAndEndOfTrackingNotifiedByRace = new TimePoint[2];
@@ -369,7 +369,7 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
/* useMarkPassingCalculator */ false,
OneDesignRankingMetric::new, mock(RaceLogAndTrackedRaceResolver.class), null);
OneDesignRankingMetric::new, mock(RaceLogAndTrackedRaceResolver.class), /* trackingConnectorInfo */ null);
trackedRace.attachRaceLog(raceLog);
final TimePoint[] oldAndNewStartTimeNotifiedByRace = new TimePoint[2];
trackedRace.addListener(new AbstractRaceChangeListener() {
@@ -57,6 +57,7 @@ import com.sap.sailing.domain.common.abstractlog.TimePointSpecificationFoundInLo
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.domain.common.racelog.tracking.RaceLogTrackingState;
import com.sap.sailing.domain.common.racelog.tracking.RaceNotCreatedException;
import com.sap.sailing.domain.common.tracking.TrackingConnectorType;
import com.sap.sailing.domain.racelog.RaceLogAndTrackedRaceResolver;
import com.sap.sailing.domain.regattalike.IsRegattaLike;
import com.sap.sailing.domain.tracking.AbstractRaceTrackerBaseImpl;
@@ -68,6 +69,7 @@ import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.domain.tracking.impl.TrackingConnectorInfoImpl;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.impl.MillisecondsTimePoint;
@@ -86,7 +88,6 @@ import difflib.PatchFailedException;
*/
public class RaceLogRaceTracker extends AbstractRaceTrackerBaseImpl {
private static final String RACE_LOG = "raceLog";
private static final String LOGGER_AND_LOGAUTHOR_NAME = RaceLogRaceTracker.class.getName();
private static final Logger logger = Logger.getLogger(LOGGER_AND_LOGAUTHOR_NAME);
@@ -314,7 +315,8 @@ public class RaceLogRaceTracker extends AbstractRaceTrackerBaseImpl {
trackedRace = raceTrackingHandler.createTrackedRace(trackedRegatta, raceDef, sidelines, windStore,
params.getDelayToLiveInMillis(), WindTrack.DEFAULT_MILLISECONDS_OVER_WHICH_TO_AVERAGE_WIND,
boatClass.getApproximateManeuverDurationInMilliseconds(), null, /*useMarkPassingCalculator*/ true, raceLogResolver,
/* Not needed because the RaceTracker is not active on a replica */ Optional.empty(), RACE_LOG);
/* Not needed because the RaceTracker is not active on a replica */ Optional.empty(),
new TrackingConnectorInfoImpl(TrackingConnectorType.RaceLog, /* webUrl */ null));
notifyRaceCreationListeners();
logger.info(String.format("Started tracking race-log race (%s)", raceLog));
// this wakes up all waiting race handles
@@ -3,7 +3,9 @@ package com.sap.sailing.domain.base;
import java.net.URL;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import com.sap.sailing.domain.tracking.TrackingConnectorInfo;
import com.sap.sse.common.NamedWithID;
import com.sap.sse.common.Renamable;
import com.sap.sse.common.TimePoint;
@@ -107,9 +109,11 @@ public interface EventBase extends NamedWithID, WithDescription, Renamable, With
boolean setMediaURLs(Iterable<URL> imageURLs, Iterable<URL> sponsorImageURLs, Iterable<URL> videoURLs, URL logoImageURL, Map<URL, ImageSize> imageSizes);
/**
* Determines whether the race is tracked by TracTrac or not
* @return a boolean flag, whether any @TrackedRace in the event is tracked by TracTrac or not
* Gets all TrackingConnectorInfos containing information over what TrackingConnectors are involved in tracking this
* event
*
* @return a Set of {@link TrackingConnectorInfo}; the set returned is never {@code null} and never contains
* {@code null} values, but it may be empty
*/
boolean isTrackedByTracTrac();
Set<TrackingConnectorInfo> getTrackingConnectorInfos();
}
@@ -1,10 +1,12 @@
package com.sap.sailing.domain.base.impl;
import java.util.Set;
import java.util.UUID;
import com.sap.sailing.domain.base.EventBase;
import com.sap.sailing.domain.base.LeaderboardGroupBase;
import com.sap.sailing.domain.base.Venue;
import com.sap.sailing.domain.tracking.TrackingConnectorInfo;
import com.sap.sse.common.TimePoint;
/**
@@ -16,20 +18,21 @@ import com.sap.sse.common.TimePoint;
*
*/
public class StrippedEventImpl extends EventBaseImpl {
private static final long serialVersionUID = -8158306909959745156L;
private final boolean isTrackedByTracTrac;
private static final long serialVersionUID = -4443856327974643859L;
private final Set<TrackingConnectorInfo> trackingConnectorInfos;
private final Iterable<LeaderboardGroupBase> leaderboardGroups;
public StrippedEventImpl(String name, TimePoint startDate, TimePoint endDate, String venueName,
boolean isPublic, UUID id, Iterable<LeaderboardGroupBase> leaderboardGroups, boolean isTrackedByTracTrac) {
this(name, startDate, endDate, new VenueImpl(venueName), isPublic, id, leaderboardGroups, isTrackedByTracTrac);
boolean isPublic, UUID id, Iterable<LeaderboardGroupBase> leaderboardGroups, Set<TrackingConnectorInfo> trackingConnectorInfos) {
this(name, startDate, endDate, new VenueImpl(venueName), isPublic, id, leaderboardGroups, trackingConnectorInfos);
}
public StrippedEventImpl(String name, TimePoint startDate, TimePoint endDate, Venue venue,
boolean isPublic, UUID id, Iterable<LeaderboardGroupBase> leaderboardGroups, boolean isTrackedByTracTrac) {
boolean isPublic, UUID id, Iterable<LeaderboardGroupBase> leaderboardGroups, Set<TrackingConnectorInfo> trackingConnectorInfos) {
super(name, startDate, endDate, venue, isPublic, id);
this.leaderboardGroups = leaderboardGroups;
this.isTrackedByTracTrac = isTrackedByTracTrac;
assert trackingConnectorInfos != null;
this.trackingConnectorInfos = trackingConnectorInfos;
}
@Override
@@ -38,7 +41,7 @@ public class StrippedEventImpl extends EventBaseImpl {
}
@Override
public boolean isTrackedByTracTrac() {
return isTrackedByTracTrac;
public Set<TrackingConnectorInfo> getTrackingConnectorInfos() {
return trackingConnectorInfos;
}
}
@@ -0,0 +1,24 @@
package com.sap.sailing.domain.tracking;
import java.io.Serializable;
import java.net.URL;
import com.sap.sailing.domain.common.tracking.TrackingConnectorType;
/**
* Identifies the tracking connector that was used to create a TrackedRace.
* Further the Connector can provide a webUrl, that leads to an event web page.
*/
public interface TrackingConnectorInfo extends Serializable {
/**
* gets the {@link TrackingConnectorType} associated with the tracking technology used for the Race
*/
TrackingConnectorType getTrackingConnectorType();
/**
* gets a {@link URL} representation of the web-URL associated with the Event;
* may be {@code null} if the API of the respective Tracking-Service does not provide a URL;
*/
URL getWebUrl();
}
@@ -0,0 +1,57 @@
package com.sap.sailing.domain.tracking.impl;
import java.net.URL;
import com.sap.sailing.domain.common.tracking.TrackingConnectorType;
import com.sap.sailing.domain.tracking.TrackingConnectorInfo;
public class TrackingConnectorInfoImpl implements TrackingConnectorInfo {
private static final long serialVersionUID = 7970268841592389145L;
private final TrackingConnectorType trackingConnectorType;
private final URL webUrl;
public TrackingConnectorInfoImpl(TrackingConnectorType trackingConnectorType, URL webUrl) {
super();
this.trackingConnectorType = trackingConnectorType;
this.webUrl = webUrl;
}
public TrackingConnectorType getTrackingConnectorType() {
return trackingConnectorType;
}
public URL getWebUrl() {
return webUrl;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((trackingConnectorType == null) ? 0 : trackingConnectorType.hashCode());
result = prime * result + ((webUrl == null) ? 0 : webUrl.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TrackingConnectorInfoImpl other = (TrackingConnectorInfoImpl) obj;
if (trackingConnectorType == null) {
if (other.trackingConnectorType != null)
return false;
} else if (!trackingConnectorType.equals(other.trackingConnectorType))
return false;
if (webUrl == null) {
if (other.webUrl != null)
return false;
} else if (!webUrl.equals(other.webUrl))
return false;
return true;
}
}
@@ -35,6 +35,7 @@ import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
import com.sap.sailing.domain.common.impl.WindImpl;
import com.sap.sailing.domain.common.impl.WindSourceWithAdditionalID;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.common.tracking.TrackingConnectorType;
import com.sap.sailing.domain.racelog.RaceLogAndTrackedRaceResolver;
import com.sap.sailing.domain.racelog.RaceLogStore;
import com.sap.sailing.domain.regattalog.RegattaLogStore;
@@ -65,6 +66,7 @@ import com.sap.sailing.domain.tracking.TrackingDataLoader;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.domain.tracking.impl.TrackedRaceStatusImpl;
import com.sap.sailing.domain.tracking.impl.TrackingConnectorInfoImpl;
import com.sap.sailing.domain.tracking.impl.UpdateHandler;
import com.sap.sse.common.Distance;
import com.sap.sse.common.TimePoint;
@@ -76,7 +78,6 @@ import difflib.PatchFailedException;
public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl
implements SwissTimingRaceTracker, SailMasterListener, TrackingDataLoader {
private static final String SWISS_TIMING = "swissTiming";
private static final Logger logger = Logger.getLogger(SwissTimingRaceTrackerImpl.class.getName());
@@ -495,7 +496,8 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl
assert SwissTimingRaceTrackerImpl.this.race == race;
}
}, useInternalMarkPassingAlgorithm, raceLogResolver,
/* Not needed because the RaceTracker is not active on a replica */ Optional.empty(), SWISS_TIMING);
/* Not needed because the RaceTracker is not active on a replica */ Optional.empty(),
new TrackingConnectorInfoImpl(TrackingConnectorType.SwissTiming, /*no api connection to query the webUrl*/ null));
addUpdateHandlers();
notifyRaceCreationListeners();
logger.info("Created SwissTiming RaceDefinition and TrackedRace for "+race.getName());
@@ -36,6 +36,7 @@ import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
import com.sap.sailing.domain.common.impl.WindImpl;
import com.sap.sailing.domain.common.impl.WindSourceWithAdditionalID;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.common.tracking.TrackingConnectorType;
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.domain.racelog.RaceLogAndTrackedRaceResolver;
import com.sap.sailing.domain.racelog.RaceLogStore;
@@ -58,6 +59,7 @@ import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.domain.tracking.impl.MarkPassingImpl;
import com.sap.sailing.domain.tracking.impl.TrackedRaceStatusImpl;
import com.sap.sailing.domain.tracking.impl.TrackingConnectorInfoImpl;
import com.sap.sse.common.Bearing;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
@@ -79,7 +81,6 @@ import difflib.PatchFailedException;
*
*/
public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter implements TrackingDataLoader {
private static final String SWISS_TIMING = "swissTiming";
private static final int THRESHOLD_FOR_EARLIEST_MARK_PASSING_BEFORE_START_IN_MILLIS = 30000;
@@ -411,10 +412,11 @@ public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter i
DynamicTrackedRace trackedRace = raceTrackingHandler.createTrackedRace(getTrackedRegatta(),
race, Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE,
TrackedRace.DEFAULT_LIVE_DELAY_IN_MILLISECONDS,
WindTrack.DEFAULT_MILLISECONDS_OVER_WHICH_TO_AVERAGE_WIND,
WindTrack.DEFAULT_MILLISECONDS_OVER_WHICH_TO_AVERAGE_WIND,
/* time over which to average speed: */ race.getBoatClass().getApproximateManeuverDurationInMilliseconds(),
/* raceDefinitionSetToUpdate */ null, useInternalMarkPassingAlgorithm, raceLogResolver,
/* Not needed because the RaceTracker is not active on a replica */ Optional.empty(), SWISS_TIMING);
/* Not needed because the RaceTracker is not active on a replica */ Optional.empty(),
new TrackingConnectorInfoImpl(TrackingConnectorType.SwissTiming, /*no api connection to query the webUrl*/ null));
trackedRace.onStatusChanged(this, new TrackedRaceStatusImpl(TrackedRaceStatusEnum.LOADING, 0));
TimePoint bestStartTimeKnownSoFar = bestStartTimePerRaceID.get(currentRaceID);
if (bestStartTimeKnownSoFar != null) {
@@ -9,6 +9,7 @@ import java.io.IOException;
import java.net.URL;
import org.json.simple.parser.ParseException;
import org.junit.Ignore;
import org.junit.Test;
import com.sap.sailing.domain.common.orc.ORCCertificate;
@@ -26,6 +27,7 @@ public class TestORCCertificateImporterJSON {
assertNotNull(milan);
}
@Ignore("Certificate used for testing no longer valid after 2019")
@Test
public void testSimpleOnlineJSONFileRead() throws IOException, ParseException {
ORCCertificatesCollection importer = ORCCertificatesImporter.INSTANCE.read(new URL("https://data.orc.org/public/WPub.dll?action=DownRMS&CountryId=GER&ext=json").openStream());
@@ -10,6 +10,7 @@ import java.net.URL;
import java.util.Collection;
import org.json.simple.parser.ParseException;
import org.junit.Ignore;
import org.junit.Test;
import com.sap.sailing.domain.common.orc.ORCCertificate;
@@ -26,6 +27,7 @@ public class TestORCCertificateImporterRMS {
assertNotNull(milan);
}
@Ignore("Certificate used for testing no longer valid after 2019")
@Test
public void testSimpleOnlineRMSFileRead() throws IOException, ParseException {
ORCCertificatesCollection certificates = ORCCertificatesImporter.INSTANCE.read(new URL("https://data.orc.org/public/WPub.dll?action=DownRMS&CountryId=GER&ext=rms").openStream());
@@ -17,6 +17,7 @@ import org.apache.commons.math.MaxIterationsExceededException;
import org.json.simple.parser.ParseException;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ErrorCollector;
@@ -237,6 +238,7 @@ public class TestORCPerformanceCurve {
/**
* Tests to make sure, that the structure of the certificate files didn't change and performance curves can be built
*/
@Ignore("Certificate used for testing no longer valid after 2019")
@Test
public void testOnlineImport() throws FunctionEvaluationException {
assertFalse(Util.isEmpty(importerOnline.getCertificateIds()));
@@ -13,6 +13,7 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import com.sap.sailing.domain.base.impl.BoatClassImpl;
@@ -85,7 +86,7 @@ public class TestORCPublicCertificateDatabase {
assertEquals(handle.getSailNumber(), result.getSailNumber());
}
// TODO this test will probably break 2020 when 2019 certificates will no longer be returned as valid...
@Ignore("Certificate used for testing no longer valid after 2019")
@Test
public void testParallelFuzzySearch() throws InterruptedException, ExecutionException {
final Future<Set<ORCCertificate>> soulmateCertificatesFuture = db.search("Soulmate", "DEN13", new BoatClassImpl("ORC", BoatClassMasterdata.ORC));
@@ -320,7 +320,7 @@ public class CourseTest {
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, /* delayToLiveInMillis */3000,
/* millisecondsOverWhichToAverageWind */30000,
/* millisecondsOverWhichToAverageSpeed */8000, /*useMarkPassingCalculator*/ false, OneDesignRankingMetric::new,
mock(RaceLogAndTrackedRaceResolver.class), null);
mock(RaceLogAndTrackedRaceResolver.class), /* trackingConnectorInfo */ null);
assertLegStructure(course, trackedRace);
course.removeWaypoint(0);
assertLegStructure(course, trackedRace);
@@ -356,7 +356,7 @@ public class CourseTest {
EmptyWindStore.INSTANCE, /* delayToLiveInMillis */ 3000,
/* millisecondsOverWhichToAverageWind */ 30000,
/* millisecondsOverWhichToAverageSpeed */ 8000, /*useMarkPassingCalculator*/ false, OneDesignRankingMetric::new,
mock(RaceLogAndTrackedRaceResolver.class), null);
mock(RaceLogAndTrackedRaceResolver.class), /* trackingConnectorInfo */ null);
assertLegStructure(course, trackedRace);
final WaypointImpl wp1_5 = new WaypointImpl(new MarkImpl("Test Mark 1.5"));
assertWaypointIndexes(course);
@@ -87,7 +87,8 @@ public class CourseUpdateDuringNonAtomicSerializationTest implements Serializabl
trackedRace = new DynamicTrackedRaceImpl(trackedRegatta, race, Collections.<Sideline> emptySet(),
EmptyWindStore.INSTANCE,
/* delayToLiveInMillis */10000, /* millisecondsOverWhichToAverageWind */30000, /* millisecondsOverWhichToAverageSpeed */
7000, /*useMarkPassingCalculator*/ false, OneDesignRankingMetric::new, mock(RaceLogAndTrackedRaceResolver.class), null) {
7000, /* useMarkPassingCalculator */ false, OneDesignRankingMetric::new,
mock(RaceLogAndTrackedRaceResolver.class), /* trackingConnectorInfo */ null) {
private static final long serialVersionUID = 9114777576548711763L;
@Override
@@ -152,7 +152,7 @@ public class LeaderboardCourseChangeTest {
TrackedRace spyedTrackedRace = spy(new DynamicTrackedRaceImpl(mockedTrackedRegatta, mockedRace,
new HashSet<Sideline>(), EmptyWindStore.INSTANCE, 5000, 20000, 20000,
/* useMarkPassingCalculator */ false, OneDesignRankingMetric::new,
mock(RaceLogAndTrackedRaceResolver.class), null));
mock(RaceLogAndTrackedRaceResolver.class), /* trackingConnectorInfo */ null));
return spyedTrackedRace;
}
@@ -42,7 +42,7 @@ public class SerializeRankingMetricTest extends AbstractSerializationTest {
new RaceDefinitionImpl("Race", new CourseImpl("Course", Collections.<Waypoint>emptyList()) ,
/* boatClass */ _49er, Collections.<Competitor,Boat>emptyMap()),
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0l, 0l, 0l,
false, TimeOnTimeAndDistanceRankingMetric::new, null, null);
false, TimeOnTimeAndDistanceRankingMetric::new, null, /* trackingConnectorInfo */ null);
RankingMetric clone = cloneBySerialization(trackedRace.getRankingMetric(), DomainFactory.INSTANCE);
assertNotNull(clone);
assertTrue(clone instanceof TimeOnTimeAndDistanceRankingMetric);
@@ -91,7 +91,7 @@ public class StarbordSideOfStartLineRecognitionTest {
public MockedTrackedRaceImpl() {
super(null, null, Collections.<Sideline> emptyList(), null, 0, 0, 0, 0, false, OneDesignRankingMetric::new,
mock(RaceLogAndTrackedRaceResolver.class), null);
mock(RaceLogAndTrackedRaceResolver.class), /* trackingConnectorInfo */ null);
}
@Override
@@ -201,7 +201,7 @@ public abstract class TrackBasedTest {
/* delayToLiveInMillis */ 0,
/* millisecondsOverWhichToAverageWind */ 30000, /* millisecondsOverWhichToAverageSpeed */ 30000,
/* delay for wind estimation cache invalidation */ 0, useMarkPassingCalculator,
rankingMetricConstructor, raceLogResolver, null);
rankingMetricConstructor, raceLogResolver, /* trackingConnectorInfo */ null);
// in this simplified artificial course, the top mark is exactly north of the right leeward gate
DegreePosition topPosition = new DegreePosition(54.48, 10.24);
TimePoint afterTheRace = new MillisecondsTimePoint(timePointForFixes.asMillis() + 36000000); // 10h after the fix timed
@@ -47,12 +47,13 @@ public class UpdateMarkPassingTest {
when(race.getBoatClass()).thenReturn(new BoatClassImpl("49er", /* typicallyStartsUpwind */ true));
when(race.getCompetitors()).thenReturn(Collections.singleton(competitor));
DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(
/* trackedRegatta */new DynamicTrackedRegattaImpl(new RegattaImpl("test", null, true, CompetitorRegistrationType.CLOSED, null, null, new HashSet<Series>(), false, null,
"test", null, OneDesignRankingMetric::new,
/* registrationLinkSecret */ UUID.randomUUID().toString())),
race, Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE,
/* delayToLiveInMillis */1000, /* millisecondsOverWhichToAverageWind */30000,
/* millisecondsOverWhichToAverageSpeed */30000, /*useMarkPassingCalculator*/ false, OneDesignRankingMetric::new, mock(RaceLogAndTrackedRaceResolver.class), null);
/* trackedRegatta */new DynamicTrackedRegattaImpl(new RegattaImpl("test", null, true,
CompetitorRegistrationType.CLOSED, null, null, new HashSet<Series>(), false, null, "test", null,
OneDesignRankingMetric::new, /* registrationLinkSecret */ UUID.randomUUID().toString())),
race, Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, /* delayToLiveInMillis */1000,
/* millisecondsOverWhichToAverageWind */30000, /* millisecondsOverWhichToAverageSpeed */30000,
/* useMarkPassingCalculator */ false, OneDesignRankingMetric::new,
mock(RaceLogAndTrackedRaceResolver.class), /* trackingConnectorInfo */ null);
TimePoint now = MillisecondsTimePoint.now();
TimePoint later = now.plus(1000);
trackedRace.updateMarkPassings(competitor, Arrays.asList(new MarkPassing[] { new MarkPassingImpl(now, waypoint, competitor) }));
@@ -318,7 +318,7 @@ public class WindTest {
EmptyWindStore.INSTANCE, /* delayToLiveInMillis */ 1000,
/* millisecondsOverWhichToAverageWind */ 30000,
/* millisecondsOverWhichToAverageSpeed */ 30000, /*useMarkPassingCalculator*/ false, OneDesignRankingMetric::new,
mock(RaceLogAndTrackedRaceResolver.class), null);
mock(RaceLogAndTrackedRaceResolver.class), /* trackingConnectorInfo */ null);
TimePoint start = MillisecondsTimePoint.now();
TimePoint topMarkRounding = start.plus(30000);
TimePoint finish = topMarkRounding.plus(30000);
@@ -105,8 +105,9 @@ public abstract class AbstractExportedPositionsBasedTest {
competitorsAndBoats, UUID.randomUUID()),
/* sidelines */ Collections.emptySet(),
EmptyWindStore.INSTANCE,
/* delayToLiveInMillis */ 3000, /* millisecondsOverWhichToAverageWind */ 15000, /* millisecondsOverWhichToAverageSpeed */ 10000,
/* useInternalMarkPassingAlgorithm */ true, OneDesignRankingMetric::new, /* raceLogResolver */ null, null);
/* delayToLiveInMillis */ 3000, /* millisecondsOverWhichToAverageWind */ 15000,
/* millisecondsOverWhichToAverageSpeed */ 10000, /* useInternalMarkPassingAlgorithm */ true,
OneDesignRankingMetric::new, /* raceLogResolver */ null, /* trackingConnectorInfo */ null);
result.setStatus(new TrackedRaceStatusImpl(TrackedRaceStatusEnum.LOADING, 0.0));
for (final Entry<CompetitorWithBoat, Iterable<GPSFixMoving>> e : competitorsAndTheirTracks.entrySet()) {
final DynamicGPSFixTrack<Competitor, GPSFixMoving> track = result.getTrack(e.getKey());
@@ -88,7 +88,7 @@ public class AbstractMockedRaceMarkPassingTest {
race = new DynamicTrackedRaceImpl(new DynamicTrackedRegattaImpl(r), raceDef, new ArrayList<Sideline>(),
new EmptyWindStore(), 0, 10000, 10000, /* useMarkPassingCalculator */ false,
OneDesignRankingMetric::new,
mock(RaceLogAndTrackedRaceResolver.class), null);
mock(RaceLogAndTrackedRaceResolver.class), /* trackingConnectorInfo */ null);
race.setStartTimeReceived(new MillisecondsTimePoint(10000));
TimePoint t = new MillisecondsTimePoint(30000);
List<Util.Pair<Mark, Position>> pos = Arrays.asList(new Util.Pair<Mark, Position>(m, new DegreePosition(0, 0)),
@@ -77,6 +77,7 @@ import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
import com.sap.sailing.domain.tracking.TrackingConnectorInfo;
import com.sap.sailing.domain.tracking.TrackingDataLoader;
import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingAndORCPerformanceCurveCache;
import com.sap.sailing.domain.tracking.WindPositionMode;
@@ -657,7 +658,9 @@ public class MockedTrackedRace implements DynamicTrackedRace {
WindStore windStore, long delayToLiveInMillis,
long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed,
DynamicRaceDefinitionSet raceDefinitionSetToUpdate, boolean useMarkPassingcalculator,
RaceLogAndTrackedRaceResolver raceLogResolver, Optional<ThreadLocalTransporter> threadLocalTransporter, String trackingConnector) {
RaceLogAndTrackedRaceResolver raceLogResolver,
Optional<ThreadLocalTransporter> threadLocalTransporter,
TrackingConnectorInfo trackingConnectorInfo) {
return null;
}
@@ -1285,7 +1288,7 @@ public class MockedTrackedRace implements DynamicTrackedRace {
}
@Override
public String getTrackingConnector() {
public TrackingConnectorInfo getTrackingConnectorInfo() {
return null;
}
@@ -58,6 +58,7 @@ import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
import com.sap.sailing.domain.tracking.TrackedRegatta;
import com.sap.sailing.domain.tracking.TrackingConnectorInfo;
import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingAndORCPerformanceCurveCache;
import com.sap.sailing.domain.tracking.WindPositionMode;
import com.sap.sailing.domain.tracking.WindStore;
@@ -809,7 +810,7 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
}
@Override
public String getTrackingConnector() {
public TrackingConnectorInfo getTrackingConnectorInfo() {
return null;
}
@@ -122,6 +122,6 @@ public class TrackedRegattaTest {
RaceDefinition race1 = new RaceDefinitionImpl(name, course, boatClass, Collections.emptyMap());
return new DynamicTrackedRaceImpl(regatta, race1, Collections.<Sideline> emptyList(),
EmptyWindStore.INSTANCE, 0, 0, 0, /* useMarkPassingCalculator */ false, OneDesignRankingMetric::new,
mock(RaceLogAndTrackedRaceResolver.class), null);
mock(RaceLogAndTrackedRaceResolver.class), /* trackingConnectorInfo */ null);
}
}
@@ -55,6 +55,7 @@ import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.domain.common.impl.DegreePosition;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.common.tracking.TrackingConnectorType;
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
@@ -74,11 +75,13 @@ import com.sap.sailing.domain.tracking.RaceTrackingConnectivityParameters;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRegatta;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
import com.sap.sailing.domain.tracking.TrackingConnectorInfo;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.domain.tracking.impl.FinishTimeUpdateHandler;
import com.sap.sailing.domain.tracking.impl.RaceAbortedHandler;
import com.sap.sailing.domain.tracking.impl.StartTimeUpdateHandler;
import com.sap.sailing.domain.tracking.impl.TrackingConnectorInfoImpl;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
import com.sap.sailing.domain.tractracadapter.JSONService;
import com.sap.sailing.domain.tractracadapter.MetadataParser;
@@ -116,7 +119,6 @@ import com.tractrac.subscription.lib.api.SubscriberInitializationException;
import difflib.PatchFailedException;
public class DomainFactoryImpl implements DomainFactory {
public static final String TRAC_TRAC = "tracTrac";
private static final Logger logger = Logger.getLogger(DomainFactoryImpl.class.getName());
@@ -643,9 +645,13 @@ public class DomainFactoryImpl implements DomainFactory {
// add to existing regatta only if boat class matches
if (raceDefinition.getBoatClass() == trackedRegatta.getRegatta().getBoatClass()) {
trackedRegatta.getRegatta().addRace(raceDefinition);
TrackingConnectorInfo trackingConnectorInfo = null;
if (tractracRace != null) {
trackingConnectorInfo = new TrackingConnectorInfoImpl(TrackingConnectorType.TracTrac, tractracRace.getEvent().getWebURL());
}
trackedRace = createTrackedRace(trackedRegatta, raceDefinition, sidelines, windStore,
delayToLiveInMillis, millisecondsOverWhichToAverageWind, raceDefinitionSetToUpdate, ignoreTracTracMarkPassings,
raceLogResolver, raceTrackingHandler);
raceLogResolver, raceTrackingHandler, trackingConnectorInfo);
logger.info("Added race " + raceDefinition + " to regatta " + trackedRegatta.getRegatta());
if (runBeforeExposingRace != null) {
logger.fine("Running callback for tracked race creation for "+trackedRace.getRace());
@@ -742,11 +748,13 @@ public class DomainFactoryImpl implements DomainFactory {
private DynamicTrackedRace createTrackedRace(TrackedRegatta trackedRegatta, RaceDefinition race,
Iterable<Sideline> sidelines, WindStore windStore, long delayToLiveInMillis,
long millisecondsOverWhichToAverageWind, DynamicRaceDefinitionSet raceDefinitionSetToUpdate,
boolean useMarkPassingCalculator, RaceLogAndTrackedRaceResolver raceLogResolver, RaceTrackingHandler raceTrackingHandler) {
boolean useMarkPassingCalculator, RaceLogAndTrackedRaceResolver raceLogResolver,
RaceTrackingHandler raceTrackingHandler, TrackingConnectorInfo trackingConnectorInfo) {
return raceTrackingHandler.createTrackedRace(trackedRegatta, race, sidelines,
windStore, delayToLiveInMillis, millisecondsOverWhichToAverageWind,
/* time over which to average speed: */ race.getBoatClass().getApproximateManeuverDurationInMilliseconds(),
raceDefinitionSetToUpdate, useMarkPassingCalculator, raceLogResolver, Optional.empty(), TRAC_TRAC);
raceDefinitionSetToUpdate, useMarkPassingCalculator, raceLogResolver, Optional.empty(),
trackingConnectorInfo);
}
/**
@@ -20,6 +20,7 @@ import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.common.PassingInstruction;
import com.sap.sailing.domain.common.tracking.TrackingConnectorType;
import com.sap.sailing.domain.leaderboard.LeaderboardGroupResolver;
import com.sap.sailing.domain.racelog.RaceLogAndTrackedRaceResolver;
import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet;
@@ -28,6 +29,7 @@ import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.RaceTrackingHandler;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.impl.TrackingConnectorInfoImpl;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
import com.sap.sailing.domain.tractracadapter.TracTracControlPoint;
import com.sap.sse.common.TimePoint;
@@ -269,7 +271,7 @@ public class RaceCourseReceiver extends AbstractReceiverWithQueue<IControlRoute,
raceDefinitionSetToUpdate, useInternalMarkPassingAlgorithm, raceLogResolver,
/* ThreadLocalTransporter not needed because the RaceTracker is not active on a replica */ Optional
.empty(),
DomainFactoryImpl.TRAC_TRAC);
new TrackingConnectorInfoImpl(TrackingConnectorType.TracTrac, tractracRace.getEvent().getWebURL()));
if (runAfterCreatingTrackedRace != null) {
runAfterCreatingTrackedRace.accept(trackedRace);
}
@@ -17,6 +17,7 @@ import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackingConnectorInfo;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
@@ -104,17 +105,18 @@ public class EventImpl extends EventBaseImpl implements Event {
}
@Override
public boolean isTrackedByTracTrac() {
public Set<TrackingConnectorInfo> getTrackingConnectorInfos() {
final Set<TrackingConnectorInfo> result = new HashSet<>();
for (LeaderboardGroup lbg : this.getLeaderboardGroups()) {
for (Leaderboard lb : lbg.getLeaderboards()) {
//Leaderboard.getTrackedRaces() could lead to performance issues due to duplicative collection of TrackedRaces
for (TrackedRace tr : lb.getTrackedRaces()) {
if("tracTrac".equals(tr.getTrackingConnector())){
return true;
final TrackingConnectorInfo trackingConnectorInfo = tr.getTrackingConnectorInfo();
if (trackingConnectorInfo != null) {
result.add(trackingConnectorInfo);
}
}
}
}
return false;
return result;
}
}
@@ -747,7 +747,7 @@ public class DummyTrackedRace extends TrackedRaceWithWindEssentials {
}
@Override
public String getTrackingConnector() {
public TrackingConnectorInfo getTrackingConnectorInfo() {
return null;
}
@@ -35,8 +35,9 @@ public interface RaceTrackingHandler {
Iterable<Sideline> sidelines, WindStore windStore, long delayToLiveInMillis,
long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed,
DynamicRaceDefinitionSet raceDefinitionSetToUpdate, boolean useMarkPassingCalculator,
RaceLogAndTrackedRaceResolver raceLogResolver, Optional<ThreadLocalTransporter> threadLocalTransporter, String trackingConnector);
RaceLogAndTrackedRaceResolver raceLogResolver, Optional<ThreadLocalTransporter> threadLocalTransporter,
TrackingConnectorInfo trackingConnectorInfo);
DynamicCompetitor getOrCreateCompetitor(CompetitorAndBoatStore competitorAndBoatStore, Serializable competitorId,
String name, String shortName, Color displayColor, String email, URI flagImageURI, DynamicTeam team,
Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag);
@@ -58,10 +59,11 @@ public interface RaceTrackingHandler {
Iterable<Sideline> sidelines, WindStore windStore, long delayToLiveInMillis,
long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed,
DynamicRaceDefinitionSet raceDefinitionSetToUpdate, boolean useMarkPassingCalculator,
RaceLogAndTrackedRaceResolver raceLogResolver, Optional<ThreadLocalTransporter> threadLocalTransporter, String trackingConnector) {
RaceLogAndTrackedRaceResolver raceLogResolver, Optional<ThreadLocalTransporter> threadLocalTransporter,
TrackingConnectorInfo trackingConnectorInfo) {
return trackedRegatta.createTrackedRace(raceDefinition, sidelines, windStore, delayToLiveInMillis,
millisecondsOverWhichToAverageWind, millisecondsOverWhichToAverageSpeed, raceDefinitionSetToUpdate,
useMarkPassingCalculator, raceLogResolver, threadLocalTransporter, trackingConnector);
useMarkPassingCalculator, raceLogResolver, threadLocalTransporter, trackingConnectorInfo);
}
@Override
@@ -1249,7 +1249,8 @@ public interface TrackedRace
}
/**
* gets a String representation of the Tracking-Service used to Track the Race
* gets a {@link TrackingConnectorInfo}, which contains a String representation of the Tracking-Service used to Track the Race and a web-URL for the Event Event;
* may be {@code null}, particularly in test set-ups
*/
String getTrackingConnector();
TrackingConnectorInfo getTrackingConnectorInfo();
}
@@ -67,7 +67,7 @@ public interface TrackedRegatta extends Serializable {
DynamicTrackedRace createTrackedRace(RaceDefinition raceDefinition, Iterable<Sideline> sidelines, WindStore windStore,
long delayToLiveInMillis, long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed,
DynamicRaceDefinitionSet raceDefinitionSetToUpdate, boolean useInternalMarkPassingAlgorithm, RaceLogAndTrackedRaceResolver raceLogResolver,
Optional<ThreadLocalTransporter> beforeAndAfterNotificationHandler, String trackingConnector);
Optional<ThreadLocalTransporter> beforeAndAfterNotificationHandler, TrackingConnectorInfo trackingConnectorInfo);
/**
* Obtains the tracked race for <code>race</code>. Blocks until the tracked race has been created
@@ -64,6 +64,7 @@ import com.sap.sailing.domain.tracking.TrackFactory;
import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
import com.sap.sailing.domain.tracking.TrackedRegatta;
import com.sap.sailing.domain.tracking.TrackingConnectorInfo;
import com.sap.sailing.domain.tracking.TrackingDataLoader;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.WindTrack;
@@ -119,10 +120,10 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
WindStore windStore, long delayToLiveInMillis, long millisecondsOverWhichToAverageWind,
long millisecondsOverWhichToAverageSpeed, long delayForCacheInvalidationOfWindEstimation,
boolean useInternalMarkPassingAlgorithm, RankingMetricConstructor rankingMetricConstructor,
RaceLogAndTrackedRaceResolver raceLogResolver, String trackingConnector) {
RaceLogAndTrackedRaceResolver raceLogResolver, TrackingConnectorInfo trackingConnectorInfo) {
super(trackedRegatta, race, sidelines, windStore, delayToLiveInMillis, millisecondsOverWhichToAverageWind,
millisecondsOverWhichToAverageSpeed, delayForCacheInvalidationOfWindEstimation,
useInternalMarkPassingAlgorithm, rankingMetricConstructor, raceLogResolver, trackingConnector);
useInternalMarkPassingAlgorithm, rankingMetricConstructor, raceLogResolver, trackingConnectorInfo);
raceStateBasedStartTimeChangedListener = createRaceStateStartTimeChangeListener();
this.competitorResultsFromRaceLog = new HashMap<>();
this.logListener = new DynamicTrackedRaceLogListener(this);
@@ -210,10 +211,10 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
public DynamicTrackedRaceImpl(TrackedRegatta trackedRegatta, RaceDefinition race, Iterable<Sideline> sidelines,
WindStore windStore, long delayToLiveInMillis, long millisecondsOverWhichToAverageWind,
long millisecondsOverWhichToAverageSpeed, boolean useInternalMarkPassingAlgorithm,
RankingMetricConstructor rankingMetricConstructor, RaceLogAndTrackedRaceResolver raceLogResolver, String trackingConnector) {
RankingMetricConstructor rankingMetricConstructor, RaceLogAndTrackedRaceResolver raceLogResolver, TrackingConnectorInfo trackingConnectorInfo) {
this(trackedRegatta, race, sidelines, windStore, delayToLiveInMillis,
millisecondsOverWhichToAverageWind, millisecondsOverWhichToAverageSpeed,
millisecondsOverWhichToAverageWind / 2, useInternalMarkPassingAlgorithm, rankingMetricConstructor, raceLogResolver, trackingConnector);
millisecondsOverWhichToAverageWind / 2, useInternalMarkPassingAlgorithm, rankingMetricConstructor, raceLogResolver, trackingConnectorInfo);
}
@Override
@@ -144,6 +144,7 @@ import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
import com.sap.sailing.domain.tracking.TrackedRaceWithWindEssentials;
import com.sap.sailing.domain.tracking.TrackedRegatta;
import com.sap.sailing.domain.tracking.TrackingConnectorInfo;
import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingAndORCPerformanceCurveCache;
import com.sap.sailing.domain.tracking.WindPositionMode;
import com.sap.sailing.domain.tracking.WindStore;
@@ -188,7 +189,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
private TrackedRaceStatus status;
private final String trackingConnector;
private final TrackingConnectorInfo trackingConnectorInfo;
private final Object statusNotifier;
@@ -434,10 +435,10 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
public TrackedRaceImpl(final TrackedRegatta trackedRegatta, RaceDefinition race, final Iterable<Sideline> sidelines,
final WindStore windStore, long delayToLiveInMillis, final long millisecondsOverWhichToAverageWind,
long millisecondsOverWhichToAverageSpeed, long delayForWindEstimationCacheInvalidation,
boolean useInternalMarkPassingAlgorithm, RaceLogAndTrackedRaceResolver raceLogResolver, String trackedBy) {
boolean useInternalMarkPassingAlgorithm, RaceLogAndTrackedRaceResolver raceLogResolver, TrackingConnectorInfo trackingConnectorInfo) {
this(trackedRegatta, race, sidelines, windStore, delayToLiveInMillis, millisecondsOverWhichToAverageWind,
millisecondsOverWhichToAverageSpeed, delayForWindEstimationCacheInvalidation,
useInternalMarkPassingAlgorithm, OneDesignRankingMetric::new, raceLogResolver, trackedBy);
useInternalMarkPassingAlgorithm, OneDesignRankingMetric::new, raceLogResolver, trackingConnectorInfo);
}
/**
@@ -451,10 +452,10 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
final WindStore windStore, long delayToLiveInMillis, final long millisecondsOverWhichToAverageWind,
long millisecondsOverWhichToAverageSpeed, long delayForWindEstimationCacheInvalidation,
boolean useInternalMarkPassingAlgorithm, RankingMetricConstructor rankingMetricConstructor,
RaceLogAndTrackedRaceResolver raceLogResolver, String trackingConnector) {
RaceLogAndTrackedRaceResolver raceLogResolver, TrackingConnectorInfo trackingConnectorInfo) {
super(race, trackedRegatta, windStore, millisecondsOverWhichToAverageWind);
this.raceLogResolver = raceLogResolver;
this.trackingConnector = trackingConnector;
this.trackingConnectorInfo = trackingConnectorInfo;
raceStates = new WeakHashMap<>();
shortTimeWindCache = new ShortTimeWindCache(this, millisecondsOverWhichToAverageWind / 2);
locksForMarkPassings = new ConcurrentHashMap<IdentityWrapper<Iterable<MarkPassing>>, NamedReentrantReadWriteLock>();
@@ -3974,7 +3975,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
}
@Override
public String getTrackingConnector() {
return trackingConnector;
public TrackingConnectorInfo getTrackingConnectorInfo() {
return trackingConnectorInfo;
}
}
@@ -29,6 +29,7 @@ import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.RaceListener;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRegatta;
import com.sap.sailing.domain.tracking.TrackingConnectorInfo;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
@@ -321,13 +322,13 @@ public class TrackedRegattaImpl implements TrackedRegatta {
WindStore windStore, long delayToLiveInMillis,
long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed,
DynamicRaceDefinitionSet raceDefinitionSetToUpdate, boolean useInternalMarkPassingAlgorithm, RaceLogAndTrackedRaceResolver raceLogResolver,
Optional<ThreadLocalTransporter> threadLocalTransporter, String trackingConnector) {
Optional<ThreadLocalTransporter> threadLocalTransporter, TrackingConnectorInfo trackingConnectorInfo) {
logger.log(Level.INFO, "Creating DynamicTrackedRaceImpl for RaceDefinition " + raceDefinition.getName());
DynamicTrackedRaceImpl result = new DynamicTrackedRaceImpl(this, raceDefinition, sidelines, windStore,
delayToLiveInMillis, millisecondsOverWhichToAverageWind,
millisecondsOverWhichToAverageSpeed,
/* useMarkPassingCalculator */useInternalMarkPassingAlgorithm, getRegatta().getRankingMetricConstructor(), raceLogResolver,
trackingConnector);
trackingConnectorInfo);
// adding the raceDefinition to the raceDefinitionSetToUpdate BEFORE calling addTrackedRace helps those who
// are called back by RaceListener.raceAdded(TrackedRace) and who then expect the update to have happened
if (raceDefinitionSetToUpdate != null) {
@@ -64,6 +64,7 @@ import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
import com.sap.sailing.domain.tracking.TrackingConnectorInfo;
import com.sap.sailing.domain.tracking.TrackingDataLoader;
import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingAndORCPerformanceCurveCache;
import com.sap.sailing.domain.tracking.WindPositionMode;
@@ -336,7 +337,7 @@ public class MockedTrackedRace implements DynamicTrackedRace {
public DynamicTrackedRace createTrackedRace(RaceDefinition raceDefinition, Iterable<Sideline> sidelines, WindStore windStore,
long delayToLiveInMillis, long millisecondsOverWhichToAverageWind,
long millisecondsOverWhichToAverageSpeed, DynamicRaceDefinitionSet raceDefinitionSetToUpdate,
boolean useMarkPassingCalculator, RaceLogAndTrackedRaceResolver raceLogResolver, Optional<ThreadLocalTransporter> threadLocalTransporter, String trackingConnector) {
boolean useMarkPassingCalculator, RaceLogAndTrackedRaceResolver raceLogResolver, Optional<ThreadLocalTransporter> threadLocalTransporter, TrackingConnectorInfo trackingConnectorInfo) {
return null;
}
@@ -962,7 +963,7 @@ public class MockedTrackedRace implements DynamicTrackedRace {
}
@Override
public String getTrackingConnector() {
public TrackingConnectorInfo getTrackingConnectorInfo() {
return null;
}
+17
View File
@@ -697,6 +697,15 @@ img.openColumn {
color: white;
}
.RegattaAndRaceTime-Header_with_databy {
top: 3px;
}
.compactHeader .RegattaAndRaceTime-Header.RegattaAndRaceTime-Header_with_databy {
top: 0;
font-size: 90%;
}
.RegattaAndRaceTime-Header .RegattaName-Anchor {
font-size: 15px;
color: white;
@@ -717,6 +726,14 @@ img.openColumn {
margin-top: 5px;
}
.compactHeader .RegattaAndRaceTime-Header>* {
margin-top: 3px;
}
.RegattaAndRaceTime-Header_with_databy .RegattaName-Anchor, .RegattaAndRaceTime-Header_with_databy .RaceTime-Label {
font-size: 13px;
}
.compactHeader .RegattaRaceInformation-Header {
left: 110px;
}
@@ -77,7 +77,7 @@ public class LiveRaceBoardNode extends FiresPlaceNode implements RaceTimesInfoPr
/** leaderboardGroupName */
null, /** eventId */
null, cf.getErrorReporter(), StringMessages.INSTANCE, null, raceTimesInfoProvider, true, false,
Arrays.asList(DetailType.values()), result.getLeaderboard(), result.getRace());
Arrays.asList(DetailType.values()), result.getLeaderboard(), result.getRace(), result.getTrackingConnectorInfo());
setPlaceToGo(new LiveRaceWithRaceboardPlace(raceboardPerspective));
firePlaceChangeAndStartTimer();
getBus().fireEvent(new AutoPlayHeaderEvent(cf.getAutoPlayCtxSignalError().getLifeOrPreLiveRace().getRegattaName(),
@@ -8,6 +8,7 @@ import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import com.google.gwt.core.shared.GwtIncompatible;
import com.sap.sailing.domain.base.Event;
@@ -22,6 +23,7 @@ import com.sap.sailing.gwt.home.server.EventActionUtil;
import com.sap.sailing.gwt.home.server.EventActionUtil.LeaderboardCallback;
import com.sap.sailing.gwt.home.server.LeaderboardContext;
import com.sap.sailing.gwt.server.HomeServiceUtil;
import com.sap.sailing.gwt.ui.shared.TrackingConnectorInfoDTO;
import com.sap.sse.common.Util;
import com.sap.sse.common.media.MediaTagConstants;
import com.sap.sse.gwt.dispatch.shared.caching.IsClientCacheable;
@@ -118,8 +120,10 @@ public class GetEventViewAction implements SailingAction<EventViewDTO>, IsClient
singleLeaderboardGroup.getId(), eventAndLeaderboardReferencesForSeriesOrdered));
}
}
dto.setTrackedByTracTrac(event.isTrackedByTracTrac());
Set<TrackingConnectorInfoDTO> trackingConnectorInfos = event.getTrackingConnectorInfos().stream()
.map(TrackingConnectorInfoDTO::new).collect(Collectors.toSet());
dto.setTrackingConnectorInfos(trackingConnectorInfos);
return dto;
}
@@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import com.sap.sailing.domain.common.WindSource;
@@ -11,6 +12,7 @@ import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.domain.common.windfinder.SpotDTO;
import com.sap.sailing.gwt.home.communication.event.EventMetadataDTO;
import com.sap.sailing.gwt.home.communication.event.HasLogo;
import com.sap.sailing.gwt.ui.shared.TrackingConnectorInfoDTO;
import com.sap.sse.common.Util;
import com.sap.sse.gwt.client.media.ImageDTO;
import com.sap.sse.gwt.dispatch.shared.commands.Result;
@@ -27,7 +29,7 @@ public class EventViewDTO extends EventMetadataDTO implements Result, HasLogo {
private String sailorsInfoWebsiteURL;
private String description;
private List<SpotDTO> allWindFinderSpotIdsUsedByEvent;
private boolean isTrackedByTracTrac;
private Set<TrackingConnectorInfoDTO> trackingConnectorInfos;
public Collection<RegattaMetadataDTO> getRegattas() {
@@ -143,12 +145,12 @@ public class EventViewDTO extends EventMetadataDTO implements Result, HasLogo {
public boolean isMultiRegatta() {
return multiRegatta;
}
public boolean isTrackedByTracTrac() {
return isTrackedByTracTrac;
public Set<TrackingConnectorInfoDTO> getTrackingConnectorInfos() {
return trackingConnectorInfos;
}
public void setTrackedByTracTrac(boolean isTrackedByTracTrac) {
this.isTrackedByTracTrac = isTrackedByTracTrac;
public void setTrackingConnectorInfos(Set<TrackingConnectorInfoDTO> trackingConnectorInfo) {
this.trackingConnectorInfos = trackingConnectorInfo;
}
}
@@ -1,13 +1,15 @@
package com.sap.sailing.gwt.home.communication.start;
import java.util.Set;
import com.sap.sailing.gwt.home.communication.event.EventLinkAndMetadataDTO;
import com.sap.sailing.gwt.ui.shared.TrackingConnectorInfoDTO;
public class EventStageDTO extends EventLinkAndMetadataDTO {
private StageEventType stageType;
private String stageImageURL;
private boolean isTrackedByTracTrac;
private Set<TrackingConnectorInfoDTO> trackingConnectorInfo;
@Override
public StageEventType getStageType() {
@@ -25,11 +27,12 @@ public class EventStageDTO extends EventLinkAndMetadataDTO {
public void setStageImageURL(String stageImageURL) {
this.stageImageURL = stageImageURL;
}
public boolean isTrackedByTracTrac() {
return isTrackedByTracTrac;
public Set<TrackingConnectorInfoDTO> getTrackingConnectorInfos() {
return trackingConnectorInfo;
}
public void setTrackedByTracTrac(boolean isTrackedByTracTrac) {
this.isTrackedByTracTrac = isTrackedByTracTrac;
public void setTrackingConnectorInfos(Set<TrackingConnectorInfoDTO> trackingConnectorInfo) {
this.trackingConnectorInfo = trackingConnectorInfo;
}
}
@@ -173,6 +173,7 @@
margin: 0.266666666666667em 0 0.266666666666667em 0.333333333333333em;
padding-left: 0.666666666666667em;
color: #666;
vertical-align: middle;
}
.eventheader_intro_details_itemlink {
color: inherit;
@@ -191,14 +192,6 @@
.eventheader_status_body {
font-size: 1rem;
}
.eventheader_dataBy_logo_container{
display: inline-block;
white-space: nowrap;
font-size: 0.75em;
}
.eventheader_dataBy_logo{
height: 1.3333333em !important;
}
.locationicon {
vertical-align: text-bottom;
margin-right: 0.333333333333333em;
@@ -273,4 +266,3 @@
.eventnavigation .navbar_button {
font-size: 1.2rem;
}
@@ -30,6 +30,7 @@ import com.sap.sailing.gwt.home.shared.utils.EventDatesFormatterUtil;
import com.sap.sailing.gwt.home.shared.utils.LabelTypeUtil;
import com.sap.sailing.gwt.home.shared.utils.LogoUtil;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.databylogo.DataByLogo;
import com.sap.sse.common.Util;
import com.sap.sse.gwt.client.LinkUtil;
@@ -60,7 +61,7 @@ public class EventHeader extends Composite {
@UiField DivElement courseAreaUi;
@UiField FlowPanel dropdownContent;
@UiField SharingButtons sharing;
@UiField AnchorElement tractracLogoContainer;
@UiField DataByLogo dataByLogo;
private EventViewDTO event;
private Presenter presenter;
@@ -150,9 +151,7 @@ public class EventHeader extends Composite {
}
hide(competitors, races, courseAreaUi, eventCategory);
}
if(!event.isTrackedByTracTrac()) {
hide(tractracLogoContainer);
}
dataByLogo.setUp(event.getTrackingConnectorInfos(), /** colorIfPossible **/ true, /** enforceTextColor **/ false);
initTitleAndSelection(nameToShow);
}
@@ -1,6 +1,7 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:dp="urn:import:com.sap.sailing.gwt.home.desktop.partials">
xmlns:dp="urn:import:com.sap.sailing.gwt.home.desktop.partials"
xmlns:s="urn:import:com.sap.sailing.gwt.ui.shared">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.desktop.partials.eventheader.EventHeaderResources" />
@@ -46,10 +47,7 @@
<span ui:field="eventVenue"></span>
</div>
<a ui:field="eventLink" class="{local_res.css.eventheader_intro_details_item}"></a>
<a ui:field="tractracLogoContainer" target="_blank" href="https://www.tractrac.com" class="{local_res.css.eventheader_intro_details_item} {local_res.css.eventheader_dataBy_logo_container}">
<ui:text from="{i18n.dataBy}"/>
<img src="{local_res.tractrac.getSafeUri}" class="{local_res.css.eventheader_dataBy_logo}"></img>
</a>
<s:databylogo.DataByLogo ui:field="dataByLogo" addStyleNames="{local_res.css.eventheader_intro_details_item}"></s:databylogo.DataByLogo>
<!-- IFEND event.venue && event.eventType !== 'multi-regatta-event' -->
<!-- IF event.eventType === 'multi-regatta-event' -->
<div ui:field="competitors" class="{local_res.css.eventheader_intro_details_item}" />
@@ -2,8 +2,6 @@ package com.sap.sailing.gwt.home.desktop.partials.eventheader;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.DataResource;
import com.google.gwt.resources.client.DataResource.MimeType;
import com.google.gwt.resources.client.ImageResource;
import com.sap.sailing.gwt.home.desktop.resources.SharedDesktopResources;
@@ -16,10 +14,6 @@ public interface EventHeaderResources extends SharedDesktopResources {
@Source("location-icon.png")
ImageResource location();
@Source("tractrac-color.svg")
@MimeType("image/svg+xml")
DataResource tractrac();
public interface LocalCss extends CssResource {
String jsdropdown();
String jsdropdown_head();
@@ -47,8 +41,6 @@ public interface EventHeaderResources extends SharedDesktopResources {
String eventheader_status();
String eventheader_status_title();
String eventheader_status_body();
String eventheader_dataBy_logo();
String eventheader_dataBy_logo_container();
String locationicon();
String eventnavigation();
String eventnavigationnormal();
@@ -60,5 +52,4 @@ public interface EventHeaderResources extends SharedDesktopResources {
String navbar_button();
String navbar_buttonhidden();
}
}
@@ -209,3 +209,14 @@
-ms-transition: width 0.1s linear;
transition: width 0.1s linear;
}
.stage_dataBy_logo_container{
padding: 0 0.4em;
line-height: 4rem;
}
.stage_dataBy_logo_container>*{
display: inline-block !important;
vertical-align: middle;
}
.stageteaser_rightbound_bond_item{
float: right;
}
@@ -30,6 +30,7 @@ public interface StageResources extends ClientBundle {
String stageteaser_content_band_text_headline();
String stageteaser_content_band_text_name();
String stageteaser_content_band_action();
String stageteaser_rightbound_bond_item();
String swipercontainer();
String swiperslide();
String stage();
@@ -37,6 +38,7 @@ public interface StageResources extends ClientBundle {
String stage_controls();
String stage_progress();
String stage_progress_bar();
String stage_dataBy_logo_container();
}
}
@@ -16,6 +16,7 @@ import com.sap.sailing.gwt.home.desktop.app.DesktopPlacesNavigator;
import com.sap.sailing.gwt.home.shared.app.PlaceNavigation;
import com.sap.sailing.gwt.home.shared.app.PlaceNavigator;
import com.sap.sailing.gwt.home.shared.places.event.EventDefaultPlace;
import com.sap.sailing.gwt.ui.shared.databylogo.DataByLogo;
public abstract class StageTeaserBand extends Composite {
@@ -28,6 +29,7 @@ public abstract class StageTeaserBand extends Composite {
@UiField SpanElement bandSubtitle;
@UiField Anchor actionLink;
@UiField DivElement isLiveDiv;
@UiField DataByLogo dataByLogo;
private final DesktopPlacesNavigator placeNavigator;
private final EventStageDTO event;
@@ -41,6 +43,8 @@ public abstract class StageTeaserBand extends Composite {
initWidget(uiBinder.createAndBindUi(this));
isLiveDiv.getStyle().setDisplay(Display.NONE);
dataByLogo.setUp(event.getTrackingConnectorInfos(), /** colorIfPossible **/ false, /** enforceTextColor **/ true);
eventNavigation = placeNavigator.getEventNavigation(event.getId().toString(), event.getBaseURL(), event.isOnRemoteServer());
}
@@ -1,10 +1,13 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:s="urn:import:com.sap.sailing.gwt.ui.shared">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages"/>
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.desktop.partials.stage.StageResources" />
<g:HTMLPanel styleName="{local_res.css.stageteaser_content_band_item} {res.mediaCss.columns}">
<g:Anchor ui:field="actionLink" styleName="{res.mainCss.button} {local_res.css.stageteaser_content_band_action}" />
<div class="{local_res.css.stageteaser_rightbound_bond_item}">
<g:Anchor ui:field="actionLink" styleName="{res.mainCss.button} {local_res.css.stageteaser_content_band_action}" />
</div>
<s:databylogo.DataByLogo ui:field="dataByLogo" addStyleNames="{local_res.css.stage_dataBy_logo_container} {local_res.css.stageteaser_rightbound_bond_item}" />
<div class="{local_res.css.stageteaser_content_band_text}">
<div class="{local_res.css.stageteaser_content_band_text_headline}">
<span ui:field="bandTitle" />
@@ -9,7 +9,8 @@
transition: top 0.3s ease-in-out;
}
.eventheader_with_logo{
padding-bottom: 1.5em;
padding-bottom: 0.5em;
position: relative;
}
.eventheader_info {
padding: 0.666666666666667em 0 0 0.666666666666667em;
@@ -56,18 +57,9 @@
.eventheader_info_subtitle_info_location {
visibility: visible;
}
.eventheader_info_subtitle_dataBy_logo{
height: 1.33333em !important;
}
.eventheader_info_subtitle_dataBy_logo_container{
position:absolute;
bottom:0.25em;
right:0.25em;
font-size: 0.75em;
display: inline-block;
color: black;
}
.subtleLink, .subtleLink:hover, .subtleLink:active, .subtleLink:visited, .subtleLink:focus {
text-decoration: none;
}
@@ -14,6 +14,7 @@ import com.sap.sailing.gwt.home.shared.app.PlaceNavigation;
import com.sap.sailing.gwt.home.shared.utils.EventDatesFormatterUtil;
import com.sap.sailing.gwt.home.shared.utils.LabelTypeUtil;
import com.sap.sailing.gwt.home.shared.utils.LogoUtil;
import com.sap.sailing.gwt.ui.shared.databylogo.DataByLogo;
public class EventHeader extends Composite {
private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
@@ -29,7 +30,7 @@ public class EventHeader extends Composite {
@UiField DivElement eventDateUi;
@UiField DivElement eventLocationUi;
@UiField DivElement eventHeader;
@UiField AnchorElement tractracLogoContainer;
@UiField DataByLogo dataByLogo;
public EventHeader(EventViewDTO event, String optionalRegattaDisplayName, PlaceNavigation<?> logoNavigation) {
EventHeaderResources.INSTANCE.css().ensureInjected();
@@ -50,10 +51,9 @@ public class EventHeader extends Composite {
if (logoNavigation != null) {
logoNavigation.configureAnchorElement(eventLogoUi);
}
if (event.isTrackedByTracTrac()) {
eventHeader.addClassName(EventHeaderResources.INSTANCE.css().eventheader_with_logo());
} else {
tractracLogoContainer.removeFromParent();
dataByLogo.setUp(event.getTrackingConnectorInfos(), /** colorIfPossible **/ true, /** enforceTextColor **/ true);
if (dataByLogo.isVisible()) {
this.addStyleName(EventHeaderResources.INSTANCE.css().eventheader_with_logo());
}
eventDateUi.setInnerText(EventDatesFormatterUtil.formatDateRangeWithYear(event.getStartDate(), event.getEndDate()));
eventLocationUi.setInnerText(event.getLocationAndVenueAndCountry());
@@ -1,6 +1,6 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared">
xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:s="urn:import:com.sap.sailing.gwt.ui.shared">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
@@ -40,11 +40,8 @@
</div>
</div>
</div>
<a ui:field="tractracLogoContainer" target="_blank" href="https://www.tractrac.com" class="{local_res.css.eventheader_info_subtitle_dataBy_logo_container} {local_res.css.subtleLink}">
<ui:text from="{i18n.dataBy}"/>
<img src="{local_res.tractrac.getSafeUri}" class="{local_res.css.eventheader_info_subtitle_dataBy_logo}"></img>
</a>
</div>
</div>
<s:databylogo.DataByLogo ui:field="dataByLogo" addStyleNames="{local_res.css.eventheader_info_subtitle_dataBy_logo_container}" />
</g:HTMLPanel>
</ui:UiBinder>
@@ -3,19 +3,12 @@ package com.sap.sailing.gwt.home.mobile.partials.eventheader;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.DataResource;
import com.google.gwt.resources.client.DataResource.MimeType;
public interface EventHeaderResources extends ClientBundle {
public static final EventHeaderResources INSTANCE = GWT.create(EventHeaderResources.class);
@Source("EventHeader.gss")
LocalCss css();
@Source("tractrac-color.svg")
@MimeType("image/svg+xml")
DataResource tractrac();
public interface LocalCss extends CssResource {
String eventheader();
@@ -31,8 +24,6 @@ public interface EventHeaderResources extends ClientBundle {
String eventheader_info_subtitle_info();
String eventheader_info_subtitle_info_date();
String eventheader_info_subtitle_info_location();
String eventheader_info_subtitle_dataBy_logo();
String eventheader_info_subtitle_dataBy_logo_container();
String subtleLink();
}
}
@@ -1 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 100 23" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><rect id="Artboard1" x="0" y="0" width="99.997" height="22.94" style="fill:none;"/><path d="M7.044,22.474l-3.981,0l2.681,-16.956l-4.117,0l0.542,-3.468l12.216,0l-0.542,3.468l-4.117,0l-2.682,16.956Z" style="fill:#005a84;fill-rule:nonzero;"/><path d="M16.185,8.781l0.054,0c0.948,-1.165 2.167,-1.815 3.576,-1.815c0.542,0 1.084,0.135 1.517,0.325l-1.002,3.522c-0.406,-0.325 -0.921,-0.488 -1.49,-0.488c-2.627,0 -3.278,2.329 -3.603,4.388l-0.948,5.986l-3.792,0l2.113,-13.299l3.792,0l-0.217,1.381Z" style="fill:#005a84;fill-rule:nonzero;"/><path d="M30.362,14.036c0.271,-1.788 -0.623,-3.711 -2.573,-3.711c-1.951,0 -3.467,1.923 -3.738,3.711c-0.271,1.787 0.596,3.738 2.546,3.738c1.95,0 3.494,-1.951 3.765,-3.738m2.303,6.664l-3.739,0l0.19,-1.219l-0.054,0c-0.975,1.056 -2.492,1.652 -3.873,1.652c-3.901,0 -5.554,-3.548 -4.985,-7.151c0.569,-3.522 3.359,-7.016 7.178,-7.016c1.382,0 2.709,0.596 3.441,1.68l0.216,-1.246l3.738,0l-2.112,13.3Z" style="fill:#005a84;fill-rule:nonzero;"/><path d="M45.568,11.462c-0.677,-0.812 -1.408,-1.299 -2.573,-1.299c-2.14,0 -3.684,2.004 -4.009,3.954c-0.325,2.086 0.731,3.82 2.898,3.82c1.03,0 2.059,-0.515 2.872,-1.274l-0.596,3.657c-1.111,0.569 -2.249,0.813 -3.414,0.813c-3.927,0 -6.203,-3.224 -5.579,-7.043c0.622,-3.955 4.009,-7.124 8.017,-7.124c1.057,0 2.14,0.271 2.953,0.84l-0.569,3.656Z" style="fill:#005a84;fill-rule:nonzero;"/><path d="M51.914,22.474l-3.982,0l2.682,-16.956l-4.118,0l0.542,-3.468l12.217,0l-0.542,3.468l-4.117,0l-2.682,16.956Z" style="fill:#009fc2;fill-rule:nonzero;"/><path d="M61.18,8.781l0.055,0c0.947,-1.165 2.167,-1.815 3.575,-1.815c0.541,0 1.084,0.135 1.517,0.325l-1.002,3.522c-0.406,-0.325 -0.921,-0.488 -1.49,-0.488c-2.627,0 -3.277,2.329 -3.603,4.388l-0.948,5.986l-3.792,0l2.113,-13.299l3.792,0l-0.217,1.381Z" style="fill:#009fc2;fill-rule:nonzero;"/><path d="M75.357,14.036c0.271,-1.788 -0.623,-3.711 -2.573,-3.711c-1.95,0 -3.467,1.923 -3.738,3.711c-0.271,1.787 0.596,3.738 2.546,3.738c1.951,0 3.494,-1.951 3.765,-3.738m2.302,6.664l-3.738,0l0.19,-1.219l-0.054,0c-0.975,1.056 -2.492,1.652 -3.874,1.652c-3.901,0 -5.553,-3.548 -4.983,-7.151c0.569,-3.522 3.358,-7.016 7.178,-7.016c1.381,0 2.708,0.596 3.439,1.68l0.218,-1.246l3.737,0l-2.113,13.3Z" style="fill:#009fc2;fill-rule:nonzero;"/><path d="M90.563,11.462c-0.677,-0.812 -1.409,-1.299 -2.573,-1.299c-2.14,0 -3.684,2.004 -4.009,3.954c-0.325,2.086 0.731,3.82 2.899,3.82c1.029,0 2.058,-0.515 2.871,-1.274l-0.597,3.657c-1.11,0.569 -2.248,0.813 -3.412,0.813c-3.928,0 -6.204,-3.224 -5.58,-7.043c0.623,-3.955 4.009,-7.124 8.017,-7.124c1.057,0 2.141,0.271 2.953,0.84l-0.569,3.656Z" style="fill:#009fc2;fill-rule:nonzero;"/><path d="M89.199,14.063c0,0.93 -0.753,1.683 -1.683,1.683c-0.929,0 -1.682,-0.753 -1.682,-1.683c0,-0.929 0.753,-1.683 1.682,-1.683c0.93,0 1.683,0.754 1.683,1.683" style="fill:#005a84;fill-rule:nonzero;"/><path d="M96.407,2.836c-1.148,-1.262 -2.668,-2.087 -4.333,-2.37l-0.161,1.206c1.38,0.245 2.639,0.935 3.593,1.984c1.034,1.137 1.608,2.588 1.647,4.115l1.217,0c-0.04,-1.831 -0.724,-3.573 -1.963,-4.935m-4.627,-0.169l-0.161,1.212c0.861,0.173 1.646,0.613 2.245,1.271c0.658,0.723 1.032,1.649 1.071,2.621l1.218,0c-0.039,-1.276 -0.526,-2.493 -1.389,-3.44c-0.792,-0.872 -1.837,-1.451 -2.984,-1.664m-0.294,2.207l-0.162,1.219c0.342,0.097 0.656,0.285 0.897,0.551c0.283,0.311 0.452,0.71 0.489,1.127l1.225,0c-0.038,-0.721 -0.326,-1.412 -0.813,-1.947c-0.435,-0.477 -1.009,-0.809 -1.636,-0.95" style="fill:#005a84;fill-rule:nonzero;"/></svg>

Before

Width:  |  Height:  |  Size: 3.8 KiB

@@ -206,5 +206,9 @@
background: #333;
}
.stageteaser_databylogo_container{
padding-top: .4em;
}
@external slick-dots, slick-active;
@@ -30,6 +30,7 @@ public interface StageResources extends ClientBundle {
String stageteaser_content_band_text_headline();
String stageteaser_content_band_text_name();
String stageteaser_content_band_action();
String stageteaser_databylogo_container();
String swipercontainer();
String swiperslide();
String stage();
@@ -10,10 +10,12 @@ import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.home.communication.event.EventLinkAndMetadataDTO;
import com.sap.sailing.gwt.home.communication.start.EventStageDTO;
import com.sap.sailing.gwt.home.mobile.app.MobilePlacesNavigator;
import com.sap.sailing.gwt.home.shared.app.PlaceNavigation;
import com.sap.sailing.gwt.home.shared.app.PlaceNavigator;
import com.sap.sailing.gwt.home.shared.places.event.EventDefaultPlace;
import com.sap.sailing.gwt.ui.shared.databylogo.DataByLogo;
public abstract class StageTeaserBand extends Composite {
@@ -26,7 +28,10 @@ public abstract class StageTeaserBand extends Composite {
DivElement bandTitle;
@UiField
DivElement bandSubtitle;
@UiField Anchor actionLink;
@UiField
Anchor actionLink;
@UiField
DataByLogo dataByLogo;
private final MobilePlacesNavigator placeNavigator;
private final EventLinkAndMetadataDTO event;
@@ -38,7 +43,13 @@ public abstract class StageTeaserBand extends Composite {
StageResources.INSTANCE.css().ensureInjected();
initWidget(uiBinder.createAndBindUi(this));
if (event instanceof EventStageDTO) {
dataByLogo.setUp(((EventStageDTO) event).getTrackingConnectorInfos(), /** colorIfPossible **/ false, /** enforceTextColor **/ true);
} else {
dataByLogo.setVisible(false);
}
eventNavigation = placeNavigator.getEventNavigation(event.getId().toString(), event.getBaseURL(), event.isOnRemoteServer());
}
@@ -1,6 +1,6 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared">
xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:s="urn:import:com.sap.sailing.gwt.ui.shared">
<ui:with field="i18n"
type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="res"
@@ -10,16 +10,14 @@
<ui:style>
.left {
display: inline;
position: absolute;
top: 0px;
left: 0px;
width: 50%;
vertical-align: middle;
}
.right {
display: inline;
position: absolute;
display: inline;
position: absolute;
top: 0px;
left: 50%;
right: 0px;
@@ -41,6 +39,7 @@
<div class="{local_res.css.stageteaser_content_band_text}" >
<div class="{local_res.css.stageteaser_content_band_text_name} {style.left}" >
<div ui:field="bandSubtitle" />
<s:databylogo.DataByLogo ui:field="dataByLogo" addStyleNames="{local_res.css.stageteaser_databylogo_container}" />
</div>
<div class="{style.right}">
<g:Anchor ui:field="actionLink"
@@ -41,6 +41,7 @@ import com.sap.sailing.gwt.home.communication.eventlist.EventListEventDTO;
import com.sap.sailing.gwt.home.communication.media.SailingVideoDTO;
import com.sap.sailing.gwt.home.communication.start.EventStageDTO;
import com.sap.sailing.gwt.home.communication.start.StageEventType;
import com.sap.sailing.gwt.ui.shared.TrackingConnectorInfoDTO;
import com.sap.sailing.server.interfaces.RacingEventService;
import com.sap.sailing.server.util.EventUtil;
import com.sap.sse.common.TimePoint;
@@ -311,7 +312,9 @@ public final class HomeServiceUtil {
dto.setBaseURL(baseURL.toString());
dto.setOnRemoteServer(onRemoteServer);
dto.setStageType(stageType);
dto.setTrackedByTracTrac(event.isTrackedByTracTrac());
Set<TrackingConnectorInfoDTO> trackingConnectorInfos = event.getTrackingConnectorInfos().stream()
.map(TrackingConnectorInfoDTO::new).collect(Collectors.toSet());
dto.setTrackingConnectorInfos(trackingConnectorInfos);
dto.setStageImageURL(useTeaserImage ? findEventThumbnailImageUrlAsString(event) : getStageImageURLAsString(event));
return dto;
}
@@ -1713,7 +1713,7 @@ seriesHeaderUpcoming=Upcoming
eventRegattaLeaderboardLastScoreUpdate=Last Score Update
eventRegattaRaceNotTracked=Not Tracked
footerJobs=Jobs
footerCopyright=\u00A9 2011-2019 SAP Sailing Analytics
footerCopyright=\u00A9 2011-2020 SAP Sailing Analytics
footerLanguage=SAP Sailing in
footerLegal=Legal Disclosure
footerPrivacy=Privacy
@@ -1698,7 +1698,7 @@ seriesHeaderUpcoming=Demnächst
eventRegattaLeaderboardLastScoreUpdate=Letztes Ergebnis-Update
eventRegattaRaceNotTracked=Nicht getrackt
footerJobs=Jobs
footerCopyright=\u00A9 2011-2019 SAP Sailing Analytics
footerCopyright=\u00A9 2011-2020 SAP Sailing Analytics
footerLanguage=SAP Sailing in
footerLegal=Impressum
footerPrivacy=Datenschutz
@@ -1706,7 +1706,7 @@ seriesHeaderUpcoming=Próximo
eventRegattaLeaderboardLastScoreUpdate=Última actualización de puntuación
eventRegattaRaceNotTracked=No rastreado
footerJobs=Jobs
footerCopyright=© 2011-2019 SAP Sailing Analytics
footerCopyright=© 2011-2020 SAP Sailing Analytics
footerLanguage=SAP Sailing en
footerLegal=Publicidad legal
footerPrivacy=Privacidad
@@ -1706,7 +1706,7 @@ seriesHeaderUpcoming=à venir
eventRegattaLeaderboardLastScoreUpdate=Dernière mise à jour des scores
eventRegattaRaceNotTracked=Non suivi(e)
footerJobs=Carrières
footerCopyright=© 2011-2019 SAP Sailing Analytics
footerCopyright=© 2011-2020 SAP Sailing Analytics
footerLanguage=SAP Sailing in
footerLegal=Mentions légales
footerPrivacy=Confidentialité des données
@@ -1706,7 +1706,7 @@ seriesHeaderUpcoming=Prossimamente
eventRegattaLeaderboardLastScoreUpdate=Ultimo aggiornamento punteggio
eventRegattaRaceNotTracked=Tracciamento non eseguito
footerJobs=Jobs
footerCopyright=© 2011-2019 SAP Sailing Analytics
footerCopyright=© 2011-2020 SAP Sailing Analytics
footerLanguage=SAP Sailing in
footerLegal=Informativa legale
footerPrivacy=Privacy
@@ -1706,7 +1706,7 @@ seriesHeaderUpcoming=予定
eventRegattaLeaderboardLastScoreUpdate=前回スコア更新
eventRegattaRaceNotTracked=未追跡
footerJobs=採用
footerCopyright=© 2011-2019 SAP Sailing Analytics
footerCopyright=© 2011-2020 SAP Sailing Analytics
footerLanguage=SAP Sailing -
footerLegal=利用規約
footerPrivacy=個人情報保護
@@ -1706,7 +1706,7 @@ seriesHeaderUpcoming=Próximo
eventRegattaLeaderboardLastScoreUpdate=Atualização da última pontuação
eventRegattaRaceNotTracked=Não rastreado
footerJobs=Tarefas
footerCopyright=© 2011-2019 SAP Sailing Analytics
footerCopyright=© 2011-2020 SAP Sailing Analytics
footerLanguage=SAP Sailing em
footerLegal=Divulgação de informação legal
footerPrivacy=Privacidade
@@ -1706,7 +1706,7 @@ seriesHeaderUpcoming=Скоро
eventRegattaLeaderboardLastScoreUpdate=Последнее обновление оценок
eventRegattaRaceNotTracked=Не отслеживается
footerJobs=Работа
footerCopyright=© SAP Sailing Analytics, 2011-2019.
footerCopyright=© SAP Sailing Analytics, 2011-2020.
footerLanguage=Язык SAP Sailing
footerLegal=Раскрытие юридической информации
footerPrivacy=Конфиденциальность
@@ -1706,7 +1706,7 @@ seriesHeaderUpcoming=即将到来
eventRegattaLeaderboardLastScoreUpdate=上次得分更新
eventRegattaRaceNotTracked=未跟踪
footerJobs=招贤纳士
footerCopyright=版权所有 © 2011-2019 SAP Sailing Analytics
footerCopyright=版权所有 © 2011-2020 SAP Sailing Analytics
footerLanguage=SAP Sailing 语言
footerLegal=法律声明
footerPrivacy=隐私
@@ -155,7 +155,7 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint implements Pr
raceboardContextDefinition.getLeaderboardName(), raceboardContextDefinition.getLeaderboardGroupName(),
raceboardContextDefinition.getEventId(), RaceBoardEntryPoint.this, getStringMessages(), userAgent,
raceTimesInfoProvider, showChartMarkEditMediaButtonsAndVideo, true, availableDetailTypes,
raceboardData.getLeaderboard(), selectedRace);
raceboardData.getLeaderboard(), selectedRace, raceboardData.getTrackingConnectorInfo());
RootLayoutPanel.get().add(raceBoardPerspective.getEntryWidget());
if (raceBoardMode != null) {
@@ -1,6 +1,7 @@
package com.sap.sailing.gwt.ui.raceboard;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@@ -94,6 +95,8 @@ import com.sap.sailing.gwt.ui.raceboard.tagging.TaggingPanel;
import com.sap.sailing.gwt.ui.shared.RaceWithCompetitorsAndBoatsDTO;
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTOWithSecurity;
import com.sap.sailing.gwt.ui.shared.TrackingConnectorInfoDTO;
import com.sap.sailing.gwt.ui.shared.databylogo.DataByLogo;
import com.sap.sse.common.Distance;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
@@ -182,6 +185,7 @@ public class RaceBoardPanel
private ManeuverTablePanel maneuverTablePanel;
private static final RaceMapResources raceMapResources = GWT.create(RaceMapResources.class);
private TrackingConnectorInfoDTO trackingConnectorInfo;
/**
* @param eventId
@@ -199,6 +203,7 @@ public class RaceBoardPanel
* @param availableDetailTypes
* A list of all Detailtypes, that will be offered in the Settingsdialog. Can be used to hide settings no
* data exists for, eg Bravo, Expdition ect.
* @param trackingConnectorInfo
*/
public RaceBoardPanel(Component<?> parent,
ComponentContext<PerspectiveCompositeSettings<RaceBoardPerspectiveOwnSettings>> componentContext,
@@ -211,7 +216,7 @@ public class RaceBoardPanel
UserAgentDetails userAgent, RaceTimesInfoProvider raceTimesInfoProvider,
boolean showChartMarkEditMediaButtonsAndVideo, boolean showHeaderPanel,
Iterable<DetailType> availableDetailTypes, StrippedLeaderboardDTOWithSecurity leaderboardDTO,
final RaceWithCompetitorsAndBoatsDTO raceDTO) {
final RaceWithCompetitorsAndBoatsDTO raceDTO, TrackingConnectorInfoDTO trackingConnectorInfo) {
super(parent, componentContext, lifecycle, settings);
this.sailingService = sailingService;
this.mediaService = mediaService;
@@ -221,6 +226,7 @@ public class RaceBoardPanel
this.userAgent = userAgent;
this.timer = timer;
this.eventId = eventId;
this.trackingConnectorInfo = trackingConnectorInfo;
this.currentRaceHasBeenSelectedOnce = false;
this.leaderboardName = leaderboardName;
this.selectedRaceIdentifier = selectedRaceIdentifier;
@@ -712,6 +718,13 @@ public class RaceBoardPanel
regattaAndRaceTimeInformationHeader.clear();
regattaAndRaceTimeInformationHeader.add(regattaNameAnchor);
regattaAndRaceTimeInformationHeader.add(raceTimeLabel);
DataByLogo dataByLogo = new DataByLogo();
dataByLogo.setUp(trackingConnectorInfo == null ? Collections.emptySet()
: Collections.singleton(trackingConnectorInfo), /** colorIfPossible **/ false, /** enforceTextColor **/ true);
if (dataByLogo.isVisible()) {
regattaAndRaceTimeInformationHeader.addStyleName("RegattaAndRaceTime-Header_with_databy");
}
regattaAndRaceTimeInformationHeader.add(dataByLogo);
currentRaceHasBeenSelectedOnce = true;
taggingPanel.updateRace(leaderboardName, raceColumn, fleet);
}
@@ -192,7 +192,13 @@ public class TaggingPanel extends ComponentWithoutSettings
tagButtons = new ArrayList<TagButton>();
taggingPanel = new DockLayoutPanel(Style.Unit.PX);
taggingPanel = new DockLayoutPanel(Style.Unit.PX) {
@Override
public void onResize() {
super.onResize();
taggingPanel.setWidgetSize(footerPanel, calculateFooterPanelHeight());
}
};
filterbarAndContentPanel = new HeaderPanel();
tagFooterPanel = new TagFooterPanel(this, sailingService, stringMessages, userService);
footerPanel = new ScrollPanel(tagFooterPanel);
@@ -705,15 +711,7 @@ public class TaggingPanel extends ComponentWithoutSettings
Scheduler.get().scheduleFinally(new RepeatingCommand() {
@Override
public boolean execute() {
// Default size of 2/3 the TaggingPanel
int height = (int) Math.round(taggingPanel.getOffsetHeight() / 3f * 2f);
// Get actual size of the footerPanel which might be 0 if the browser screwed up
final int vScroll = footerPanel.getWidget().getElement().getScrollHeight();
if (vScroll != 0) {
height = Math.min(height, vScroll);
}
height = Math.max(200, height);
taggingPanel.setWidgetSize(footerPanel, height);
taggingPanel.setWidgetSize(footerPanel, calculateFooterPanelHeight());
taggingPanel.animate(FOOTERPANEL_ANIMATION_PERIOD_MS);
return false;
}
@@ -728,6 +726,15 @@ public class TaggingPanel extends ComponentWithoutSettings
}
}
private int calculateFooterPanelHeight() {
// Start with footerPanel content height
int height = footerPanel.getWidget().getElement().getOffsetHeight();
// Limit size if we take up the entire height of the viewing area
// to make sure we don't get pushed out of it at the top making parts of the footerPanel inaccessible
height = Math.min(height, taggingPanel.getOffsetHeight());
return height;
}
/**
* Checks whether current user has permission to modify public tags.
*
@@ -414,6 +414,7 @@ import com.sap.sailing.domain.tracking.Track;
import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackingConnectorInfo;
import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingAndORCPerformanceCurveCache;
import com.sap.sailing.domain.tracking.WindPositionMode;
import com.sap.sailing.domain.tracking.WindTrack;
@@ -511,6 +512,7 @@ import com.sap.sailing.gwt.ui.shared.SwissTimingReplayRaceDTO;
import com.sap.sailing.gwt.ui.shared.TracTracConfigurationWithSecurityDTO;
import com.sap.sailing.gwt.ui.shared.TracTracRaceRecordDTO;
import com.sap.sailing.gwt.ui.shared.TrackFileImportDeviceIdentifierDTO;
import com.sap.sailing.gwt.ui.shared.TrackingConnectorInfoDTO;
import com.sap.sailing.gwt.ui.shared.TypedDeviceMappingDTO;
import com.sap.sailing.gwt.ui.shared.VenueDTO;
import com.sap.sailing.gwt.ui.shared.WaypointDTO;
@@ -2026,7 +2028,7 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
public RaceboardDataDTO getRaceboardData(String regattaName, String raceName, String leaderboardName,
String leaderboardGroupName, UUID eventId) {
RaceboardDataDTO result = new RaceboardDataDTO(null, false, false, Collections.emptyList(),
Collections.emptyList(), null, false);
Collections.emptyList(), null, null);
RaceWithCompetitorsAndBoatsDTO raceDTO = null;
Regatta regatta = getService().getRegattaByName(regattaName);
if (regatta != null) {
@@ -2080,9 +2082,11 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
StrippedLeaderboardDTOWithSecurity leaderboardDTO = createStrippedLeaderboardDTOWithSecurity(
leaderboard, false,
false);
boolean isTrackedByTracTrac = isValidEvent && event.isTrackedByTracTrac();
final TrackingConnectorInfo trackingConnectorInfo = trackedRace.getTrackingConnectorInfo();
final TrackingConnectorInfoDTO trackingConnectorInfoDTO = trackingConnectorInfo == null ? null
: new TrackingConnectorInfoDTO(trackingConnectorInfo);
result = new RaceboardDataDTO(raceDTO, isValidLeaderboardGroup, isValidEvent,
detailTypesForCompetitorChart, availableDetailTypesForLeaderboard, leaderboardDTO, isTrackedByTracTrac);
detailTypesForCompetitorChart, availableDetailTypesForLeaderboard, leaderboardDTO, trackingConnectorInfoDTO);
}
}
}
@@ -16,15 +16,15 @@ public class RaceboardDataDTO implements IsSerializable {
private ArrayList<DetailType> detailTypesForCompetitorChart;
private ArrayList<DetailType> availableDetailTypesForLeaderboard;
private StrippedLeaderboardDTOWithSecurity leaderboard;
private boolean isTrackedByTracTrac;
private TrackingConnectorInfoDTO trackingConnectorInfo;
// for GWT
RaceboardDataDTO() {}
public RaceboardDataDTO(RaceWithCompetitorsAndBoatsDTO race,
boolean isValidLeaderboardGroup, boolean isValidEvent, Iterable<DetailType> detailTypesForCompetitorChart,
Iterable<DetailType> availableDetailTypesForLeaderboard, StrippedLeaderboardDTOWithSecurity leaderboard, boolean isTrackedByTracTrac) {
Iterable<DetailType> availableDetailTypesForLeaderboard, StrippedLeaderboardDTOWithSecurity leaderboard,
TrackingConnectorInfoDTO trackingConnectorInfo) {
this.race = race;
this.isValidLeaderboardGroup = isValidLeaderboardGroup;
this.isValidEvent = isValidEvent;
@@ -33,7 +33,7 @@ public class RaceboardDataDTO implements IsSerializable {
this.availableDetailTypesForLeaderboard = new ArrayList<>();
Util.addAll(availableDetailTypesForLeaderboard, this.availableDetailTypesForLeaderboard);
this.leaderboard = leaderboard;
this.isTrackedByTracTrac = isTrackedByTracTrac;
this.trackingConnectorInfo = trackingConnectorInfo;
}
public StrippedLeaderboardDTOWithSecurity getLeaderboard() {
@@ -67,8 +67,8 @@ public class RaceboardDataDTO implements IsSerializable {
public boolean isValidEvent() {
return isValidEvent;
}
public boolean isTrackedByTracTrac() {
return isTrackedByTracTrac;
public TrackingConnectorInfoDTO getTrackingConnectorInfo() {
return trackingConnectorInfo;
}
}
@@ -0,0 +1,56 @@
package com.sap.sailing.gwt.ui.shared;
import com.google.gwt.core.shared.GwtIncompatible;
import com.google.gwt.user.client.rpc.IsSerializable;
import com.sap.sailing.domain.common.tracking.TrackingConnectorType;
import com.sap.sailing.domain.tracking.TrackingConnectorInfo;
public class TrackingConnectorInfoDTO implements IsSerializable {
private TrackingConnectorType trackingConnectorType;
private String webUrl;
TrackingConnectorInfoDTO() {
} // GWT serialization
@GwtIncompatible
public TrackingConnectorInfoDTO(TrackingConnectorInfo trackingConnectorInfo) {
this.trackingConnectorType = trackingConnectorInfo.getTrackingConnectorType();
this.webUrl = trackingConnectorInfo.getWebUrl() == null ? null : trackingConnectorInfo.getWebUrl().toString();
}
public TrackingConnectorType getTrackingConnectorType() {
return trackingConnectorType;
}
public String getWebUrl() {
return webUrl;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((trackingConnectorType == null) ? 0 : trackingConnectorType.hashCode());
result = prime * result + ((webUrl == null) ? 0 : webUrl.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TrackingConnectorInfoDTO other = (TrackingConnectorInfoDTO) obj;
if (trackingConnectorType != other.trackingConnectorType)
return false;
if (webUrl == null) {
if (other.webUrl != null)
return false;
} else if (!webUrl.equals(other.webUrl))
return false;
return true;
}
}
@@ -0,0 +1,30 @@
img.databylogo_logo {
height: 1.3333333em !important;
vertical-align: middle;
display: inline-block;
}
.databylogo_text {
vertical-align: middle;
}
.databylogo_white_text {
color: white;
}
.databylogo_black_text {
color: black;
}
.databylogo_subtlelink, .databylogo_subtlelink:hover,
.databylogo_subtlelink:active, .databylogo_subtlelink:visited,
.databylogo_subtlelink:focus {
text-decoration: none;
}
.databylogo_container {
display: inline-block;
white-space: nowrap;
font-size: 0.75em;
cursor: pointer;
}
@@ -0,0 +1,86 @@
package com.sap.sailing.gwt.ui.shared.databylogo;
import java.util.Set;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.AnchorElement;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.ImageElement;
import com.google.gwt.resources.client.DataResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.domain.common.tracking.TrackingConnectorType;
import com.sap.sailing.gwt.ui.shared.TrackingConnectorInfoDTO;
public class DataByLogo extends Widget {
private static DataByLogoUiBinder uiBinder = GWT.create(DataByLogoUiBinder.class);
interface DataByLogoUiBinder extends UiBinder<Element, DataByLogo> {
}
@UiField
AnchorElement dataByContainer;
@UiField
ImageElement logo;
public DataByLogo() {
DataByLogoResources.INSTANCE.css().ensureInjected();
setElement(uiBinder.createAndBindUi(this));
}
public void setUp(Set<TrackingConnectorInfoDTO> trackingConnectorInfos, boolean colorIfPossible,
boolean enforceTextColor) {
TrackingConnectorInfoDTO mostProminentConnectorInfo = selectMostProminentConnectorInfo(trackingConnectorInfos);
if (mostProminentConnectorInfo == null) {
this.setVisible(false);
} else {
setUpForConnectorType(colorIfPossible, enforceTextColor, mostProminentConnectorInfo);
}
}
private TrackingConnectorInfoDTO selectMostProminentConnectorInfo(
Set<TrackingConnectorInfoDTO> trackingConnectorInfos) {
TrackingConnectorInfoDTO potentialConnectorInfo = null;
if (trackingConnectorInfos != null && !trackingConnectorInfos.isEmpty()) {
for (TrackingConnectorInfoDTO trackingConnectorInfo : trackingConnectorInfos) {
// This logic currently only supports TracTrac as ConnectorInfo
if (trackingConnectorInfo.getTrackingConnectorType() == TrackingConnectorType.TracTrac) {
potentialConnectorInfo = trackingConnectorInfo;
String webUrl = trackingConnectorInfo.getWebUrl();
if (webUrl != null && !webUrl.isEmpty()) {
break;
}
}
}
}
return potentialConnectorInfo;
}
private void setUpForConnectorType(boolean colorIfPossible, boolean enforceTextColor,
TrackingConnectorInfoDTO trackingConnectorInfo) {
if (trackingConnectorInfo.getTrackingConnectorType() == TrackingConnectorType.TracTrac) {
setUpTracTracLogo(colorIfPossible, enforceTextColor);
}
setUrl(trackingConnectorInfo);
}
private void setUpTracTracLogo(boolean colorIfPossible, boolean enforceTextColor) {
final DataByLogoResources resources = DataByLogoResources.INSTANCE;
final DataResource imageToSet = colorIfPossible ? resources.tractracColor() : resources.tractracWhite();
logo.setSrc(imageToSet.getSafeUri().asString());
if (enforceTextColor) {
this.addStyleName(colorIfPossible ? resources.css().databylogo_black_text()
: resources.css().databylogo_white_text());
}
}
private void setUrl(TrackingConnectorInfoDTO trackingConnectorInfo) {
String webUrl = trackingConnectorInfo.getWebUrl();
if (webUrl == null || "".equals(trackingConnectorInfo.getWebUrl())) {
webUrl = trackingConnectorInfo.getTrackingConnectorType().getDefaultUrl();
}
dataByContainer.setHref(webUrl);
}
}
@@ -0,0 +1,10 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.ui.shared.databylogo.DataByLogoResources" />
<a ui:field="dataByContainer" target="_blank" href="" class="{local_res.css.databylogo_subtlelink} {local_res.css.databylogo_container}">
<span class="{local_res.css.databylogo_text}"><ui:text from="{i18n.dataBy}"/></span>
<img ui:field="logo" class="{local_res.css.databylogo_logo}"></img>
</a>
</ui:UiBinder>
@@ -0,0 +1,31 @@
package com.sap.sailing.gwt.ui.shared.databylogo;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.DataResource;
import com.google.gwt.resources.client.DataResource.MimeType;
public interface DataByLogoResources extends ClientBundle {
public static final DataByLogoResources INSTANCE = GWT.create(DataByLogoResources.class);
@Source("DataByLogo.gss")
LocalCss css();
@Source("tractrac-color.svg")
@MimeType("image/svg+xml")
DataResource tractracColor();
@Source("tractrac-white.svg")
@MimeType("image/svg+xml")
DataResource tractracWhite();
public interface LocalCss extends CssResource {
String databylogo_logo();
String databylogo_subtlelink();
String databylogo_container();
String databylogo_white_text();
String databylogo_black_text();
String databylogo_text();
}
}
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 100 23" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><rect id="Artboard1" x="0" y="0" width="99.997" height="22.94" style="fill:none;"/><path d="M7.044,22.474l-3.981,0l2.681,-16.956l-4.117,0l0.542,-3.468l12.216,0l-0.542,3.468l-4.117,0l-2.682,16.956Z" style="fill:#fff;fill-rule:nonzero;"/><path d="M16.185,8.781l0.054,0c0.948,-1.165 2.167,-1.815 3.576,-1.815c0.542,0 1.084,0.135 1.517,0.325l-1.002,3.522c-0.406,-0.325 -0.921,-0.488 -1.49,-0.488c-2.627,0 -3.278,2.329 -3.603,4.388l-0.948,5.986l-3.792,0l2.113,-13.299l3.792,0l-0.217,1.381Z" style="fill:#fff;fill-rule:nonzero;"/><path d="M30.362,14.036c0.271,-1.788 -0.623,-3.711 -2.573,-3.711c-1.951,0 -3.467,1.923 -3.738,3.711c-0.271,1.787 0.596,3.738 2.546,3.738c1.95,0 3.494,-1.951 3.765,-3.738m2.303,6.664l-3.739,0l0.19,-1.219l-0.054,0c-0.975,1.056 -2.492,1.652 -3.873,1.652c-3.901,0 -5.554,-3.548 -4.985,-7.151c0.569,-3.522 3.359,-7.016 7.178,-7.016c1.382,0 2.709,0.596 3.441,1.68l0.216,-1.246l3.738,0l-2.112,13.3Z" style="fill:#fff;fill-rule:nonzero;"/><path d="M45.568,11.462c-0.677,-0.812 -1.408,-1.299 -2.573,-1.299c-2.14,0 -3.684,2.004 -4.009,3.954c-0.325,2.086 0.731,3.82 2.898,3.82c1.03,0 2.059,-0.515 2.872,-1.274l-0.596,3.657c-1.111,0.569 -2.249,0.813 -3.414,0.813c-3.927,0 -6.203,-3.224 -5.579,-7.043c0.622,-3.955 4.009,-7.124 8.017,-7.124c1.057,0 2.14,0.271 2.953,0.84l-0.569,3.656Z" style="fill:#fff;fill-rule:nonzero;"/><path d="M51.914,22.474l-3.982,0l2.682,-16.956l-4.118,0l0.542,-3.468l12.217,0l-0.542,3.468l-4.117,0l-2.682,16.956Z" style="fill:#fff;fill-rule:nonzero;"/><path d="M61.18,8.781l0.055,0c0.947,-1.165 2.167,-1.815 3.575,-1.815c0.541,0 1.084,0.135 1.517,0.325l-1.002,3.522c-0.406,-0.325 -0.921,-0.488 -1.49,-0.488c-2.627,0 -3.277,2.329 -3.603,4.388l-0.948,5.986l-3.792,0l2.113,-13.299l3.792,0l-0.217,1.381Z" style="fill:#fff;fill-rule:nonzero;"/><path d="M75.357,14.036c0.271,-1.788 -0.623,-3.711 -2.573,-3.711c-1.95,0 -3.467,1.923 -3.738,3.711c-0.271,1.787 0.596,3.738 2.546,3.738c1.951,0 3.494,-1.951 3.765,-3.738m2.302,6.664l-3.738,0l0.19,-1.219l-0.054,0c-0.975,1.056 -2.492,1.652 -3.874,1.652c-3.901,0 -5.553,-3.548 -4.983,-7.151c0.569,-3.522 3.358,-7.016 7.178,-7.016c1.381,0 2.708,0.596 3.439,1.68l0.218,-1.246l3.737,0l-2.113,13.3Z" style="fill:#fff;fill-rule:nonzero;"/><path d="M90.563,11.462c-0.677,-0.812 -1.409,-1.299 -2.573,-1.299c-2.14,0 -3.684,2.004 -4.009,3.954c-0.325,2.086 0.731,3.82 2.899,3.82c1.029,0 2.058,-0.515 2.871,-1.274l-0.597,3.657c-1.11,0.569 -2.248,0.813 -3.412,0.813c-3.928,0 -6.204,-3.224 -5.58,-7.043c0.623,-3.955 4.009,-7.124 8.017,-7.124c1.057,0 2.141,0.271 2.953,0.84l-0.569,3.656Z" style="fill:#fff;fill-rule:nonzero;"/><path d="M89.199,14.063c0,0.93 -0.753,1.683 -1.683,1.683c-0.929,0 -1.682,-0.753 -1.682,-1.683c0,-0.929 0.753,-1.683 1.682,-1.683c0.93,0 1.683,0.754 1.683,1.683" style="fill:#fff;fill-rule:nonzero;"/><path d="M96.407,2.836c-1.148,-1.262 -2.668,-2.087 -4.333,-2.37l-0.161,1.206c1.38,0.245 2.639,0.935 3.593,1.984c1.034,1.137 1.608,2.588 1.647,4.115l1.217,0c-0.04,-1.831 -0.724,-3.573 -1.963,-4.935m-4.627,-0.169l-0.161,1.212c0.861,0.173 1.646,0.613 2.245,1.271c0.658,0.723 1.032,1.649 1.071,2.621l1.218,0c-0.039,-1.276 -0.526,-2.493 -1.389,-3.44c-0.792,-0.872 -1.837,-1.451 -2.984,-1.664m-0.294,2.207l-0.162,1.219c0.342,0.097 0.656,0.285 0.897,0.551c0.283,0.311 0.452,0.71 0.489,1.127l1.225,0c-0.038,-0.721 -0.326,-1.412 -0.813,-1.947c-0.435,-0.477 -1.009,-0.809 -1.636,-0.95" style="fill:#fff;fill-rule:nonzero;"/></svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

@@ -106,7 +106,7 @@ public class TestStoringAndRetrievingWindTracksTest extends AbstractTracTracLive
public void addRaceDefinition(RaceDefinition race, DynamicTrackedRace trackedRace) {
}
}, /*useMarkPassingCalculator*/ false, mock(RaceLogAndTrackedRaceResolver.class),
Optional.empty(), null);
Optional.empty(), /* trackingConnectorInfo */ null);
WindSource windSource = new WindSourceImpl(WindSourceType.WEB);
MongoClient myFirstMongo = newMongo();
MongoDatabase firstDatabase = myFirstMongo.getDatabase(dbConfiguration.getDatabaseName());
@@ -3,8 +3,10 @@ package com.sap.sailing.server.gateway.deserialization.impl;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.UUID;
import org.json.simple.JSONArray;
@@ -14,6 +16,7 @@ import com.sap.sailing.domain.base.EventBase;
import com.sap.sailing.domain.base.LeaderboardGroupBase;
import com.sap.sailing.domain.base.Venue;
import com.sap.sailing.domain.base.impl.StrippedEventImpl;
import com.sap.sailing.domain.tracking.TrackingConnectorInfo;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer;
@@ -28,10 +31,14 @@ import com.sap.sse.shared.media.impl.VideoDescriptorImpl;
public class EventBaseJsonDeserializer implements JsonDeserializer<EventBase> {
private final JsonDeserializer<Venue> venueDeserializer;
private final JsonDeserializer<LeaderboardGroupBase> leaderboardGroupDeserializer;
private final JsonDeserializer<TrackingConnectorInfo>trackingConnectorInfoDeserializer;
public EventBaseJsonDeserializer(JsonDeserializer<Venue> venueDeserializer, JsonDeserializer<LeaderboardGroupBase> leaderboardGroupDeserializer) {
public EventBaseJsonDeserializer(JsonDeserializer<Venue> venueDeserializer,
JsonDeserializer<LeaderboardGroupBase> leaderboardGroupDeserializer,
JsonDeserializer<TrackingConnectorInfo> trackingConnectorInfoDeserializer) {
this.venueDeserializer = venueDeserializer;
this.leaderboardGroupDeserializer = leaderboardGroupDeserializer;
this.trackingConnectorInfoDeserializer = trackingConnectorInfoDeserializer;
}
public EventBase deserialize(JSONObject eventJson) throws JsonDeserializationException {
@@ -56,9 +63,18 @@ public class EventBaseJsonDeserializer implements JsonDeserializer<EventBase> {
leaderboardGroups.add(leaderboardGroupDeserializer.deserialize((JSONObject) lgJson));
}
}
boolean isTrackedByTracTrac = Boolean.TRUE.equals(eventJson.get(EventBaseJsonSerializer.Field_TRACKED_BY_TRACTRAC));
StrippedEventImpl result = new StrippedEventImpl(name, startDate == null ? null : new MillisecondsTimePoint(startDate.longValue()),
endDate == null ? null : new MillisecondsTimePoint(endDate.longValue()), venue, /* is public */ true, id, leaderboardGroups, isTrackedByTracTrac);
final Set<TrackingConnectorInfo> trackingConnectorInfos = new HashSet<>();
final JSONArray trackingConnectorInfosJson = (JSONArray) eventJson
.get(EventBaseJsonSerializer.FIELD_TRACKING_CONNECTOR_INFOS);
if (trackingConnectorInfosJson != null) {
for (Object jsonPair : trackingConnectorInfosJson) {
trackingConnectorInfos.add(trackingConnectorInfoDeserializer.deserialize((JSONObject) jsonPair));
}
}
StrippedEventImpl result = new StrippedEventImpl(name,
startDate == null ? null : new MillisecondsTimePoint(startDate.longValue()),
endDate == null ? null : new MillisecondsTimePoint(endDate.longValue()), venue, /* is public */ true,
id, leaderboardGroups, trackingConnectorInfos);
result.setDescription(description);
if (officialWebsiteURLAsString != null) {
try {
@@ -0,0 +1,35 @@
package com.sap.sailing.server.gateway.deserialization.impl;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.common.tracking.TrackingConnectorType;
import com.sap.sailing.domain.tracking.TrackingConnectorInfo;
import com.sap.sailing.domain.tracking.impl.TrackingConnectorInfoImpl;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
import com.sap.sailing.server.gateway.serialization.impl.TrackingConnectorInfoJsonSerializer;
public class TrackingConnectorInfoJsonDeserializer implements JsonDeserializer<TrackingConnectorInfo> {
private static final Logger logger = Logger.getLogger(TrackingConnectorInfoJsonDeserializer.class.getName());
public TrackingConnectorInfo deserialize(JSONObject object) throws JsonDeserializationException {
final TrackingConnectorType trackingConnectorType = TrackingConnectorType
.valueOf((String) object.get(TrackingConnectorInfoJsonSerializer.FIELD_TRACKING_CONNECTOR_TYPE));
final String webUrlString = (String) object.get(TrackingConnectorInfoJsonSerializer.FIELD_WEB_URL);
URL webUrl;
try {
webUrl = webUrlString == null ? null : new URL(webUrlString);
} catch (MalformedURLException e) {
logger.log(Level.WARNING, "Error while parsing webUrl of TrackingConnectorInfo", e);
webUrl = null;
}
final TrackingConnectorInfo trackingConnectorInfo = new TrackingConnectorInfoImpl(trackingConnectorType,
webUrl);
return trackingConnectorInfo;
}
}
@@ -10,6 +10,7 @@ import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.EventBase;
import com.sap.sailing.domain.base.LeaderboardGroupBase;
import com.sap.sailing.domain.base.Venue;
import com.sap.sailing.domain.tracking.TrackingConnectorInfo;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
@@ -39,7 +40,7 @@ public class EventBaseJsonSerializer implements JsonSerializer<EventBase> {
public static final String FIELD_CREATEDATDATE = "createdAtDate";
public static final String FIELD_LOCALE = "locale";
public static final String FIELD_TAGS = "tags";
public static final String Field_TRACKED_BY_TRACTRAC = "trackedByTracTrac";
public static final String FIELD_TRACKING_CONNECTOR_INFOS = "trackingConnectorInfos";
// specific image fields
public static final String FIELD_IMAGES = "images";
public static final String FIELD_IMAGE_WIDTH_IN_PX = "widthInPixel";
@@ -53,10 +54,14 @@ public class EventBaseJsonSerializer implements JsonSerializer<EventBase> {
private final JsonSerializer<Venue> venueSerializer;
private final JsonSerializer<? super LeaderboardGroupBase> leaderboardGroupBaseSerializer;
private final JsonSerializer<TrackingConnectorInfo> trackingConnectorInfoSerializer;
public EventBaseJsonSerializer(JsonSerializer<Venue> venueSerializer, JsonSerializer<? super LeaderboardGroupBase> leaderboardGroupBaseSerializer) {
public EventBaseJsonSerializer(JsonSerializer<Venue> venueSerializer,
JsonSerializer<? super LeaderboardGroupBase> leaderboardGroupBaseSerializer,
JsonSerializer<TrackingConnectorInfo> trackingConnectorInfoJsonSerializer) {
this.leaderboardGroupBaseSerializer = leaderboardGroupBaseSerializer;
this.venueSerializer = venueSerializer;
this.trackingConnectorInfoSerializer = trackingConnectorInfoJsonSerializer;
}
public JSONObject serialize(EventBase event) {
@@ -74,19 +79,23 @@ public class EventBaseJsonSerializer implements JsonSerializer<EventBase> {
for (LeaderboardGroupBase lg : event.getLeaderboardGroups()) {
leaderboardGroups.add(leaderboardGroupBaseSerializer.serialize(lg));
}
result.put(Field_TRACKED_BY_TRACTRAC, event.isTrackedByTracTrac());
JSONArray trackingConnectorInfos = new JSONArray();
for (TrackingConnectorInfo trackingConnectorInfo : event.getTrackingConnectorInfos()) {
trackingConnectorInfos.add(trackingConnectorInfoSerializer.serialize(trackingConnectorInfo));
}
result.put(FIELD_TRACKING_CONNECTOR_INFOS, trackingConnectorInfos);
JSONArray imageSizes = new JSONArray();
result.put(FIELD_IMAGE_SIZES, imageSizes);
for (ImageDescriptor image : event.getImages()) {
addImageSize(image, imageSizes);
}
JSONArray jsonImages = new JSONArray();
for(ImageDescriptor imageDescriptor: event.getImages()) {
for (ImageDescriptor imageDescriptor: event.getImages()) {
addImage(imageDescriptor, jsonImages);
}
result.put(FIELD_IMAGES, jsonImages);
JSONArray jsonVideos = new JSONArray();
for(VideoDescriptor videoDescriptor: event.getVideos()) {
for (VideoDescriptor videoDescriptor: event.getVideos()) {
addVideo(videoDescriptor, jsonVideos);
}
result.put(FIELD_VIDEOS, jsonVideos);
@@ -143,7 +152,7 @@ public class EventBaseJsonSerializer implements JsonSerializer<EventBase> {
* JSON object to <code>imageSizes</code>
*/
private void addImageSize(ImageDescriptor image, JSONArray imageSizes) {
if(image.getHeightInPx() != null && image.getWidthInPx() != null) {
if (image.getHeightInPx() != null && image.getWidthInPx() != null) {
JSONObject imageSizeJson = new JSONObject();
imageSizes.add(imageSizeJson);
imageSizeJson.put(FIELD_IMAGE_URL, image.getURL().toString());
@@ -0,0 +1,24 @@
package com.sap.sailing.server.gateway.serialization.impl;
import java.net.URL;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.tracking.TrackingConnectorInfo;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
public class TrackingConnectorInfoJsonSerializer implements JsonSerializer<TrackingConnectorInfo> {
public static final String FIELD_TRACKING_CONNECTOR_TYPE = "trackingConnectorType";
public static final String FIELD_WEB_URL = "webUrl";
@Override
public JSONObject serialize(TrackingConnectorInfo trackingConnectorInfo) {
JSONObject result = new JSONObject();
URL webUrl = trackingConnectorInfo.getWebUrl();
result.put(FIELD_TRACKING_CONNECTOR_TYPE, trackingConnectorInfo.getTrackingConnectorType().name());
if (webUrl != null) {
result.put(FIELD_WEB_URL, webUrl.toString());
}
return result;
}
}
@@ -27,11 +27,13 @@ import com.sap.sailing.server.gateway.deserialization.JsonDeserializationExcepti
import com.sap.sailing.server.gateway.deserialization.impl.CourseAreaJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.EventBaseJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.LeaderboardGroupBaseJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.TrackingConnectorInfoJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.VenueJsonDeserializer;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.CourseAreaJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.TrackingConnectorInfoJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
@@ -88,9 +90,12 @@ public class EventDataJsonSerializerTest {
when(event.getImages()).thenReturn(Collections.<ImageDescriptor>singleton(expectedLogoImageDescriptor));
when(event.getVideos()).thenReturn(Collections.<VideoDescriptor>emptySet());
// ... and the serializer itself.
serializer = new EventBaseJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()), new LeaderboardGroupBaseJsonSerializer());
deserializer = new EventBaseJsonDeserializer(new VenueJsonDeserializer(new CourseAreaJsonDeserializer(DomainFactory.INSTANCE)), new LeaderboardGroupBaseJsonDeserializer());
serializer = new EventBaseJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()),
new LeaderboardGroupBaseJsonSerializer(), new TrackingConnectorInfoJsonSerializer());
deserializer = new EventBaseJsonDeserializer(
new VenueJsonDeserializer(new CourseAreaJsonDeserializer(DomainFactory.INSTANCE)),
new LeaderboardGroupBaseJsonDeserializer(), new TrackingConnectorInfoJsonDeserializer());
when(expectedLeaderboardGroup.getId()).thenReturn(UUID.randomUUID());
when(expectedLeaderboardGroup.getName()).thenReturn("LG");
when(expectedLeaderboardGroup.getDescription()).thenReturn("LG Description");
@@ -28,10 +28,12 @@ import com.sap.sailing.server.gateway.deserialization.JsonDeserializationExcepti
import com.sap.sailing.server.gateway.deserialization.impl.CourseAreaJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.EventBaseJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.LeaderboardGroupBaseJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.TrackingConnectorInfoJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.VenueJsonDeserializer;
import com.sap.sailing.server.gateway.serialization.impl.CourseAreaJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.TrackingConnectorInfoJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
@@ -117,9 +119,12 @@ public class EventDataJsonSerializerWithImagesAndVideosTest {
when(event.getImages()).thenReturn(images);
when(event.getVideos()).thenReturn(videos);
// ... and the serializer itself.
serializer = new EventBaseJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()), new LeaderboardGroupBaseJsonSerializer());
deserializer = new EventBaseJsonDeserializer(new VenueJsonDeserializer(new CourseAreaJsonDeserializer(DomainFactory.INSTANCE)), new LeaderboardGroupBaseJsonDeserializer());
serializer = new EventBaseJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()),
new LeaderboardGroupBaseJsonSerializer(), new TrackingConnectorInfoJsonSerializer());
deserializer = new EventBaseJsonDeserializer(
new VenueJsonDeserializer(new CourseAreaJsonDeserializer(DomainFactory.INSTANCE)),
new LeaderboardGroupBaseJsonDeserializer(), new TrackingConnectorInfoJsonDeserializer());
when(expectedLeaderboardGroup.getId()).thenReturn(UUID.randomUUID());
when(expectedLeaderboardGroup.getName()).thenReturn("LG");
when(expectedLeaderboardGroup.getDescription()).thenReturn("LG Description");
@@ -24,11 +24,13 @@ import com.sap.sailing.server.gateway.deserialization.JsonDeserializationExcepti
import com.sap.sailing.server.gateway.deserialization.impl.CourseAreaJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.EventBaseJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.LeaderboardGroupBaseJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.TrackingConnectorInfoJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.VenueJsonDeserializer;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.CourseAreaJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.TrackingConnectorInfoJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
@@ -67,9 +69,12 @@ public class EventDataJsonSerializerWithNullValuesTest {
when(event.getImages()).thenReturn(Collections.<ImageDescriptor>emptySet());
when(event.getVideos()).thenReturn(Collections.<VideoDescriptor>emptySet());
// ... and the serializer itself.
serializer = new EventBaseJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()), new LeaderboardGroupBaseJsonSerializer());
deserializer = new EventBaseJsonDeserializer(new VenueJsonDeserializer(new CourseAreaJsonDeserializer(DomainFactory.INSTANCE)), new LeaderboardGroupBaseJsonDeserializer());
serializer = new EventBaseJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()),
new LeaderboardGroupBaseJsonSerializer(), new TrackingConnectorInfoJsonSerializer());
deserializer = new EventBaseJsonDeserializer(
new VenueJsonDeserializer(new CourseAreaJsonDeserializer(DomainFactory.INSTANCE)),
new LeaderboardGroupBaseJsonDeserializer(), new TrackingConnectorInfoJsonDeserializer());
when(expectedLeaderbaordGroup.getId()).thenReturn(UUID.randomUUID());
when(expectedLeaderbaordGroup.getName()).thenReturn("LG");
when(expectedLeaderbaordGroup.getDescription()).thenReturn("LG Description");
@@ -24,11 +24,13 @@ import com.sap.sailing.server.gateway.deserialization.JsonDeserializationExcepti
import com.sap.sailing.server.gateway.deserialization.impl.CourseAreaJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.EventBaseJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.LeaderboardGroupBaseJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.TrackingConnectorInfoJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.VenueJsonDeserializer;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.CourseAreaJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.TrackingConnectorInfoJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
@@ -85,8 +87,11 @@ public class EventWithNullStartAndEndDataJsonSerializerTest {
doReturn(expectedLeaderboardGroups).when(event).getLeaderboardGroups();
// ... and the serializer itself.
serializer = new EventBaseJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()), new LeaderboardGroupBaseJsonSerializer());
deserializer = new EventBaseJsonDeserializer(new VenueJsonDeserializer(new CourseAreaJsonDeserializer(DomainFactory.INSTANCE)), new LeaderboardGroupBaseJsonDeserializer());
serializer = new EventBaseJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()),
new LeaderboardGroupBaseJsonSerializer(), new TrackingConnectorInfoJsonSerializer());
deserializer = new EventBaseJsonDeserializer(
new VenueJsonDeserializer(new CourseAreaJsonDeserializer(DomainFactory.INSTANCE)),
new LeaderboardGroupBaseJsonDeserializer(), new TrackingConnectorInfoJsonDeserializer());
}
@Test
@@ -78,6 +78,7 @@ import com.sap.sailing.server.gateway.serialization.impl.CourseAreaJsonSerialize
import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.EventRaceStatesSerializer;
import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.TrackingConnectorInfoJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
import com.sap.sailing.server.hierarchy.SailingHierarchyOwnershipUpdater;
import com.sap.sailing.server.operationaltransformation.AddColumnToSeries;
@@ -290,7 +291,8 @@ public class EventsResource extends AbstractSailingServerResource {
@Produces("application/json;charset=UTF-8")
public Response getEvents(@QueryParam("showNonPublic") String showNonPublic) {
JsonSerializer<EventBase> eventSerializer = new EventBaseJsonSerializer(
new VenueJsonSerializer(new CourseAreaJsonSerializer()), new LeaderboardGroupBaseJsonSerializer());
new VenueJsonSerializer(new CourseAreaJsonSerializer()), new LeaderboardGroupBaseJsonSerializer(),
new TrackingConnectorInfoJsonSerializer());
JSONArray result = new JSONArray();
for (Event event : getService().getAllEvents()) {
if (getSecurityService().hasCurrentUserReadPermission(event)
@@ -329,7 +331,8 @@ public class EventsResource extends AbstractSailingServerResource {
getSecurityService().checkCurrentUserReadPermission(event);
}
JsonSerializer<EventBase> eventSerializer = new EventBaseJsonSerializer(
new VenueJsonSerializer(new CourseAreaJsonSerializer()), new LeaderboardGroupBaseJsonSerializer());
new VenueJsonSerializer(new CourseAreaJsonSerializer()), new LeaderboardGroupBaseJsonSerializer(),
new TrackingConnectorInfoJsonSerializer());
JSONObject eventJson = eventSerializer.serialize(event);
String json = eventJson.toJSONString();
@@ -637,6 +637,7 @@ public class LeaderboardsResource extends AbstractLeaderboardsResource {
@QueryParam(RaceLogServletConstants.PARAMS_RACE_FLEET_NAME) String fleetName,
@QueryParam(RaceLogServletConstants.PARAMS_TRACK_WIND) Boolean trackWind,
@QueryParam(RaceLogServletConstants.PARAMS_CORRECT_WIND_DIRECTION_BY_MAGNETIC_DECLINATION) Boolean correctWindDirectionByMagneticDeclination,
@QueryParam(RaceLogServletConstants.PARAMS_TRACKED_RACE_NAME) String optionalTrackedRaceName,
@QueryParam("secret") String secret)
throws NotDenotedForRaceLogTrackingException, Exception {
final LeaderboardAndRaceColumnAndFleetAndResponse leaderboardAndRaceColumnAndFleetAndResponse = getLeaderboardAndRaceColumnAndFleet(
@@ -654,7 +655,7 @@ public class LeaderboardsResource extends AbstractLeaderboardsResource {
jsonResult.put("addeddenotation", adapter.denoteRaceForRaceLogTracking(getService(),
leaderboardAndRaceColumnAndFleetAndResponse.getLeaderboard(),
leaderboardAndRaceColumnAndFleetAndResponse.getRaceColumn(),
leaderboardAndRaceColumnAndFleetAndResponse.getFleet(), /* use default race name */ null));
leaderboardAndRaceColumnAndFleetAndResponse.getFleet(), optionalTrackedRaceName));
final RaceHandle raceHandle = adapter.startTracking(getService(), leaderboardAndRaceColumnAndFleetAndResponse.getLeaderboard(),
leaderboardAndRaceColumnAndFleetAndResponse.getRaceColumn(),
leaderboardAndRaceColumnAndFleetAndResponse.getFleet(),
@@ -17,6 +17,7 @@ import com.sap.sailing.server.gateway.serialization.impl.CourseAreaJsonSerialize
import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.LeaderboardSearchResultJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.TrackingConnectorInfoJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
import com.sap.sse.common.Util;
import com.sap.sse.common.search.KeywordQuery;
@@ -28,8 +29,10 @@ public class SearchResource extends AbstractSailingServerResource {
public SearchResource() {
final LeaderboardGroupBaseJsonSerializer leaderboardGroupSerializer = new LeaderboardGroupBaseJsonSerializer();
serializer = new LeaderboardSearchResultJsonSerializer(new EventBaseJsonSerializer(new VenueJsonSerializer(
new CourseAreaJsonSerializer()), leaderboardGroupSerializer), leaderboardGroupSerializer);
serializer = new LeaderboardSearchResultJsonSerializer(
new EventBaseJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()),
leaderboardGroupSerializer, new TrackingConnectorInfoJsonSerializer()),
leaderboardGroupSerializer);
}
private Result<LeaderboardSearchResult> search(KeywordQuery query) {
@@ -36,6 +36,8 @@ Wind tracking can be configured using optional request parameters.</p>
<div>correctWindDirectionByMagneticDeclination a boolean value, defaulting to true; if trackWind is true,
this parameter controls whether the wind directions received are to be corrected by the magnetic
declination</div>
<div>trackedRaceName can be used to specify a non-default name for the tracked race / RaceDefinition; if not
provided, a default name consisting of race column and fleet name will be constructed instead.</div>
</td>
</tr>
<tr>
@@ -85,6 +85,7 @@ import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRegatta;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
import com.sap.sailing.domain.tracking.TrackerManager;
import com.sap.sailing.domain.tracking.TrackingConnectorInfo;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.WindTracker;
import com.sap.sse.common.PairingListCreationException;
@@ -319,7 +320,8 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
void updateStoredLeaderboardGroup(LeaderboardGroup leaderboardGroup);
DynamicTrackedRace createTrackedRace(RegattaAndRaceIdentifier raceIdentifier, WindStore windStore,
long delayToLiveInMillis, long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed, boolean useMarkPassingCalculator, String trackingConnector);
long delayToLiveInMillis, long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed,
boolean useMarkPassingCalculator, TrackingConnectorInfo trackingConnectorInfo);
Regatta getOrCreateDefaultRegatta(String name, String boatClassName, Serializable id);
@@ -7,6 +7,7 @@ import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRegatta;
import com.sap.sailing.domain.tracking.TrackingConnectorInfo;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.server.interfaces.RacingEventService;
@@ -22,11 +23,11 @@ import com.sap.sailing.server.interfaces.RacingEventServiceOperation;
*
*/
public class CreateTrackedRace extends AbstractRaceOperation<DynamicTrackedRace> {
private static final long serialVersionUID = -3707097845987093245L;
private static final long serialVersionUID = 7164691177800524484L;
private final long millisecondsOverWhichToAverageWind;
private final long millisecondsOverWhichToAverageSpeed;
private final long delayToLiveInMillis;
private final String trackingConnector;
private final TrackingConnectorInfo trackingConnectorInfo;
/**
* If a {@link WindStore} is provided to this command, it will be used for the construction of the tracked race.
@@ -41,13 +42,14 @@ public class CreateTrackedRace extends AbstractRaceOperation<DynamicTrackedRace>
* won't be serialized. A receiver of this operation will therefore always use an {@link EmptyWindStore}.
*/
public CreateTrackedRace(RegattaAndRaceIdentifier raceIdentifier, WindStore windStore, long delayToLiveInMillis,
long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed, String trackingConnector) {
long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed,
TrackingConnectorInfo trackingConnectorInfo) {
super(raceIdentifier);
this.windStore = windStore;
this.delayToLiveInMillis = delayToLiveInMillis;
this.millisecondsOverWhichToAverageWind = millisecondsOverWhichToAverageWind;
this.millisecondsOverWhichToAverageSpeed = millisecondsOverWhichToAverageSpeed;
this.trackingConnector = trackingConnector;
this.trackingConnectorInfo = trackingConnectorInfo;
}
@Override
@@ -65,9 +67,9 @@ public class CreateTrackedRace extends AbstractRaceOperation<DynamicTrackedRace>
@Override
public DynamicTrackedRace internalApplyTo(RacingEventService toState) {
return toState.createTrackedRace(getRaceIdentifier(), windStore == null ? EmptyWindStore.INSTANCE : windStore,
delayToLiveInMillis, millisecondsOverWhichToAverageWind,
millisecondsOverWhichToAverageSpeed, /* useMarkPassingCalculator */ false, trackingConnector);
// no separate mark passing calculations in replica;
delayToLiveInMillis, millisecondsOverWhichToAverageWind, millisecondsOverWhichToAverageSpeed,
/* useMarkPassingCalculator */ false, trackingConnectorInfo);
// no separate mark passing calculations in replica;
// Mark passings are computed on master and are replicated separately.
// See UpdateMarkPassings
}

Some files were not shown because too many files have changed in this diff Show More