Merge branch 'master' into bug5179

This commit is contained in:
Steffen Schaefer committed 2020-01-15 11:22:12 +01:00
commit 214c28e974
132 files changed
+955 -344

No files matched your search

@@ -1,14 +1,17 @@
package com.sap.sailing.domain.common;
public class BranchIOConstants {
public static final String SAILINSIGHT_2_APP_BRANCHIO = "https://sailinsight20-app.sapsailing.com/invite";
public static final String SAILINSIGHT_APP_BRANCHIO = "https://sailinsight-app.sapsailing.com/invite";
public static final String SAILINSIGHT_2_APP_BRANCHIO = "https://sailinsight20-app.sapsailing.com/invite";
public static final String SAILINSIGHT_3_APP_BRANCHIO = "https://sailinsight30-app.sapsailing.com/invite";
public static final String SAILINSIGHT_APP_BRANCHIO_PATH = "checkinUrl";
public static final String BUOYPINGER_APP_BRANCHIO = "https://buoypinger-app.sapsailing.com/invite";
public static final String BUOYPINGER_APP_BRANCHIO_PATH = "checkinUrl";
public static final String OPEN_REGATTA_2_APP_BRANCHIO = "https://sailinsight20-app.sapsailing.com/publicInvite";
public static final String OPEN_REGATTA_2_APP_BRANCHIO_PATH = "checkinUrl";
public static final String OPEN_REGATTA_3_APP_BRANCHIO = "https://sailinsight30-app.sapsailing.com/publicInvite";
public static final String OPEN_REGATTA_3_APP_BRANCHIO_PATH = "checkinUrl";
private BranchIOConstants() {
};
}
}
@@ -3,7 +3,8 @@ package com.sap.sailing.domain.common;
public enum MailInvitationType {
LEGACY,
SailInsight1,
SailInsight2;
SailInsight2,
SailInsight3;
public static final String SYSTEM_PROPERTY_NAME = "com.sap.sailing.domain.tracking.MailInvitationType";
}
@@ -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() {
@@ -5,7 +5,6 @@ import java.util.Locale;
import com.sap.sailing.domain.common.BranchIOConstants;
public class BranchIO2RaceLogTrackingInvitationMailBuilder extends BranchIORaceLogTrackingInvitationMailBuilder {
BranchIO2RaceLogTrackingInvitationMailBuilder(Locale locale) {
super(locale);
}
@@ -20,5 +19,4 @@ public class BranchIO2RaceLogTrackingInvitationMailBuilder extends BranchIORaceL
// FIXME the app should in the future at some point also support bouy pinging, replace this then
return BranchIOConstants.BUOYPINGER_APP_BRANCHIO;
}
}
@@ -0,0 +1,24 @@
package com.sap.sailing.domain.racelogtracking.impl;
import java.util.Locale;
import com.sap.sailing.domain.common.BranchIOConstants;
public class BranchIO3RaceLogTrackingInvitationMailBuilder extends BranchIORaceLogTrackingInvitationMailBuilder {
BranchIO3RaceLogTrackingInvitationMailBuilder(Locale locale) {
super(locale);
}
@Override
protected String getSailInsightBranchIO() {
return BranchIOConstants.SAILINSIGHT_3_APP_BRANCHIO;
}
@Override
protected String getBouyPingerBranchIO() {
// FIXME the app should in the future at some point also support bouy pinging, replace this then
return BranchIOConstants.BUOYPINGER_APP_BRANCHIO;
}
}
@@ -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);
@@ -313,7 +314,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
@@ -362,6 +362,9 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter {
case SailInsight2:
mail = new BranchIO2RaceLogTrackingInvitationMailBuilder(locale);
break;
case SailInsight3:
mail = new BranchIO3RaceLogTrackingInvitationMailBuilder(locale);
break;
default:
throw new IllegalArgumentException("Unhandled mail type");
}
@@ -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();
}
@@ -56,6 +56,9 @@ public abstract class EventBaseImpl implements EventBase {
*/
protected EventBaseImpl(String name, TimePoint startDate, TimePoint endDate, Venue venue, boolean isPublic, UUID id) {
assert venue != null;
if (startDate != null && endDate != null && startDate.after(endDate)) {
throw new IllegalArgumentException("Event "+name+" cannot start after it ends. Start: "+startDate+", end: "+endDate);
}
this.id = id;
this.name = name;
this.startDate = startDate;
@@ -132,6 +135,9 @@ public abstract class EventBaseImpl implements EventBase {
@Override
public void setStartDate(TimePoint startDate) {
if (startDate != null && getEndDate() != null && getEndDate().before(startDate)) {
throw new IllegalArgumentException("Event start date ("+startDate+") for event "+this+" must not be after end date "+getEndDate());
}
this.startDate = startDate;
}
@@ -142,6 +148,9 @@ public abstract class EventBaseImpl implements EventBase {
@Override
public void setEndDate(TimePoint endDate) {
if (endDate != null && getStartDate() != null && getStartDate().after(endDate)) {
throw new IllegalArgumentException("Event end date ("+endDate+") for event "+this+" must not be before start date "+getStartDate());
}
this.endDate = endDate;
}
@@ -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;
@@ -410,10 +411,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));
@@ -317,7 +317,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);
@@ -353,7 +353,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) }));
@@ -317,7 +317,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());
@@ -641,9 +643,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());
@@ -740,11 +746,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;
}
}
@@ -7,6 +7,7 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
@@ -330,7 +331,7 @@ public class ORCPublicCertificateDatabaseImpl implements ORCPublicCertificateDat
builder = child.getTextContent();
break;
case "dxtDate":
issueDate = new MillisecondsTimePoint(isoTimestampFormat.parse(child.getTextContent()+"+0000")); // assume UTC
issueDate = new MillisecondsTimePoint(parseDate(child.getTextContent())); // assume UTC
break;
case "CertType":
certType = Integer.valueOf(child.getTextContent().trim());
@@ -350,6 +351,19 @@ public class ORCPublicCertificateDatabaseImpl implements ORCPublicCertificateDat
sailNumber, boatClassName, designer, builder, yearBuilt, issueDate, certType, isOneDesign, isProvisional);
}
private Date parseDate(String dateString) throws ParseException {
StringBuilder stringBuilder = new StringBuilder(dateString);
char timeZoneCharacter = stringBuilder.charAt(stringBuilder.length()-1);
if(timeZoneCharacter== 'z' || timeZoneCharacter == 'Z'|| timeZoneCharacter == 'X') {
stringBuilder.deleteCharAt(stringBuilder.length()-1);
}
if(false == stringBuilder.toString().contains("+")) {
stringBuilder.append("+0000");
}
return isoTimestampFormat.parse(stringBuilder.toString());
}
@Override
public ORCCertificate getCertificate(String referenceNumber) throws Exception {
final HttpClient client = new SystemDefaultHttpClient();
@@ -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" />
@@ -166,6 +166,7 @@ public class QRCodePlace extends AbstractBasePlace {
}
public String getPublicInviteBranchIOUrl() {
// TODO why is this specific to version 2 and not considering the default server setting for mailInvitationType?
return BranchIOConstants.OPEN_REGATTA_2_APP_BRANCHIO + "?" + QRCodePlace.PARAM_REGATTA_NAME + "="
+ encodeUrl(publicRegattaName) + "&" + QRCodePlace.PARAM_REGATTA_SECRET + "="
+ encodeUrl(regattaRegistrationLinkSecret) + "&" + QRCodePlace.PARAM_SERVER + "="
@@ -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;
}
@@ -144,12 +144,9 @@ public class RegattaDetailsComposite extends Composite {
Button button = new Button(stringMessages.registrationLinkShare(), new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
RegistrationLinkWithQRCode registrationLinkWithQRCode = new RegistrationLinkWithQRCode();
registrationLinkWithQRCode.setSecret(regatta.registrationLinkSecret);
sailingService.getMailType(new AsyncCallback<MailInvitationType>() {
@Override
public void onFailure(Throwable caught) {
logger.log(Level.SEVERE, "Could not determine MailInvitationType", caught);
@@ -221,21 +221,28 @@ public class RegattaLogAddDeviceMappingDialog extends DataEntryDialogWithDateTim
String url = DeviceMappingConstants.getDeviceMappingForRegattaLogUrl(baseUrlWithoutTrailingSlash,
eventIdAsString, leaderboardName, mappedItemType, mappedItemId, regattaRegisterSecret,
GwtUrlHelper.INSTANCE);
if (mailInvitationType == MailInvitationType.LEGACY) {
switch (mailInvitationType) {
case LEGACY:
// URL is already legacy
} else if (mailInvitationType == MailInvitationType.SailInsight1) {
break;
case SailInsight1:
url = BranchIOConstants.SAILINSIGHT_APP_BRANCHIO + "?"
+ BranchIOConstants.SAILINSIGHT_APP_BRANCHIO_PATH + "="
+ GwtUrlHelper.INSTANCE.encodeQueryString(url);
} else if (mailInvitationType == MailInvitationType.SailInsight2) {
break;
case SailInsight2:
url = BranchIOConstants.SAILINSIGHT_2_APP_BRANCHIO + "?"
+ BranchIOConstants.OPEN_REGATTA_2_APP_BRANCHIO_PATH + "="
+ GwtUrlHelper.INSTANCE.encodeQueryString(url);
}
else {
break;
case SailInsight3:
url = BranchIOConstants.SAILINSIGHT_3_APP_BRANCHIO + "?"
+ BranchIOConstants.OPEN_REGATTA_3_APP_BRANCHIO_PATH + "="
+ GwtUrlHelper.INSTANCE.encodeQueryString(url);
break;
default:
throw new QRCodeURLCreationException("Unknown mail invitation type: " + mailInvitationType);
}
return url;
}
});
@@ -63,14 +63,10 @@ public class RegistrationLinkWithQRCodeDialog extends DataEntryDialog<Registrati
this.invitationType = invitationType;
this.registrationLinkWithQRCode = registrationLinkWithQRCode == null ? new RegistrationLinkWithQRCode()
: registrationLinkWithQRCode;
registrationLinkPanel = new CaptionPanel(stringMessages.registrationLinkUrl());
registrationLinkPanelContent = new VerticalPanel();
registrationLinkPanel.add(registrationLinkPanelContent);
final Label eventExplain = new Label(stringMessages.event());
events = createGenericListBox(new ValueBuilder<EventDTO>() {
@Override
public String getValue(EventDTO item) {
@@ -98,10 +94,8 @@ public class RegistrationLinkWithQRCodeDialog extends DataEntryDialog<Registrati
updateDisplayWidgets();
}
});
registrationLinkPanelContent.add(eventExplain);
registrationLinkPanelContent.add(events);
registrationLinkExplain = new Label(stringMessages.registrationLinkUrlExplain());
registrationLinkPanelContent.add(registrationLinkExplain);
urlTextBox = createTextBox("URL", 100);
@@ -109,7 +103,6 @@ public class RegistrationLinkWithQRCodeDialog extends DataEntryDialog<Registrati
registrationLinkPanelContent.add(urlTextBox);
Anchor copyAnchor = new Anchor(stringMessages.registrationLinkUrlCopy());
copyAnchor.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
urlTextBox.setFocus(true);
@@ -118,7 +111,6 @@ public class RegistrationLinkWithQRCodeDialog extends DataEntryDialog<Registrati
}
});
registrationLinkPanelContent.add(copyAnchor);
barcodePanel = new CaptionPanel(stringMessages.registrationLinkDialogQrcode());
barcodePanelContent = new VerticalPanel();
barcodePanel.add(barcodePanelContent);
@@ -144,7 +136,6 @@ public class RegistrationLinkWithQRCodeDialog extends DataEntryDialog<Registrati
}
final VerticalPanel dialogPanel = new VerticalPanel();
panel.add(dialogPanel);
dialogPanel.add(registrationLinkPanel);
dialogPanel.add(barcodePanel);
return panel;
@@ -155,29 +146,27 @@ public class RegistrationLinkWithQRCodeDialog extends DataEntryDialog<Registrati
Notification.notify(stringMessages.noEventSelected(), NotificationType.ERROR);
return;
}
String baseUrl = GWT.getHostPageBaseURL();
if (baseUrl.endsWith("/")) {
baseUrl = baseUrl.substring(0, baseUrl.lastIndexOf("/"));
baseUrl = baseUrl.substring(0, baseUrl.indexOf("/gwt"));
}
final String eventIdAsString = events.getValue().id.toString();
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("regatta_name", regattaName);
parameters.put("secret", secret);
parameters.put("server", baseUrl);
parameters.put("event_id", eventIdAsString);
// TODO decide OPEN_REGATTA link variant based on invitationType
String deeplinkUrl = BranchIO.generateLink(BranchIOConstants.OPEN_REGATTA_2_APP_BRANCHIO, parameters,
URL::encodeQueryString);
urlTextBox.setText(deeplinkUrl);
if (invitationType != MailInvitationType.SailInsight2) {
if (invitationType != MailInvitationType.SailInsight2 &&
invitationType != MailInvitationType.SailInsight3) { // TODO it would be better to make it a property of an enum literal whether open regatta invitation is possible
getStatusLabel().setText(stringMessages.warningSailInsightVersion());
getStatusLabel().setStyleName("errorLabel");
}
sailingService.openRegattaRegistrationQrCode(deeplinkUrl, new AsyncCallback<String>() {
@Override
public void onFailure(Throwable caught) {
GWT.log("Qrcode generation failed: ", caught);
@@ -187,9 +176,7 @@ public class RegistrationLinkWithQRCodeDialog extends DataEntryDialog<Registrati
public void onSuccess(String result) {
GWT.log("Qrcode generated for url: " + deeplinkUrl);
qrCodeImage.setUrl("data:image/png;base64, " + result);
}
});
}
@@ -1712,7 +1712,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.
*
@@ -397,6 +397,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;
@@ -494,6 +495,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;
@@ -1999,7 +2001,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) {
@@ -2053,9 +2055,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());
@@ -40,7 +40,7 @@
-->
<system-property>
<name>webdriver.chrome.driver</name>
<value>C:\apps\ChromeSeleniumDriver\chromedriver.exe</value>
<value>/usr/bin/chromedriver</value>
</system-property>
<!--
You need geckodriver to be able to run Selenium tests on Firefox.
@@ -50,7 +50,7 @@
-->
<system-property>
<name>webdriver.gecko.driver</name>
<value>/path/to/geckodriver.exe</value>
<value>/usr/bin/geckodriver</value>
</system-property>
<!--
geckodriver automatically finds an installed version of Firefox.
@@ -86,12 +86,14 @@
The capabilities section can be used for fine tuning of the driver (e.g. version). For more informations see the
pages mentioned above.
-->
<!--
<!-- -->
<driver-definition class="org.openqa.selenium.firefox.FirefoxDriver">
</driver-definition>
-->
<!-- -->
<!--
<driver-definition class="org.openqa.selenium.chrome.ChromeDriver">
</driver-definition>
-->
<!--
<driver-definition class="org.openqa.selenium.ie.InternetExplorerDriver">
<capabilities>
@@ -104,7 +104,7 @@ public class RegattaApi {
final String url = REGATTAS + "/" + regattaName + ADD_RACE_COLUMN_URL;
final Map<String, String> queryParams = new TreeMap<>();
queryParams.put("prefix", prefix);
queryParams.put("numberOfRaces", numberOfRaces != null ? numberOfRaces.toString() : null);
queryParams.put("numberofraces", numberOfRaces != null ? numberOfRaces.toString() : null);
final JSONArray json = ctx.post(url, queryParams);
final RaceColumn[] result = new RaceColumn[json.size()];
for (int i = 0; i < json.size(); i++) {
@@ -159,15 +159,14 @@ public class RegattaApiTest extends AbstractSeleniumTest {
RaceColumn[] result = regattaApi.addRaceColumn(ctx, EVENT_NAME, "T", 5);
assertEquals("read: racecolumn.seriesname is different", "Default", result[0].getSeriesName());
assertEquals("read: racecolumn.racename is different", "T1", result[0].getRaceName());
// assertEquals("read: racecolumn.seriesname is different", "Default", result[4].getSeriesName());
// assertEquals("read: racecolumn.racename is different", "T5", result[4].getRaceName());
assertEquals("read: racecolumn.seriesname is different", "Default", result[4].getSeriesName());
assertEquals("read: racecolumn.racename is different", "T5", result[4].getRaceName());
}
@Test
public void testRegisterExistingCompetitorWithSecret() {
final AdminConsolePage adminConsole = goToPage(getWebDriver(), getContextRoot());
adminConsole.goToLocalServerPanel().setSelfServiceServer(true);
SecurityApi securityApi = new SecurityApi();
final ApiContext adminSecurityCtx = createAdminApiContext(getContextRoot(), ApiContext.SECURITY_CONTEXT);
securityApi.createUser(adminSecurityCtx, "donald", "Donald Duck", null, "daisy0815");
@@ -176,22 +175,17 @@ public class RegattaApiTest extends AbstractSeleniumTest {
ApiContext.SECURITY_CONTEXT, "donald", "daisy0815");
securityApi.createUser(adminSecurityCtx, "dagobert", "Dagobert Duck", null, "daisy1337");
final ApiContext userOwningEventCtx = createApiContext(getContextRoot(), SERVER_CONTEXT, "dagobert", "daisy1337");
// TODO we currently can't just create a competitor using the API. This is only possible by using a temporary Event/Regatta.
eventApi.createEvent(userWithCompetitorCtx, EVENT_NAME, BOAT_CLASS, CLOSED, "default");
Competitor competitor = regattaApi.createAndAddCompetitor(userWithCompetitorCtx, EVENT_NAME, BOAT_CLASS, null, "donald", "USA");
// ensure the reader can actually see the competitor
UserGroup group = usergroupApi.getUserGroupByName(userWithCompetitorAndSecurityCtx, "donald"+SecurityService.TENANT_SUFFIX);
usergroupApi.addRoleToGroup(userWithCompetitorAndSecurityCtx, group.getGroupId(),
UUID.fromString(/* sailing viewer role id */"c42948df-517b-45cb-9fa9-d1e79f18e115"), true);
// This is the event to register the existing competitor for
Event eventToRegisterExistingCompetitor = eventApi.createEvent(userOwningEventCtx, OTHER_EVENT_NAME, BOAT_CLASS, CompetitorRegistrationType.OPEN_UNMODERATED, "default");
regattaApi.addCompetitor(userWithCompetitorCtx, OTHER_EVENT_NAME, competitor.getId(), Optional.of(eventToRegisterExistingCompetitor.getSecret()));
Competitor[] competitors = regattaApi.getCompetitors(userOwningEventCtx, OTHER_EVENT_NAME);
assertEquals(1, competitors.length);
assertEquals(competitor.getId(), competitors[0].getId());
}
Loaded 100 of 132 files, more files were not shown because too many files have changed in this diff. Show more