From 39ea54f73ae3ca862d0cffdc077a523e8bdb74a2 Mon Sep 17 00:00:00 2001 From: Benjamin Barth Date: Tue, 24 Jul 2018 12:58:45 +0200 Subject: [PATCH 01/53] bug4483 Added a label to the number of races on to of the progress bars --- .../partials/multiregattalist/MultiRegattaListStepsBody.java | 4 ++-- .../gwt/home/mobile/partials/eventsteps/EventStepsPhase.java | 4 ++-- .../java/com/sap/sailing/gwt/ui/client/StringMessages.java | 2 +- .../com/sap/sailing/gwt/ui/client/StringMessages.properties | 3 ++- .../sap/sailing/gwt/ui/client/StringMessages_de.properties | 3 ++- .../sap/sailing/gwt/ui/client/StringMessages_es.properties | 1 - .../sap/sailing/gwt/ui/client/StringMessages_fr.properties | 1 - .../sap/sailing/gwt/ui/client/StringMessages_ja.properties | 1 - .../sap/sailing/gwt/ui/client/StringMessages_pt.properties | 1 - .../sap/sailing/gwt/ui/client/StringMessages_ru.properties | 1 - .../sap/sailing/gwt/ui/client/StringMessages_zh.properties | 1 - 11 files changed, 9 insertions(+), 13 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/multiregattalist/MultiRegattaListStepsBody.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/multiregattalist/MultiRegattaListStepsBody.java index f1ce515f0bb..a2dc107749d 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/multiregattalist/MultiRegattaListStepsBody.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/multiregattalist/MultiRegattaListStepsBody.java @@ -49,10 +49,10 @@ public class MultiRegattaListStepsBody extends UIObject implements RequiresResiz mediumNameDummyUi.setInnerText(seriesNameMedium = caculateSeriesNameMedium()); seriesNameShort = caculateSeriesNameShort(); if (seriesProgress.isCompleted()) { - progressUi.setInnerText(String.valueOf(seriesProgress.getTotalRaceCount())); + progressUi.setInnerText(I18N.racesCount(seriesProgress.getTotalRaceCount())); } else { checkUi.getStyle().setDisplay(Display.NONE); - progressUi.setInnerText(I18N.currentOfTotal( + progressUi.setInnerText(I18N.currentOfTotalRaces( seriesProgress.getProgressRaceCount(), seriesProgress.getTotalRaceCount())); } addFleetProgresses(seriesProgress.getFleetState(), seriesProgress.getMaxRacesPerFleet()); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsPhase.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsPhase.java index 058d4bd75b9..3480d6fc5d0 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsPhase.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsPhase.java @@ -35,11 +35,11 @@ public class EventStepsPhase extends Composite { initWidget(uiBinder.createAndBindUi(this)); nameUi.setInnerText(DEFAULT_SERIES_NAME.equals(seriesProgress.getName()) ? I18N.races() : seriesProgress.getName()); if (seriesProgress.isCompleted()) { - progressUi.setInnerText(String.valueOf(seriesProgress.getTotalRaceCount())); + progressUi.setInnerText(I18N.racesCount(seriesProgress.getTotalRaceCount())); } else { checkUi.getStyle().setDisplay(Display.NONE); int current = seriesProgress.getProgressRaceCount(), total = seriesProgress.getTotalRaceCount(); - progressUi.setInnerText(I18N.currentOfTotal(current, total)); + progressUi.setInnerText(I18N.currentOfTotalRaces(current, total)); } if (seriesProgress.getProgressRaceCount() == 0) { addStyleName(EventStepsResources.INSTANCE.css().eventsteps_phases_phaseinactive()); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java index cc7951e05cc..f2ef38ed9ab 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java @@ -1441,7 +1441,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, String courseGeometry(); String degreesToWind(String diff); String miniLeeaderboardLegendText(); - String currentOfTotal(int current, int total); + String currentOfTotalRaces(int current, @PluralCount(DefaultRule_1_0n.class) int total); String noFinishedRaces(); String racesOverview(); String listFormatLabel(); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties index 8dd85fc710c..107537d2c53 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties @@ -1428,7 +1428,8 @@ numberOfRacesShort=# Races courseGeometry=Course Geometry degreesToWind={0}° to wind miniLeeaderboardLegendText=Shows the points along with the number of races per competitor -currentOfTotal={0,number}/{1,number} +currentOfTotalRaces={0,number}/{1,number} races +currentOfTotalRaces[one]={0,number}/{1,number} race noFinishedRaces=There are no finished races yet racesOverview=Races overview listFormatLabel=List format diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties index 48ef82f8c55..8227d8dbaa6 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties @@ -1411,7 +1411,8 @@ numberOfRacesShort=# Rennen courseGeometry=Kursgeometrie degreesToWind={0}° zum Wind miniLeeaderboardLegendText=Es werden die Punkte und die Anzahl Rennen je Team angezeigt -currentOfTotal={0,number}/{1,number} +currentOfTotalRaces={0,number}/{1,number} Rennen +currentOfTotalRaces[one]={0,number}/{1,number} Rennen noFinishedRaces=Es wurden noch keine Wettfahrten beendet. racesOverview=Wettfahrtübersicht listFormatLabel=Listenansicht diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_es.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_es.properties index 50155bb02e9..0a4e37881d5 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_es.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_es.properties @@ -1421,7 +1421,6 @@ numberOfRacesShort=Nº regatas courseGeometry=Geometría de la regata degreesToWind={0}° respecto al viento miniLeeaderboardLegendText=Muestra los puntos y el número de carreras por competidor -currentOfTotal={0,number}/{1,number} noFinishedRaces=Todavía no ha finalizado ninguna carrera racesOverview=Resumen de carreras listFormatLabel=Formato de lista diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_fr.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_fr.properties index cd84fe961fd..e8d14957744 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_fr.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_fr.properties @@ -1421,7 +1421,6 @@ numberOfRacesShort=Nombre de courses courseGeometry=Géométrie du parcours degreesToWind={0}° au vent miniLeeaderboardLegendText=Affiche les points associés au nombre de courses par concurrent -currentOfTotal={0,number}/{1,number} noFinishedRaces=Aucune course terminée pour l''instant. racesOverview=Synthèse des courses listFormatLabel=Format de liste diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ja.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ja.properties index fa4ad030dc2..328737b10bc 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ja.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ja.properties @@ -1421,7 +1421,6 @@ numberOfRacesShort=# レース courseGeometry=コース配置 degreesToWind=風と {0}° miniLeeaderboardLegendText=競技者別にレース数とともに得点を表示 -currentOfTotal={0,number}/{1,number} noFinishedRaces=フィニッシュしたレースがまだありません。 racesOverview=レース概要 listFormatLabel=レース一覧 diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_pt.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_pt.properties index 5bad9ffc42c..5aa4add0f2f 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_pt.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_pt.properties @@ -1421,7 +1421,6 @@ numberOfRacesShort=Nº de corridas courseGeometry=Geometria do percurso degreesToWind={0}° para vento miniLeeaderboardLegendText=Exibe os pontos juntamente com o número de corridas por competidor -currentOfTotal={0,number}/{1,number} noFinishedRaces=Ainda não existem corridas concluídas. racesOverview=Síntese de corridas listFormatLabel=Formato de lista diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties index c2e3bbc1ab1..f8ee0825209 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties @@ -1421,7 +1421,6 @@ numberOfRacesShort=Гонки courseGeometry=Геометрия курса degreesToWind={0}° к ветру miniLeeaderboardLegendText=Показывает баллы и число гонок каждого участника -currentOfTotal={0,number}/{1,number} noFinishedRaces=Завершенных гонок еще нет racesOverview=Обзор гонок listFormatLabel=Формат списка diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties index 0c2450d869e..dfe289bd213 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties @@ -1421,7 +1421,6 @@ numberOfRacesShort=比赛轮次数 courseGeometry=场地几何结构 degreesToWind={0}°(相对于风) miniLeeaderboardLegendText=显示分数以及各参赛队的比赛轮次数 -currentOfTotal={0,number}/{1,number} noFinishedRaces=没有结束的比赛轮次 racesOverview=比赛轮次总览 listFormatLabel=清单格式 From 2a12da9b006071ef07d7ef746fdd9f32cca0c0ef Mon Sep 17 00:00:00 2001 From: Benjamin Barth Date: Tue, 24 Jul 2018 17:51:12 +0200 Subject: [PATCH 02/53] bug4483 Optionally provide a preferred series' name when navigation to RegattaRacesPlace --- .../regatta/racestab/RegattaRacesPlace.java | 19 +++++++++++++++++-- .../RegattaRacesNavigationProvider.java | 2 ++ .../places/event/AbstractEventActivity.java | 6 ++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/event/regatta/racestab/RegattaRacesPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/event/regatta/racestab/RegattaRacesPlace.java index 574760b72cb..4ae3f62a362 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/event/regatta/racestab/RegattaRacesPlace.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/event/regatta/racestab/RegattaRacesPlace.java @@ -1,5 +1,7 @@ package com.sap.sailing.gwt.home.desktop.places.event.regatta.racestab; +import java.util.Optional; + import com.google.gwt.place.shared.Prefix; import com.sap.sailing.gwt.home.desktop.places.event.regatta.AbstractEventRegattaPlace; import com.sap.sailing.gwt.home.shared.app.HasMobileVersion; @@ -8,24 +10,37 @@ import com.sap.sailing.gwt.home.shared.places.event.AbstractEventPlace; import com.sap.sailing.gwt.home.shared.places.event.EventContext; public class RegattaRacesPlace extends AbstractEventRegattaPlace implements HasMobileVersion { + + private final String preferredSeriesName; + public RegattaRacesPlace(String id, String leaderboardName) { super(id, leaderboardName); + this.preferredSeriesName = null; } public RegattaRacesPlace(EventContext context) { + this(context, null); + } + + public RegattaRacesPlace(EventContext context, String preferredSeriesName) { super(context); + this.preferredSeriesName = preferredSeriesName; + } + + public final Optional getPreferredSeriesName() { + return Optional.ofNullable(preferredSeriesName); } @Override public AbstractEventRegattaPlace newInstanceWithContext(EventContext ctx) { - return new RegattaRacesPlace(ctx); + return new RegattaRacesPlace(ctx, null); } @Prefix(PlaceTokenPrefixes.RegattaRaces) public static class Tokenizer extends AbstractEventPlace.Tokenizer { @Override protected RegattaRacesPlace getRealPlace(EventContext context) { - return new RegattaRacesPlace(context); + return new RegattaRacesPlace(context, null); } } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/RegattaRacesNavigationProvider.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/RegattaRacesNavigationProvider.java index d4f921b1a54..8c3655e1abf 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/RegattaRacesNavigationProvider.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/RegattaRacesNavigationProvider.java @@ -5,4 +5,6 @@ import com.sap.sailing.gwt.home.shared.app.PlaceNavigation; public interface RegattaRacesNavigationProvider { PlaceNavigation getRegattaRacesNavigation(String regattaId); + + PlaceNavigation getRegattaRacesNavigation(String regattaId, String seriesName); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/AbstractEventActivity.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/AbstractEventActivity.java index 0ac77756ff0..96e653ce512 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/AbstractEventActivity.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/AbstractEventActivity.java @@ -247,6 +247,12 @@ public abstract class AbstractEventActivity ex EventContext ctx = new EventContext(getCtx()).withRegattaId(regattaId).withRegattaAnalyticsManager(null); return clientFactory.getNavigator().getEventNavigation(new RegattaRacesPlace(ctx), null, false); } + + @Override + public PlaceNavigation getRegattaRacesNavigation(String regattaId, String prefSeriesName) { + EventContext ctx = new EventContext(getCtx()).withRegattaId(regattaId).withRegattaAnalyticsManager(null); + return clientFactory.getNavigator().getEventNavigation(new RegattaRacesPlace(ctx, prefSeriesName), null, false); + } public PlaceNavigation getLatesNewsNavigation() { EventContext ctx = new EventContext(getCtx()).withRegattaId(null).withRegattaAnalyticsManager(null); From 2cdf3a578b851f1d4e3fe22229098ca812c1c8b0 Mon Sep 17 00:00:00 2001 From: Benjamin Barth Date: Tue, 24 Jul 2018 17:57:14 +0200 Subject: [PATCH 03/53] bug4483 Enabled navigation from series progresses to races page --- .../home/mobile/partials/eventsteps/EventSteps.gss | 3 +++ .../mobile/partials/eventsteps/EventSteps.java | 10 ++++++++-- .../partials/eventsteps/EventStepsPhase.java | 7 ++++++- .../partials/eventsteps/EventStepsPhase.ui.xml | 14 ++++++++------ .../partials/eventsteps/EventStepsResources.java | 1 + .../overview/regatta/RegattaOverviewImpl.java | 6 +++++- 6 files changed, 31 insertions(+), 10 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventSteps.gss b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventSteps.gss index 282125f546d..7471b4468c8 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventSteps.gss +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventSteps.gss @@ -21,6 +21,9 @@ .eventsteps_phases_phaseinactive { color: #999; } +.eventsteps_phases_phase_link { + color: #000; +} /* .eventsteps_phases_phase:nth-child(2n-1) { */ /* padding-right: 0.333333333333333em; */ /* } */ diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventSteps.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventSteps.java index 53cc73e4a0e..0f62c0792f3 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventSteps.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventSteps.java @@ -1,5 +1,7 @@ package com.sap.sailing.gwt.home.mobile.partials.eventsteps; +import java.util.function.Function; + import com.google.gwt.core.client.GWT; import com.google.gwt.resources.client.ImageResource; import com.google.gwt.uibinder.client.UiBinder; @@ -11,6 +13,7 @@ import com.sap.sailing.gwt.home.communication.regatta.RegattaProgressSeriesDTO; import com.sap.sailing.gwt.home.communication.regatta.RegattaWithProgressDTO; import com.sap.sailing.gwt.home.mobile.partials.section.MobileSection; import com.sap.sailing.gwt.home.mobile.partials.sectionHeader.SectionHeaderContent; +import com.sap.sailing.gwt.home.shared.app.PlaceNavigation; import com.sap.sailing.gwt.home.shared.refresh.RefreshableWidget; public class EventSteps extends Composite implements RefreshableWidget { @@ -22,8 +25,10 @@ public class EventSteps extends Composite implements RefreshableWidget> racesNavigationFactory; - public EventSteps(RegattaMetadataDTO regatta) { + public EventSteps(RegattaMetadataDTO regatta, Function> racesNavigationFactory) { + this.racesNavigationFactory = racesNavigationFactory; EventStepsResources.INSTANCE.css().ensureInjected(); initWidget(regattaProgessUi = uiBinder.createAndBindUi(this)); ImageResource boatClassIcon = BoatClassImageResolver.getBoatClassIconResource(regatta.getBoatClass()); @@ -37,7 +42,8 @@ public class EventSteps extends Composite implements RefreshableWidget navigation = racesNavigationFactory.apply(seriesProgress.getName()); + regattaProgessUi.addContent(new EventStepsPhase(seriesProgress, navigation)); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsPhase.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsPhase.java index 3480d6fc5d0..141d2815cfb 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsPhase.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsPhase.java @@ -6,6 +6,7 @@ import java.util.Map; import java.util.Map.Entry; import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.AnchorElement; import com.google.gwt.dom.client.DivElement; import com.google.gwt.dom.client.ImageElement; import com.google.gwt.dom.client.Style.Display; @@ -16,7 +17,9 @@ import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.gwt.home.communication.race.FleetMetadataDTO; import com.sap.sailing.gwt.home.communication.regatta.RegattaProgressFleetDTO; import com.sap.sailing.gwt.home.communication.regatta.RegattaProgressSeriesDTO; +import com.sap.sailing.gwt.home.shared.app.PlaceNavigation; import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sse.gwt.client.LinkUtil; public class EventStepsPhase extends Composite { @@ -26,13 +29,15 @@ public class EventStepsPhase extends Composite { interface EventStepsPhaseUiBinder extends UiBinder { } + @UiField AnchorElement anchorUi; @UiField DivElement nameUi; @UiField ImageElement checkUi; @UiField DivElement progressUi; @UiField DivElement fleetsContainerUi; - public EventStepsPhase(RegattaProgressSeriesDTO seriesProgress) { + public EventStepsPhase(RegattaProgressSeriesDTO seriesProgress, PlaceNavigation placeNavigation) { initWidget(uiBinder.createAndBindUi(this)); + LinkUtil.configureForAction(anchorUi, () -> placeNavigation.goToPlace()); nameUi.setInnerText(DEFAULT_SERIES_NAME.equals(seriesProgress.getName()) ? I18N.races() : seriesProgress.getName()); if (seriesProgress.isCompleted()) { progressUi.setInnerText(I18N.racesCount(seriesProgress.getTotalRaceCount())); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsPhase.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsPhase.ui.xml index 7cece0b816b..2ac9004e380 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsPhase.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsPhase.ui.xml @@ -6,11 +6,13 @@ -
-
- -
-
-
+ +
+
+ +
+
+
+
\ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsResources.java index 1bc6a0dfbd2..46e49f87206 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsResources.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsResources.java @@ -16,6 +16,7 @@ public interface EventStepsResources extends ClientBundle { String eventsteps_phases(); String eventsteps_phases_phase(); String eventsteps_phases_phaseinactive(); + String eventsteps_phases_phase_link(); String eventsteps_phases_phase_name(); String eventsteps_phases_phase_progressbar(); String eventsteps_phases_phase_progressbar_fleet(); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/overview/regatta/RegattaOverviewImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/overview/regatta/RegattaOverviewImpl.java index 83403e8d3a8..afe0f4b5e58 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/overview/regatta/RegattaOverviewImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/overview/regatta/RegattaOverviewImpl.java @@ -3,6 +3,7 @@ package com.sap.sailing.gwt.home.mobile.places.event.overview.regatta; import java.util.Collection; import java.util.Map; import java.util.Set; +import java.util.function.Function; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Panel; @@ -19,6 +20,7 @@ import com.sap.sailing.gwt.home.mobile.partials.quickfinder.Quickfinder; import com.sap.sailing.gwt.home.mobile.places.QuickfinderPresenter; import com.sap.sailing.gwt.home.mobile.places.event.EventViewBase; import com.sap.sailing.gwt.home.mobile.places.event.overview.AbstractEventOverview; +import com.sap.sailing.gwt.home.shared.app.PlaceNavigation; import com.sap.sailing.gwt.ui.client.FlagImageResolver; import com.sap.sailing.gwt.ui.client.StringMessages; @@ -54,7 +56,9 @@ public class RegattaOverviewImpl extends AbstractEventOverview { } private void setupProgress(Panel container) { - eventStepsUi = new EventSteps(currentPresenter.getRegatta()); + final Function> racesNavigationFactory = prefSeriesName -> currentPresenter + .getRegattaRacesNavigation(getRegattaId(), prefSeriesName); + eventStepsUi = new EventSteps(currentPresenter.getRegatta(), racesNavigationFactory); refreshManager.add(eventStepsUi, new GetRegattaWithProgressAction(getEventId(), getRegattaId())); container.add(eventStepsUi); } From b217ae2f7b5e697df68cdacfba9fd826bf35c310 Mon Sep 17 00:00:00 2001 From: Benjamin Barth Date: Tue, 24 Jul 2018 18:01:06 +0200 Subject: [PATCH 04/53] bug4483 Added first version of util method to scroll an element to the top --- .../src/com/sap/sse/gwt/client/DOMUtils.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/DOMUtils.java diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/DOMUtils.java b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/DOMUtils.java new file mode 100644 index 00000000000..639d68e0816 --- /dev/null +++ b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/DOMUtils.java @@ -0,0 +1,37 @@ +package com.sap.sse.gwt.client; + +import com.google.gwt.dom.client.Element; + +/** + * Utility class contained convenience methods regarding DOM operations. + */ +public final class DOMUtils { + + private DOMUtils() { + } + + /** + * Scrolls the top of the provided {@link Element element} to the top of the viewport. + * + * @param element + * {@link Element} to scroll to the top + */ + public static void scrollToTop(final Element element) { + int top = getOffsetTopOf(element); + Element current = element.getParentElement(); + while (current != null) { + if (top != current.getScrollTop()) { + current.setScrollTop(top); + } + top += getOffsetTopOf(current) - current.getScrollTop(); + current = current.getParentElement(); + } + } + + private static int getOffsetTopOf(final Element element) { + final int top = element.getOffsetTop(); + final boolean parentIsOffsetParent = element.getParentElement() == element.getOffsetParent(); + return parentIsOffsetParent ? top : top - element.getParentElement().getOffsetTop(); + } + +} \ No newline at end of file From 8f290d5f18de80a4cf2b8c4ec300a0c334596ddb Mon Sep 17 00:00:00 2001 From: Benjamin Barth Date: Tue, 24 Jul 2018 18:01:57 +0200 Subject: [PATCH 05/53] bug4483 Scroll tabbed series to the top when navigating via progress bar --- .../regattacompetition/RegattaCompetition.java | 9 +++++++++ .../home/mobile/places/event/races/RacesActivity.java | 6 ++++++ .../gwt/home/mobile/places/event/races/RacesView.java | 4 ++++ .../home/mobile/places/event/races/RacesViewImpl.java | 10 ++++++++++ 4 files changed, 29 insertions(+) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattacompetition/RegattaCompetition.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattacompetition/RegattaCompetition.java index 45a344513b3..1cbe1137bf2 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattacompetition/RegattaCompetition.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattacompetition/RegattaCompetition.java @@ -1,5 +1,8 @@ package com.sap.sailing.gwt.home.mobile.partials.regattacompetition; +import java.util.HashMap; +import java.util.Map; + import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; @@ -8,6 +11,7 @@ import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.gwt.home.communication.event.RaceCompetitionFormatSeriesDTO; import com.sap.sailing.gwt.home.shared.partials.regattacompetition.RegattaCompetitionView; +import com.sap.sse.gwt.client.DOMUtils; public class RegattaCompetition extends Composite implements RegattaCompetitionView { @@ -17,6 +21,7 @@ public class RegattaCompetition extends Composite implements RegattaCompetitionV } @UiField FlowPanel regattaSeriesContainerUi; + private final Map seriesNameToUiComponent = new HashMap<>(); public RegattaCompetition() { RegattaCompetitionResources.INSTANCE.css().ensureInjected(); @@ -31,8 +36,12 @@ public class RegattaCompetition extends Composite implements RegattaCompetitionV @Override public RegattaCompetitionSeriesView addSeriesView(RaceCompetitionFormatSeriesDTO series) { RegattaCompetitionSeries seriesView = new RegattaCompetitionSeries(series); + seriesNameToUiComponent.put(series.getSeriesName(), seriesView); regattaSeriesContainerUi.add(seriesView); return seriesView; } + public void scrollToSeries(final String seriesName) { + DOMUtils.scrollToTop(seriesNameToUiComponent.get(seriesName).getElement()); + } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/races/RacesActivity.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/races/RacesActivity.java index bac62f55092..52165919c9a 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/races/RacesActivity.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/races/RacesActivity.java @@ -1,6 +1,7 @@ package com.sap.sailing.gwt.home.mobile.places.event.races; import java.util.List; +import java.util.Optional; import com.sap.sailing.gwt.home.communication.eventview.EventViewDTO; import com.sap.sailing.gwt.home.desktop.places.event.regatta.racestab.RegattaRacesPlace; @@ -32,4 +33,9 @@ public class RacesActivity extends AbstractEventActivity impl initQuickfinder(view, true); return view; } + + @Override + public Optional getPreferredSeriesName() { + return getPlace().getPreferredSeriesName(); + } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/races/RacesView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/races/RacesView.java index e457c2af812..eca0d41c55d 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/races/RacesView.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/races/RacesView.java @@ -1,10 +1,14 @@ package com.sap.sailing.gwt.home.mobile.places.event.races; +import java.util.Optional; + import com.sap.sailing.gwt.home.mobile.places.event.EventViewBase; public interface RacesView extends EventViewBase { public interface Presenter extends EventViewBase.Presenter { + + Optional getPreferredSeriesName(); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/races/RacesViewImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/races/RacesViewImpl.java index 1aca7f4fea0..307f364b80b 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/races/RacesViewImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/races/RacesViewImpl.java @@ -7,11 +7,13 @@ import java.util.Map; import java.util.Set; import com.google.gwt.core.client.GWT; +import com.google.gwt.core.client.Scheduler; 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.gwt.home.communication.event.EventReferenceWithStateDTO; import com.sap.sailing.gwt.home.communication.event.GetCompetitionFormatRacesAction; +import com.sap.sailing.gwt.home.communication.event.RaceCompetitionFormatSeriesDTO; import com.sap.sailing.gwt.home.communication.event.SimpleCompetitorDTO; import com.sap.sailing.gwt.home.communication.eventview.RegattaMetadataDTO; import com.sap.sailing.gwt.home.communication.race.SimpleRaceMetadataDTO; @@ -27,6 +29,7 @@ import com.sap.sailing.gwt.home.shared.partials.filter.RacesByCompetitorTextBoxF import com.sap.sailing.gwt.home.shared.partials.placeholder.InfoPlaceholder; import com.sap.sailing.gwt.home.shared.partials.regattacompetition.RegattaCompetitionPresenter; import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sse.gwt.dispatch.shared.commands.ListResult; public class RacesViewImpl extends AbstractEventView implements RacesView { @@ -71,6 +74,13 @@ public class RacesViewImpl extends AbstractEventView implem protected String getRaceViewerURL(SimpleRaceMetadataDTO raceMetadata, String mode) { return currentPresenter.getRaceViewerURL(raceMetadata, mode); } + + @Override + public void setData(ListResult data) { + super.setData(data); + Scheduler.get().scheduleDeferred( + () -> currentPresenter.getPreferredSeriesName().ifPresent(regattaCompetitionUi::scrollToSeries)); + } } private class RacesViewImplFilterPresenter extends FilterPresenter { From 95da32f91e702dc2fdeddc94e66fc9f1051a002c Mon Sep 17 00:00:00 2001 From: Benjamin Barth Date: Wed, 25 Jul 2018 13:57:55 +0200 Subject: [PATCH 06/53] bug4483 Always show series name on top of the progress bar except there's only the default series --- .../multiregattalist/MultiRegattaListSteps.java | 3 ++- .../multiregattalist/MultiRegattaListStepsBody.java | 12 +++++------- .../home/mobile/partials/eventsteps/EventSteps.gss | 3 ++- .../home/mobile/partials/eventsteps/EventSteps.java | 3 ++- .../mobile/partials/eventsteps/EventStepsPhase.java | 10 ++++++---- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/multiregattalist/MultiRegattaListSteps.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/multiregattalist/MultiRegattaListSteps.java index aba27539ffb..30d3ba92244 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/multiregattalist/MultiRegattaListSteps.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/multiregattalist/MultiRegattaListSteps.java @@ -48,10 +48,11 @@ public class MultiRegattaListSteps extends Composite { double parts = Math.pow(seriesProgress.getMaxRacesPerFleet(), 0.4); sumParts += parts; } + final boolean showSeriesName = regattaProgress.getSeries().size() > 1; for(RegattaProgressSeriesDTO seriesProgress : regattaProgress.getSeries()) { double parts = Math.pow(seriesProgress.getMaxRacesPerFleet(), 0.4); double percentage = 100.0 * parts / sumParts; - MultiRegattaListStepsBody stepsBody = new MultiRegattaListStepsBody(seriesProgress); + MultiRegattaListStepsBody stepsBody = new MultiRegattaListStepsBody(seriesProgress, showSeriesName); allMultiregattaSteps.add(stepsBody); stepsBody.getElement().getStyle().setWidth(percentage, Unit.PCT); stepsContainerUi.appendChild(stepsBody.getElement()); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/multiregattalist/MultiRegattaListStepsBody.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/multiregattalist/MultiRegattaListStepsBody.java index a2dc107749d..a94a09658ef 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/multiregattalist/MultiRegattaListStepsBody.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/multiregattalist/MultiRegattaListStepsBody.java @@ -1,7 +1,5 @@ package com.sap.sailing.gwt.home.desktop.partials.multiregattalist; -import static com.sap.sailing.domain.common.LeaderboardNameConstants.DEFAULT_SERIES_NAME; - import java.util.Map; import java.util.Map.Entry; @@ -42,10 +40,10 @@ public class MultiRegattaListStepsBody extends UIObject implements RequiresResiz private final String seriesName, seriesNameMedium, seriesNameShort; private int seriesNameLength, seriesNameMediumLength; - public MultiRegattaListStepsBody(RegattaProgressSeriesDTO seriesProgress) { + MultiRegattaListStepsBody(RegattaProgressSeriesDTO seriesProgress, boolean showName) { setElement(uiBinder.createAndBindUi(this)); textContainerUi.getStyle().setVisibility(Visibility.HIDDEN); - longNameDummyUi.setInnerText(seriesName = caculateSeriesName(seriesProgress)); + longNameDummyUi.setInnerText(seriesName = caculateSeriesName(seriesProgress, showName)); mediumNameDummyUi.setInnerText(seriesNameMedium = caculateSeriesNameMedium()); seriesNameShort = caculateSeriesNameShort(); if (seriesProgress.isCompleted()) { @@ -93,9 +91,9 @@ public class MultiRegattaListStepsBody extends UIObject implements RequiresResiz } } - private String caculateSeriesName(RegattaProgressSeriesDTO seriesProgress) { - if (seriesProgress.getName() == null || seriesProgress.getName().isEmpty() - || DEFAULT_SERIES_NAME.equals(seriesProgress.getName())) { + private String caculateSeriesName(RegattaProgressSeriesDTO seriesProgress, boolean showName) { + if (!showName || seriesProgress.getName() == null || seriesProgress.getName().isEmpty()) { + nameUi.getStyle().setDisplay(Display.NONE); return I18N.races(); } else { return seriesProgress.getName(); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventSteps.gss b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventSteps.gss index 7471b4468c8..e3911716fb0 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventSteps.gss +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventSteps.gss @@ -38,6 +38,7 @@ /* padding: .666666666666667em 0; */ display: inline; vertical-align: middle; + margin-right: 0.333333333333333rem; } .eventsteps_phases_phase_progressbar { height: 1.266666666666667em; @@ -61,7 +62,7 @@ img.eventsteps_phases_phase_progress_icon { vertical-align: middle; height: 1.133333333333333em; width: 1.133333333333333em; - margin: 0 0.333333333333333em; + margin-right: 0.333333333333333em; } .eventsteps_phases_phase_progress_text { font-size: 0.866666666666667em; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventSteps.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventSteps.java index 0f62c0792f3..a13a5fd4120 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventSteps.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventSteps.java @@ -41,9 +41,10 @@ public class EventSteps extends Composite implements RefreshableWidget 1; for (RegattaProgressSeriesDTO seriesProgress : data.getProgress().getSeries()) { final PlaceNavigation navigation = racesNavigationFactory.apply(seriesProgress.getName()); - regattaProgessUi.addContent(new EventStepsPhase(seriesProgress, navigation)); + regattaProgessUi.addContent(new EventStepsPhase(seriesProgress, navigation, showSeriesName)); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsPhase.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsPhase.java index 141d2815cfb..9728319df95 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsPhase.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventsteps/EventStepsPhase.java @@ -1,7 +1,5 @@ package com.sap.sailing.gwt.home.mobile.partials.eventsteps; -import static com.sap.sailing.domain.common.LeaderboardNameConstants.DEFAULT_SERIES_NAME; - import java.util.Map; import java.util.Map.Entry; @@ -35,10 +33,14 @@ public class EventStepsPhase extends Composite { @UiField DivElement progressUi; @UiField DivElement fleetsContainerUi; - public EventStepsPhase(RegattaProgressSeriesDTO seriesProgress, PlaceNavigation placeNavigation) { + EventStepsPhase(RegattaProgressSeriesDTO seriesProgress, PlaceNavigation placeNavigation, boolean showName) { initWidget(uiBinder.createAndBindUi(this)); LinkUtil.configureForAction(anchorUi, () -> placeNavigation.goToPlace()); - nameUi.setInnerText(DEFAULT_SERIES_NAME.equals(seriesProgress.getName()) ? I18N.races() : seriesProgress.getName()); + if (showName) { + nameUi.setInnerText(seriesProgress.getName()); + } else { + nameUi.removeFromParent(); + } if (seriesProgress.isCompleted()) { progressUi.setInnerText(I18N.racesCount(seriesProgress.getTotalRaceCount())); } else { From 9c5983084887f0131c3c090636d5c5963e761fca Mon Sep 17 00:00:00 2001 From: Benjamin Barth Date: Wed, 25 Jul 2018 17:11:46 +0200 Subject: [PATCH 07/53] bug4483 Simplified util method which scrolls an element to the top --- .../RegattaCompetition.java | 2 +- .../places/event/races/RacesViewImpl.java | 5 ++- .../src/com/sap/sse/gwt/client/DOMUtils.java | 37 ++++++++++--------- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattacompetition/RegattaCompetition.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattacompetition/RegattaCompetition.java index 1cbe1137bf2..9c0c0e3be8e 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattacompetition/RegattaCompetition.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattacompetition/RegattaCompetition.java @@ -42,6 +42,6 @@ public class RegattaCompetition extends Composite implements RegattaCompetitionV } public void scrollToSeries(final String seriesName) { - DOMUtils.scrollToTop(seriesNameToUiComponent.get(seriesName).getElement()); + DOMUtils.scrollToTop(seriesNameToUiComponent.get(seriesName)); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/races/RacesViewImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/races/RacesViewImpl.java index 307f364b80b..89bc76e0473 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/races/RacesViewImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/races/RacesViewImpl.java @@ -5,6 +5,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.Consumer; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.Scheduler; @@ -78,8 +79,8 @@ public class RacesViewImpl extends AbstractEventView implem @Override public void setData(ListResult data) { super.setData(data); - Scheduler.get().scheduleDeferred( - () -> currentPresenter.getPreferredSeriesName().ifPresent(regattaCompetitionUi::scrollToSeries)); + final Consumer scrollCommand = regattaCompetitionUi::scrollToSeries; + Scheduler.get().scheduleDeferred(() -> currentPresenter.getPreferredSeriesName().ifPresent(scrollCommand)); } } diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/DOMUtils.java b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/DOMUtils.java index 639d68e0816..0e0f8ef8183 100644 --- a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/DOMUtils.java +++ b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/DOMUtils.java @@ -1,6 +1,8 @@ package com.sap.sse.gwt.client; +import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; +import com.google.gwt.user.client.ui.Widget; /** * Utility class contained convenience methods regarding DOM operations. @@ -11,27 +13,28 @@ public final class DOMUtils { } /** - * Scrolls the top of the provided {@link Element element} to the top of the viewport. + * Scrolls the top of the provided {@link Widget widget} to the topmost possible position in the viewport. * - * @param element - * {@link Element} to scroll to the top + * @param widget + * {@link Widget} to scroll to the topmost possible position */ - public static void scrollToTop(final Element element) { - int top = getOffsetTopOf(element); - Element current = element.getParentElement(); - while (current != null) { - if (top != current.getScrollTop()) { - current.setScrollTop(top); - } - top += getOffsetTopOf(current) - current.getScrollTop(); - current = current.getParentElement(); - } + public static void scrollToTop(final Widget widget) { + getViewportElement().setScrollTop(widget.getAbsoluteTop()); } - private static int getOffsetTopOf(final Element element) { - final int top = element.getOffsetTop(); - final boolean parentIsOffsetParent = element.getParentElement() == element.getOffsetParent(); - return parentIsOffsetParent ? top : top - element.getParentElement().getOffsetTop(); + /** + * Scrolls the top of the provided {@link Element element} to the topmost possible position in the viewport. + * + * @param element + * {@link Element} to scroll to the topmost possible position + */ + public static void scrollToTop(final Element element) { + getViewportElement().setScrollTop(element.getAbsoluteTop()); + } + + private static Element getViewportElement() { + final Document doc = Document.get(); + return doc.isCSS1Compat() ? doc.getDocumentElement() : doc.getBody(); } } \ No newline at end of file From f84be9535f4658265ecbedca2979ac4a68f1e0df Mon Sep 17 00:00:00 2001 From: Benjamin Barth Date: Wed, 25 Jul 2018 17:12:43 +0200 Subject: [PATCH 08/53] bug4483 Always reset viewport/scroll to top when navigation on mobile devices --- .../sap/sailing/gwt/home/mobile/app/MobileActivityMapper.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/app/MobileActivityMapper.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/app/MobileActivityMapper.java index 7a31ba34000..5bac0e34c98 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/app/MobileActivityMapper.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/app/MobileActivityMapper.java @@ -34,6 +34,7 @@ import com.sap.sailing.gwt.home.shared.places.user.confirmation.ConfirmationPlac import com.sap.sailing.gwt.home.shared.places.user.passwordreset.PasswordResetActivityProxy; import com.sap.sailing.gwt.home.shared.places.user.passwordreset.PasswordResetPlace; import com.sap.sailing.gwt.home.shared.places.user.profile.AbstractUserProfilePlace; +import com.sap.sse.gwt.client.DOMUtils; public class MobileActivityMapper implements ActivityMapper { private final MobileApplicationClientFactory clientFactory; @@ -52,6 +53,7 @@ public class MobileActivityMapper implements ActivityMapper { SwitchingEntryPoint.reloadApp(); return null; } + DOMUtils.scrollToTop(clientFactory.getRoot()); if (place instanceof ErrorPlace) { return new ErrorActivityProxy((ErrorPlace) place, clientFactory); } else if (place instanceof StartPlace) { From 2a7221c2c6b1688fe390aa712abd030e349cd6bb Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 27 Jul 2018 17:11:50 +0200 Subject: [PATCH 09/53] started to move update handler classes to com.sap.sailing.domain bundle Change-Id: I821f633ee1e5f1db970017788473b4edcce8cbd8 --- .../impl/DomainFactoryImpl.java | 9 ++- .../TracTracCourseDesignUpdateHandler.java | 62 +-------------- .../META-INF/MANIFEST.MF | 7 ++ .../domain/base/impl/DomainFactoryImpl.java | 2 +- .../impl/CourseDesignUpdateHandler.java | 78 +++++++++++++++++++ .../impl/FinishTimeUpdateHandler.java} | 13 ++-- .../tracking/impl/RaceAbortedHandler.java} | 10 +-- .../tracking/impl/StartTimeResetHandler.java} | 10 +-- .../impl/StartTimeUpdateHandler.java} | 8 +- .../domain/tracking}/impl/UpdateHandler.java | 49 +++++++----- .../domain/tracking/impl}/UpdateResponse.java | 3 +- .../impl/UpdateResponseDeserializer.java | 3 +- .../tracking}/impl/UpdateResponseImpl.java | 4 +- 13 files changed, 147 insertions(+), 111 deletions(-) create mode 100755 java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/CourseDesignUpdateHandler.java rename java/{com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracFinishTimeUpdateHandler.java => com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/FinishTimeUpdateHandler.java} (84%) rename java/{com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracRaceAbortedHandler.java => com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/RaceAbortedHandler.java} (78%) rename java/{com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracStartTimeResetHandler.java => com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/StartTimeResetHandler.java} (73%) rename java/{com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracStartTimeUpdateHandler.java => com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/StartTimeUpdateHandler.java} (93%) rename java/{com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter => com.sap.sailing.domain/src/com/sap/sailing/domain/tracking}/impl/UpdateHandler.java (83%) rename java/{com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter => com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl}/UpdateResponse.java (63%) rename java/{com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter => com.sap.sailing.domain/src/com/sap/sailing/domain/tracking}/impl/UpdateResponseDeserializer.java (86%) rename java/{com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter => com.sap.sailing.domain/src/com/sap/sailing/domain/tracking}/impl/UpdateResponseImpl.java (78%) diff --git a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/DomainFactoryImpl.java b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/DomainFactoryImpl.java index 1d6ccf2ae2b..ed867cb4ed8 100755 --- a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/DomainFactoryImpl.java +++ b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/DomainFactoryImpl.java @@ -73,6 +73,9 @@ import com.sap.sailing.domain.tracking.TrackedRegatta; 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.FinishTimeUpdateHandler; +import com.sap.sailing.domain.tracking.impl.RaceAbortedHandler; +import com.sap.sailing.domain.tracking.impl.StartTimeUpdateHandler; import com.sap.sailing.domain.tractracadapter.DomainFactory; import com.sap.sailing.domain.tractracadapter.JSONService; import com.sap.sailing.domain.tractracadapter.MetadataParser; @@ -678,15 +681,15 @@ public class DomainFactoryImpl implements DomainFactory { tracTracUpdateURI, tracTracUsername, tracTracPassword, tracTracEventUuid, raceDefinition.getId(), tractracRace, this); trackedRace.addCourseDesignChangedListener(courseDesignHandler); - TracTracStartTimeUpdateHandler startTimeHandler = new TracTracStartTimeUpdateHandler( + StartTimeUpdateHandler startTimeHandler = new StartTimeUpdateHandler( tracTracUpdateURI, tracTracUsername, tracTracPassword, tracTracEventUuid, raceDefinition.getId(), trackedRace.getTrackedRegatta().getRegatta()); trackedRace.addStartTimeChangedListener(startTimeHandler); - TracTracRaceAbortedHandler raceAbortedHandler = new TracTracRaceAbortedHandler( + RaceAbortedHandler raceAbortedHandler = new RaceAbortedHandler( tracTracUpdateURI, tracTracUsername, tracTracPassword, tracTracEventUuid, raceDefinition.getId()); trackedRace.addRaceAbortedListener(raceAbortedHandler); - trackedRace.addListener(new TracTracFinishTimeUpdateHandler(tracTracUpdateURI, tracTracUsername, tracTracPassword, tracTracEventUuid, + trackedRace.addListener(new FinishTimeUpdateHandler(tracTracUpdateURI, tracTracUsername, tracTracPassword, tracTracEventUuid, raceDefinition.getId(), trackedRace.getTrackedRegatta().getRegatta()).getListener()); } diff --git a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracCourseDesignUpdateHandler.java b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracCourseDesignUpdateHandler.java index c2167e8d888..18984574043 100644 --- a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracCourseDesignUpdateHandler.java +++ b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracCourseDesignUpdateHandler.java @@ -1,86 +1,32 @@ package com.sap.sailing.domain.tractracadapter.impl; -import java.io.IOException; import java.io.Serializable; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; import java.net.URI; -import java.net.URL; import java.util.Iterator; -import java.util.logging.Logger; - -import org.json.simple.JSONObject; -import org.json.simple.parser.ParseException; import com.sap.sailing.domain.base.ControlPoint; import com.sap.sailing.domain.base.CourseBase; import com.sap.sailing.domain.base.Mark; import com.sap.sailing.domain.base.Waypoint; import com.sap.sailing.domain.base.impl.CourseDataImpl; -import com.sap.sailing.domain.tracking.CourseDesignChangedListener; +import com.sap.sailing.domain.tracking.impl.CourseDesignUpdateHandler; import com.sap.sailing.domain.tractracadapter.DomainFactory; -import com.sap.sailing.server.gateway.serialization.JsonSerializer; -import com.sap.sailing.server.gateway.serialization.coursedata.impl.ControlPointJsonSerializer; -import com.sap.sailing.server.gateway.serialization.coursedata.impl.CourseBaseJsonSerializer; -import com.sap.sailing.server.gateway.serialization.coursedata.impl.CourseJsonSerializer; -import com.sap.sailing.server.gateway.serialization.coursedata.impl.GateJsonSerializer; -import com.sap.sailing.server.gateway.serialization.coursedata.impl.MarkJsonSerializer; -import com.sap.sailing.server.gateway.serialization.coursedata.impl.WaypointJsonSerializer; import com.sap.sse.common.Util; import com.tractrac.model.lib.api.event.IRace; import com.tractrac.model.lib.api.route.IControl; -public class TracTracCourseDesignUpdateHandler extends UpdateHandler implements CourseDesignChangedListener { - - private final static String ACTION = "update_course"; - - private final static Logger logger = Logger.getLogger(TracTracCourseDesignUpdateHandler.class.getName()); - private final JsonSerializer courseSerializer; +public class TracTracCourseDesignUpdateHandler extends CourseDesignUpdateHandler { private final IRace tractracRace; private final DomainFactory domainFactory; public TracTracCourseDesignUpdateHandler(URI updateURI, String tracTracUsername, String tracTracPassword, Serializable tracTracEventId, Serializable raceId, IRace tractracRace, DomainFactory domainFactory) { - super(updateURI, ACTION, tracTracUsername, tracTracPassword, tracTracEventId, raceId); + super(updateURI, tracTracUsername, tracTracPassword, tracTracEventId, raceId); this.domainFactory = domainFactory; this.tractracRace = tractracRace; - this.courseSerializer = new CourseJsonSerializer( - new CourseBaseJsonSerializer( - new WaypointJsonSerializer( - new ControlPointJsonSerializer( - new MarkJsonSerializer(), - new GateJsonSerializer(new MarkJsonSerializer()))))); } @Override - public void courseDesignChanged(final CourseBase newCourseDesign) throws MalformedURLException, IOException { - if (!isActive()) { - logger.info("Not sending course update to TracTrac because no URL has been provided."); - return; - } - final CourseBase newCourseDesignWithExistingControlPoints = replaceControlPointsByMatchingExistingControlPoints(newCourseDesign); - JSONObject serializedCourseDesign = courseSerializer.serialize(newCourseDesignWithExistingControlPoints); - String payload = serializedCourseDesign.toJSONString(); - URL currentCourseDesignURL = buildUpdateURL(); - logger.info("Using " + currentCourseDesignURL.toString() + " for the course update!"); - logger.info("Payload is " + payload); - HttpURLConnection connection = (HttpURLConnection) currentCourseDesignURL.openConnection(); - try { - setConnectionPropertiesAndSendWithPayload(connection, payload); - try { - checkAndLogUpdateResponse(connection); - } catch (ParseException e) { - e.printStackTrace(); - } - } finally { - if (connection != null) { - connection.disconnect(); - } else { - logger.severe("Connection to TracTrac Course Update URL " + currentCourseDesignURL.toString() + " could not be established"); - } - } - } - - private CourseBase replaceControlPointsByMatchingExistingControlPoints(CourseBase courseDesign) { + protected CourseBase replaceControlPointsByMatchingExistingControlPoints(CourseBase courseDesign) { final Iterable candidates = domainFactory.getControlsForCourseArea(tractracRace.getEvent(), tractracRace.getCourseArea()); final CourseBase result = new CourseDataImpl(courseDesign.getName()); int zeroBasedPosition = 0; diff --git a/java/com.sap.sailing.domain/META-INF/MANIFEST.MF b/java/com.sap.sailing.domain/META-INF/MANIFEST.MF index 6f6d9a68bbe..8d5cf1bb0a9 100755 --- a/java/com.sap.sailing.domain/META-INF/MANIFEST.MF +++ b/java/com.sap.sailing.domain/META-INF/MANIFEST.MF @@ -47,5 +47,12 @@ Require-Bundle: com.googlecode.java-diff-utils;bundle-version="1.3.0", com.sap.sse.shared.android, org.apache.commons.math, com.sap.sailing.declination, + com.sap.sailing.server.gateway.serialization.shared.android, com.sap.sse.datamining.annotations +Import-Package: org.apache.http, + org.apache.http.client;version="[4.2.5,4.3.0)", + org.apache.http.client.entity;version="[4.2.5,4.3.0)", + org.apache.http.client.methods;version="[4.2.5,4.3.0)", + org.apache.http.impl.client;version="[4.2.5,4.3.0)", + org.apache.http.message;version="[4.2.5,4.3.0)" Automatic-Module-Name: com.sap.sailing.domain diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java index 01e73aeacfe..1185b0861b4 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java @@ -205,7 +205,7 @@ public class DomainFactoryImpl extends SharedDomainFactoryImpl implements Domain raceDTO.status.status = trackedRace.getStatus() == null ? null : trackedRace.getStatus().getStatus(); raceDTO.status.loadingProgress = trackedRace.getStatus() == null ? 0.0 : trackedRace.getStatus().getLoadingProgress(); } - + @Override public TrackedRaceDTO createTrackedRaceDTO(TrackedRace trackedRace) { TrackedRaceDTO trackedRaceDTO = new TrackedRaceDTO(); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/CourseDesignUpdateHandler.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/CourseDesignUpdateHandler.java new file mode 100755 index 00000000000..1ad1a82c1c5 --- /dev/null +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/CourseDesignUpdateHandler.java @@ -0,0 +1,78 @@ +package com.sap.sailing.domain.tracking.impl; + +import java.io.IOException; +import java.io.Serializable; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.logging.Logger; + +import org.json.simple.JSONObject; +import org.json.simple.parser.ParseException; + +import com.sap.sailing.domain.base.CourseBase; +import com.sap.sailing.domain.tracking.CourseDesignChangedListener; +import com.sap.sailing.server.gateway.serialization.JsonSerializer; +import com.sap.sailing.server.gateway.serialization.coursedata.impl.ControlPointJsonSerializer; +import com.sap.sailing.server.gateway.serialization.coursedata.impl.CourseBaseJsonSerializer; +import com.sap.sailing.server.gateway.serialization.coursedata.impl.CourseJsonSerializer; +import com.sap.sailing.server.gateway.serialization.coursedata.impl.GateJsonSerializer; +import com.sap.sailing.server.gateway.serialization.coursedata.impl.MarkJsonSerializer; +import com.sap.sailing.server.gateway.serialization.coursedata.impl.WaypointJsonSerializer; + +public class CourseDesignUpdateHandler extends UpdateHandler implements CourseDesignChangedListener { + + private final static String ACTION = "update_course"; + + private final static Logger logger = Logger.getLogger(CourseDesignUpdateHandler.class.getName()); + private final JsonSerializer courseSerializer; + + public CourseDesignUpdateHandler(URI updateURI, String username, String password, Serializable eventId, Serializable raceId) { + super(updateURI, ACTION, username, password, eventId, raceId); + this.courseSerializer = new CourseJsonSerializer( + new CourseBaseJsonSerializer( + new WaypointJsonSerializer( + new ControlPointJsonSerializer( + new MarkJsonSerializer(), + new GateJsonSerializer(new MarkJsonSerializer()))))); + } + + @Override + public void courseDesignChanged(final CourseBase newCourseDesign) throws MalformedURLException, IOException { + if (!isActive()) { + logger.info("Not sending course update to TracTrac because no URL has been provided."); + return; + } + final CourseBase newCourseDesignWithExistingControlPoints = replaceControlPointsByMatchingExistingControlPoints(newCourseDesign); + JSONObject serializedCourseDesign = courseSerializer.serialize(newCourseDesignWithExistingControlPoints); + String payload = serializedCourseDesign.toJSONString(); + URL currentCourseDesignURL = buildUpdateURL(); + logger.info("Using " + currentCourseDesignURL.toString() + " for the course update!"); + logger.info("Payload is " + payload); + HttpURLConnection connection = (HttpURLConnection) currentCourseDesignURL.openConnection(); + try { + setConnectionPropertiesAndSendWithPayload(connection, payload); + try { + checkAndLogUpdateResponse(connection); + } catch (ParseException e) { + e.printStackTrace(); + } + } finally { + if (connection != null) { + connection.disconnect(); + } else { + logger.severe("Connection to TracTrac Course Update URL " + currentCourseDesignURL.toString() + " could not be established"); + } + } + } + + /** + * This default implementation returns the {@code courseDesign} unchanged. Subclasses have the possibility to + * override this method in order to replace individual course marks provided in a detailed course design, + * based on the actual course marks available. + */ + protected CourseBase replaceControlPointsByMatchingExistingControlPoints(CourseBase courseDesign) { + return courseDesign; + } +} diff --git a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracFinishTimeUpdateHandler.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/FinishTimeUpdateHandler.java similarity index 84% rename from java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracFinishTimeUpdateHandler.java rename to java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/FinishTimeUpdateHandler.java index dfae3907cfa..e5c027ec562 100644 --- a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracFinishTimeUpdateHandler.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/FinishTimeUpdateHandler.java @@ -1,4 +1,4 @@ -package com.sap.sailing.domain.tractracadapter.impl; +package com.sap.sailing.domain.tracking.impl; import java.io.BufferedReader; import java.io.IOException; @@ -20,12 +20,11 @@ import org.json.simple.parser.ParseException; import com.sap.sailing.domain.base.Regatta; import com.sap.sailing.domain.tracking.TrackedRace; -import com.sap.sailing.domain.tracking.impl.AbstractRaceChangeListener; import com.sap.sse.common.TimePoint; import com.sap.sse.util.LaxRedirectStrategyForAllRedirectResponseCodes; -public class TracTracFinishTimeUpdateHandler extends UpdateHandler { - private final static Logger logger = Logger.getLogger(TracTracFinishTimeUpdateHandler.class.getName()); +public class FinishTimeUpdateHandler extends UpdateHandler { + private final static Logger logger = Logger.getLogger(FinishTimeUpdateHandler.class.getName()); private final static String ACTION_STOP_TRACKING = "end_tracking"; private final static String FIELD_TRACKING_END_TIME = "tracking_end_time"; @@ -36,9 +35,9 @@ public class TracTracFinishTimeUpdateHandler extends UpdateHandler { */ private final Regatta regatta; - public TracTracFinishTimeUpdateHandler(URI updateURI, String tracTracUsername, String tracTracPassword, - Serializable tracTracEventId, Serializable raceId, Regatta regatta) { - super(updateURI, ACTION_STOP_TRACKING, tracTracUsername, tracTracPassword, tracTracEventId, raceId); + public FinishTimeUpdateHandler(URI updateURI, String username, String password, + Serializable eventId, Serializable raceId, Regatta regatta) { + super(updateURI, ACTION_STOP_TRACKING, username, password, eventId, raceId); this.regatta = regatta; } diff --git a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracRaceAbortedHandler.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/RaceAbortedHandler.java similarity index 78% rename from java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracRaceAbortedHandler.java rename to java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/RaceAbortedHandler.java index 1963e3f4dc5..50b723a4405 100755 --- a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracRaceAbortedHandler.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/RaceAbortedHandler.java @@ -1,4 +1,4 @@ -package com.sap.sailing.domain.tractracadapter.impl; +package com.sap.sailing.domain.tracking.impl; import java.io.IOException; import java.io.Serializable; @@ -15,14 +15,14 @@ import org.json.simple.parser.ParseException; import com.sap.sailing.domain.common.racelog.Flags; import com.sap.sailing.domain.tracking.RaceAbortedListener; -public class TracTracRaceAbortedHandler extends UpdateHandler implements RaceAbortedListener { +public class RaceAbortedHandler extends UpdateHandler implements RaceAbortedListener { private final static String ACTION = "update_race_status"; - private final static Logger logger = Logger.getLogger(TracTracRaceAbortedHandler.class.getName()); + private final static Logger logger = Logger.getLogger(RaceAbortedHandler.class.getName()); - public TracTracRaceAbortedHandler(URI updateURI, String tracTracUsername, String tracTracPassword, Serializable tracTracEventId, Serializable raceId) { - super(updateURI, ACTION, tracTracUsername, tracTracPassword, tracTracEventId, raceId); + public RaceAbortedHandler(URI updateURI, String username, String password, Serializable eventId, Serializable raceId) { + super(updateURI, ACTION, username, password, eventId, raceId); } @Override diff --git a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracStartTimeResetHandler.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/StartTimeResetHandler.java similarity index 73% rename from java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracStartTimeResetHandler.java rename to java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/StartTimeResetHandler.java index dc46e1b23a9..941d74e20ee 100644 --- a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracStartTimeResetHandler.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/StartTimeResetHandler.java @@ -1,4 +1,4 @@ -package com.sap.sailing.domain.tractracadapter.impl; +package com.sap.sailing.domain.tracking.impl; import java.io.IOException; import java.io.Serializable; @@ -13,14 +13,14 @@ import org.json.simple.parser.ParseException; import com.sap.sailing.domain.tracking.StartTimeChangedListener; import com.sap.sse.common.TimePoint; -public class TracTracStartTimeResetHandler extends UpdateHandler implements StartTimeChangedListener { +public class StartTimeResetHandler extends UpdateHandler implements StartTimeChangedListener { private static final String ACTION = "resetStartTime"; - private final static Logger logger = Logger.getLogger(TracTracStartTimeResetHandler.class.getName()); + private final static Logger logger = Logger.getLogger(StartTimeResetHandler.class.getName()); - public TracTracStartTimeResetHandler(URI updateURI, String tracTracUsername, String tracTracPassword, Serializable tracTracEventId, Serializable raceId) { - super(updateURI, ACTION, tracTracUsername, tracTracPassword, tracTracEventId, raceId); + public StartTimeResetHandler(URI updateURI, String username, String password, Serializable eventId, Serializable raceId) { + super(updateURI, ACTION, username, password, eventId, raceId); } @Override diff --git a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracStartTimeUpdateHandler.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/StartTimeUpdateHandler.java similarity index 93% rename from java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracStartTimeUpdateHandler.java rename to java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/StartTimeUpdateHandler.java index eaef290e628..8dab411be13 100644 --- a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracStartTimeUpdateHandler.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/StartTimeUpdateHandler.java @@ -1,4 +1,4 @@ -package com.sap.sailing.domain.tractracadapter.impl; +package com.sap.sailing.domain.tracking.impl; import java.io.BufferedReader; import java.io.IOException; @@ -28,8 +28,8 @@ import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sse.common.TimePoint; import com.sap.sse.util.LaxRedirectStrategyForAllRedirectResponseCodes; -public class TracTracStartTimeUpdateHandler extends UpdateHandler implements StartTimeChangedListener { - private final static Logger logger = Logger.getLogger(TracTracStartTimeUpdateHandler.class.getName()); +public class StartTimeUpdateHandler extends UpdateHandler implements StartTimeChangedListener { + private final static Logger logger = Logger.getLogger(StartTimeUpdateHandler.class.getName()); private final static String ACTION = "update_race_start_time"; private final static String ACTION_START_TRACKING = "start_tracking"; @@ -42,7 +42,7 @@ public class TracTracStartTimeUpdateHandler extends UpdateHandler implements Sta */ private final Regatta regatta; - public TracTracStartTimeUpdateHandler(URI updateURI, String tracTracUsername, String tracTracPassword, + public StartTimeUpdateHandler(URI updateURI, String tracTracUsername, String tracTracPassword, Serializable tracTracEventId, Serializable raceId, Regatta regatta) { super(updateURI, ACTION, tracTracUsername, tracTracPassword, tracTracEventId, raceId); this.regatta = regatta; diff --git a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/UpdateHandler.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/UpdateHandler.java similarity index 83% rename from java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/UpdateHandler.java rename to java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/UpdateHandler.java index f87d3c8a814..97cd7a4a61d 100644 --- a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/UpdateHandler.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/UpdateHandler.java @@ -1,4 +1,4 @@ -package com.sap.sailing.domain.tractracadapter.impl; +package com.sap.sailing.domain.tracking.impl; import java.io.BufferedReader; import java.io.DataOutputStream; @@ -25,21 +25,28 @@ import org.json.simple.JSONObject; import org.json.simple.JSONValue; import org.json.simple.parser.ParseException; -import com.sap.sailing.domain.tractracadapter.UpdateResponse; +import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException; import com.sap.sailing.server.gateway.deserialization.JsonDeserializer; import com.sap.sailing.server.gateway.deserialization.impl.Helpers; import com.sap.sse.common.Duration; +/** + * An update handler can be registered as a listener on a {@link TrackedRace} and can then propagate information to + * an external service. This can, e.g., be a tracking partner's system that is interested in receiving race status + * updates such as new start times or postponements. + * + * @author Axel Uhl (d043530) + * + */ public class UpdateHandler { - private final static Logger logger = Logger.getLogger(UpdateHandler.class.getName()); private JsonDeserializer updateDeserializer; private final URI baseURI; - private final String tracTracUsername; - private final String tracTracPassword; - private final Serializable tracTracEventId; + private final String username; + private final String password; + private final Serializable eventId; private final Serializable raceId; private final String action; private final boolean active; @@ -53,16 +60,16 @@ public class UpdateHandler { private final static String ResponseCodeForFailure = "FAILURE"; private final static String UpdateUrlTemplate = "%s%s?eventid=%s&raceid=%s&username=%s&password=%s"; - public UpdateHandler(URI updateURI, String action, String tracTracUsername, String tracTracPassword, Serializable tracTracEventId, Serializable raceId) { + public UpdateHandler(URI updateURI, String action, String username, String password, Serializable eventId, Serializable raceId) { this.baseURI = updateURI; this.action = action; - this.tracTracUsername = tracTracUsername; - this.tracTracPassword = tracTracPassword; - this.tracTracEventId = tracTracEventId; + this.username = username; + this.password = password; + this.eventId = eventId; this.raceId = raceId; this.updateDeserializer = new UpdateResponseDeserializer(); if (updateURI != null && !updateURI.toString().equals("")) { - logger.info("Activating TracTrac update handler "+this+" for race with ID "+raceId); + logger.info("Activating update handler "+this+" for race with ID "+raceId); this.active = true; } else { this.active = false; @@ -87,10 +94,10 @@ public class UpdateHandler { */ protected List getDefaultParametersAsNewList() { final List result = new ArrayList<>(); - result.add(new BasicNameValuePair("eventid", tracTracEventId.toString())); + result.add(new BasicNameValuePair("eventid", eventId.toString())); result.add(new BasicNameValuePair("raceid", this.raceId.toString())); - result.add(new BasicNameValuePair("username", tracTracUsername)); - result.add(new BasicNameValuePair("password", tracTracPassword)); + result.add(new BasicNameValuePair("username", username)); + result.add(new BasicNameValuePair("password", password)); return result; } @@ -103,10 +110,10 @@ public class UpdateHandler { String url = String.format(UpdateUrlTemplate, serverUpdateURI.toString(), this.action, - URLEncoder.encode(this.tracTracEventId.toString(), EncodingUtf8), + URLEncoder.encode(this.eventId.toString(), EncodingUtf8), URLEncoder.encode(this.raceId.toString(), EncodingUtf8), - URLEncoder.encode(tracTracUsername, EncodingUtf8), - URLEncoder.encode(tracTracPassword, EncodingUtf8)); + URLEncoder.encode(username, EncodingUtf8), + URLEncoder.encode(password, EncodingUtf8)); for (Entry entry : additionalParameters.entrySet()) { url += String.format("&%s=%s", @@ -123,7 +130,7 @@ public class UpdateHandler { protected void checkAndLogUpdateResponse(HttpURLConnection connection) throws IOException, ParseException { connection.setConnectTimeout(10000/*milliseconds*/); connection.connect(); - BufferedReader reader = getResponseOnUpdateFromTracTrac(connection); + BufferedReader reader = getResponseOnUpdateFromProvider(connection); parseAndLogResponse(reader); } @@ -133,13 +140,13 @@ public class UpdateHandler { JSONObject responseObject = Helpers.toJSONObjectSafe(responseBody); UpdateResponse updateResponse = updateDeserializer.deserialize(responseObject); if (updateResponse.getStatus().equals(ResponseCodeForFailure)) { - logger.severe("Failed to send data to TracTrac, got following response: " + updateResponse.getMessage()); + logger.severe("Failed to send data to provider, got following response: " + updateResponse.getMessage()); } else { - logger.info("Successfully sent data to TracTrac with response: " + updateResponse.getMessage()); + logger.info("Successfully sent data to provider with response: " + updateResponse.getMessage()); } } - private BufferedReader getResponseOnUpdateFromTracTrac(HttpURLConnection connection) throws IOException { + private BufferedReader getResponseOnUpdateFromProvider(HttpURLConnection connection) throws IOException { InputStream inputStream = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); return reader; diff --git a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/UpdateResponse.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/UpdateResponse.java similarity index 63% rename from java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/UpdateResponse.java rename to java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/UpdateResponse.java index 2a3a9193096..49ea7846f60 100644 --- a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/UpdateResponse.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/UpdateResponse.java @@ -1,7 +1,6 @@ -package com.sap.sailing.domain.tractracadapter; +package com.sap.sailing.domain.tracking.impl; public interface UpdateResponse { - String getStatus(); String getMessage(); diff --git a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/UpdateResponseDeserializer.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/UpdateResponseDeserializer.java similarity index 86% rename from java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/UpdateResponseDeserializer.java rename to java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/UpdateResponseDeserializer.java index 496f22b4f09..75bd2dabe92 100644 --- a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/UpdateResponseDeserializer.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/UpdateResponseDeserializer.java @@ -1,8 +1,7 @@ -package com.sap.sailing.domain.tractracadapter.impl; +package com.sap.sailing.domain.tracking.impl; import org.json.simple.JSONObject; -import com.sap.sailing.domain.tractracadapter.UpdateResponse; import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException; import com.sap.sailing.server.gateway.deserialization.JsonDeserializer; diff --git a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/UpdateResponseImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/UpdateResponseImpl.java similarity index 78% rename from java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/UpdateResponseImpl.java rename to java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/UpdateResponseImpl.java index 9c1eef86ce1..109414350ec 100644 --- a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/UpdateResponseImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/UpdateResponseImpl.java @@ -1,6 +1,4 @@ -package com.sap.sailing.domain.tractracadapter.impl; - -import com.sap.sailing.domain.tractracadapter.UpdateResponse; +package com.sap.sailing.domain.tracking.impl; public class UpdateResponseImpl implements UpdateResponse { From eda96aa5daa703632b56d60d100bcd10a08aa972 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 2 Aug 2018 14:36:52 +0200 Subject: [PATCH 10/53] added updateURL, updateUsername and updatePassword fields to SwissTimingEventManagementPanel Change-Id: I86ed5a341baace0cd028e385bcfb5f44e56c2e03 --- .../persistence/impl/FieldNames.java | 3 +- .../SwissTimingAdapterPersistenceImpl.java | 13 +++-- .../SwissTimingConfiguration.java | 6 +++ .../SwissTimingFactory.java | 2 +- .../impl/SwissTimingConfigurationImpl.java | 19 ++++++- .../impl/SwissTimingFactoryImpl.java | 4 +- .../SwissTimingEventManagementPanel.java | 52 ++++++++++++------- .../TracTracEventManagementPanel.java | 7 ++- .../sailing/gwt/ui/client/SailingService.java | 2 +- .../gwt/ui/client/SailingServiceAsync.java | 2 +- .../sailing/gwt/ui/client/StringMessages.java | 3 ++ .../gwt/ui/client/StringMessages.properties | 5 +- .../ui/client/StringMessages_de.properties | 5 +- .../gwt/ui/server/SailingServiceImpl.java | 8 +-- .../shared/SwissTimingConfigurationDTO.java | 34 +++++++++++- .../GWT Security SDM.launch | 5 +- 16 files changed, 126 insertions(+), 44 deletions(-) diff --git a/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/FieldNames.java b/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/FieldNames.java index d90bffeb0ca..26a4a5053ff 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/FieldNames.java +++ b/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/FieldNames.java @@ -2,7 +2,8 @@ package com.sap.sailing.domain.swisstimingadapter.persistence.impl; public enum FieldNames { // SwissTiming configuration parameters: - ST_CONFIG_NAME, ST_CONFIG_HOSTNAME, ST_CONFIG_PORT, ST_CONFIG_JSON_URL, ST_ARCHIVE_JSON_URL, + ST_CONFIG_NAME, ST_CONFIG_HOSTNAME, ST_CONFIG_PORT, ST_CONFIG_JSON_URL, ST_CONFIG_UPDATE_URL, + ST_CONFIG_UPDATE_USERNAME, ST_CONFIG_UPDATE_PASSWORD, ST_ARCHIVE_JSON_URL, // last message count field: LAST_MESSAGE_COUNT, diff --git a/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/SwissTimingAdapterPersistenceImpl.java b/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/SwissTimingAdapterPersistenceImpl.java index 7d6b0d260f8..71d8b5d3a54 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/SwissTimingAdapterPersistenceImpl.java +++ b/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/SwissTimingAdapterPersistenceImpl.java @@ -37,8 +37,8 @@ public class SwissTimingAdapterPersistenceImpl implements SwissTimingAdapterPers DBCollection stConfigs = database.getCollection(CollectionNames.SWISSTIMING_CONFIGURATIONS.name()); for (DBObject o : stConfigs.find()) { SwissTimingConfiguration stConfig = loadSwissTimingConfiguration(o); - // the old swisstiming config was not based on a json URL -> ignore such configs - if(stConfig.getJsonURL() != null) { + // the old SwissTiming configuration was not based on a JSON URL -> ignore such configurations + if (stConfig.getJsonURL() != null) { result.add(stConfig); } } @@ -57,8 +57,10 @@ public class SwissTimingAdapterPersistenceImpl implements SwissTimingAdapterPers String jsonURL = (String) object.get(FieldNames.ST_CONFIG_JSON_URL.name()); String hostname = (String) object.get(FieldNames.ST_CONFIG_HOSTNAME.name()); Integer port = (Integer) object.get(FieldNames.ST_CONFIG_PORT.name()); - - return swissTimingFactory.createSwissTimingConfiguration(name, jsonURL, hostname, port); + String updateURL = (String) object.get(FieldNames.ST_CONFIG_UPDATE_URL.name()); + String updateUsername = (String) object.get(FieldNames.ST_CONFIG_UPDATE_USERNAME.name()); + String updatePassword = (String) object.get(FieldNames.ST_CONFIG_UPDATE_PASSWORD.name()); + return swissTimingFactory.createSwissTimingConfiguration(name, jsonURL, hostname, port, updateURL, updateUsername, updatePassword); } @Override @@ -96,6 +98,9 @@ public class SwissTimingAdapterPersistenceImpl implements SwissTimingAdapterPers result.put(FieldNames.ST_CONFIG_JSON_URL.name(), swissTimingConfiguration.getJsonURL()); result.put(FieldNames.ST_CONFIG_HOSTNAME.name(), swissTimingConfiguration.getHostname()); result.put(FieldNames.ST_CONFIG_PORT.name(), swissTimingConfiguration.getPort()); + result.put(FieldNames.ST_CONFIG_UPDATE_URL.name(), swissTimingConfiguration.getUpdateURL()); + result.put(FieldNames.ST_CONFIG_UPDATE_USERNAME.name(), swissTimingConfiguration.getUpdateUsername()); + result.put(FieldNames.ST_CONFIG_UPDATE_PASSWORD.name(), swissTimingConfiguration.getUpdatePassword()); stConfigCollection.insert(result); } diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingConfiguration.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingConfiguration.java index 293eff3c8be..09c500c6581 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingConfiguration.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingConfiguration.java @@ -14,4 +14,10 @@ public interface SwissTimingConfiguration { String getHostname(); Integer getPort(); + + String getUpdateURL(); + + String getUpdateUsername(); + + String getUpdatePassword(); } diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingFactory.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingFactory.java index 8badef20f87..407239168ff 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingFactory.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingFactory.java @@ -49,7 +49,7 @@ public interface SwissTimingFactory { SailMasterTransceiver createSailMasterTransceiver(); - SwissTimingConfiguration createSwissTimingConfiguration(String name, String jsonURL, String hostname, Integer port); + SwissTimingConfiguration createSwissTimingConfiguration(String name, String jsonURL, String hostname, Integer port, String updateURL, String updateUsername, String updatePassword); SwissTimingRaceTracker createRaceTracker(String raceID, String raceName, String raceDescription, BoatClass boatClass, String hostname, int port, StartList startList, long delayToLiveInMillis, diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingConfigurationImpl.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingConfigurationImpl.java index c16ca7a5b71..8c1087e2d11 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingConfigurationImpl.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingConfigurationImpl.java @@ -7,13 +7,19 @@ public class SwissTimingConfigurationImpl implements SwissTimingConfiguration { private final String jsonURL; private final String hostname; private final Integer port; + private final String updateURL; + private final String updateUsername; + private final String updatePassword; - public SwissTimingConfigurationImpl(String name, String jsonURL, String hostname, Integer port) { + public SwissTimingConfigurationImpl(String name, String jsonURL, String hostname, Integer port, String updateURL, String updateUsername, String updatePassword) { super(); this.name = name; this.jsonURL = jsonURL; this.hostname = hostname; this.port = port; + this.updateURL = updateURL; + this.updateUsername = updateUsername; + this.updatePassword = updatePassword; } @Override @@ -36,4 +42,15 @@ public class SwissTimingConfigurationImpl implements SwissTimingConfiguration { return port; } + public String getUpdateURL() { + return updateURL; + } + + public String getUpdateUsername() { + return updateUsername; + } + + public String getUpdatePassword() { + return updatePassword; + } } diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingFactoryImpl.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingFactoryImpl.java index 9d7b4b82cb1..3ef6ea77427 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingFactoryImpl.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingFactoryImpl.java @@ -83,8 +83,8 @@ public class SwissTimingFactoryImpl implements SwissTimingFactory { } @Override - public SwissTimingConfiguration createSwissTimingConfiguration(String name, String jsonURL, String hostname, Integer port) { - return new SwissTimingConfigurationImpl(name, jsonURL, hostname, port); + public SwissTimingConfiguration createSwissTimingConfiguration(String name, String jsonURL, String hostname, Integer port, String updateURL, String updateUsername, String updatePassword) { + return new SwissTimingConfigurationImpl(name, jsonURL, hostname, port, updateURL, updateUsername, updatePassword); } @Override diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SwissTimingEventManagementPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SwissTimingEventManagementPanel.java index 54a122e1cce..b0a2ed089f1 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SwissTimingEventManagementPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SwissTimingEventManagementPanel.java @@ -25,6 +25,7 @@ import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.IntegerBox; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.ListBox; +import com.google.gwt.user.client.ui.PasswordTextBox; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.view.client.ListDataProvider; @@ -62,6 +63,9 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane private final ListBox previousConfigurationsComboBox; private final TextBox eventIdBox; private final TextBox jsonUrlBox; + private final TextBox updateURLBox; + private final TextBox updateUsernameBox; + private final PasswordTextBox updatePasswordBox; private final TextBox hostnameTextbox; private final IntegerBox portIntegerbox; private final List availableSwissTimingRaces = new ArrayList(); @@ -75,22 +79,16 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane RegattaRefresher regattaRefresher, StringMessages stringConstants) { super(sailingService, regattaRefresher, errorReporter, true, stringConstants); this.errorReporter = errorReporter; - VerticalPanel mainPanel = new VerticalPanel(); this.setWidget(mainPanel); mainPanel.setWidth("100%"); - CaptionPanel captionPanelConnections = new CaptionPanel(stringConstants.connections()); mainPanel.add(captionPanelConnections); - VerticalPanel verticalPanel = new VerticalPanel(); - captionPanelConnections.setContentWidget(verticalPanel); captionPanelConnections.setStyleName("bold"); - - Grid connectionsGrid = new Grid(6, 2); + Grid connectionsGrid = new Grid(9, 2); verticalPanel.add(connectionsGrid); - previousConfigurations = new HashMap(); previousConfigurationsComboBox = new ListBox(); connectionsGrid.setWidget(0, 1, previousConfigurationsComboBox); @@ -107,10 +105,6 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane } }); fillConfigurations(); - - jsonUrlBox = new TextBox(); - jsonUrlBox.getElement().getStyle().setWidth(50, Unit.EM); - connectionsGrid.setWidget(0, 0, new Label(stringMessages.swissTimingEvents() + ":")); connectionsGrid.setWidget(0, 1, previousConfigurationsComboBox); @@ -125,6 +119,8 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane } }); + jsonUrlBox = new TextBox(); + jsonUrlBox.getElement().getStyle().setWidth(50, Unit.EM); connectionsGrid.setWidget(2, 0, new Label(stringMessages.manage2SailEventURLBox() + ":")); connectionsGrid.setWidget(2, 1, jsonUrlBox); jsonUrlBox.addChangeHandler(event -> { @@ -142,8 +138,23 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane connectionsGrid.setWidget(4, 0, new Label(stringMessages.manage2SailPort() + ":")); connectionsGrid.setWidget(4, 1, portIntegerbox); + updateURLBox = new TextBox(); + updateURLBox.getElement().getStyle().setWidth(50, Unit.EM); + connectionsGrid.setWidget(5, 0, new Label(stringMessages.swissTimingUpdateURL() + ":")); + connectionsGrid.setWidget(5, 1, updateURLBox); + + updateUsernameBox = new TextBox(); + updateUsernameBox.getElement().getStyle().setWidth(50, Unit.EM); + connectionsGrid.setWidget(6, 0, new Label(stringMessages.swissTimingUpdateUsername() + ":")); + connectionsGrid.setWidget(6, 1, updateUsernameBox); + + updatePasswordBox = new PasswordTextBox(); + updatePasswordBox.getElement().getStyle().setWidth(50, Unit.EM); + connectionsGrid.setWidget(7, 0, new Label(stringMessages.swissTimingUpdatePassword() + ":")); + connectionsGrid.setWidget(7, 1, updatePasswordBox); + Button btnListRaces = new Button(stringConstants.listRaces()); - connectionsGrid.setWidget(5, 1, btnListRaces); + connectionsGrid.setWidget(8, 1, btnListRaces); btnListRaces.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { @@ -459,6 +470,9 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane private void fillRaces(final SailingServiceAsync sailingService) { final String jsonUrl = jsonUrlBox.getValue(); + final String updateURL = updateURLBox.getValue(); + final String updateUsername = updateUsernameBox.getValue(); + final String updatePassword = updatePasswordBox.getValue(); sailingService.getRacesOfSwissTimingEvent(jsonUrl, new AsyncCallback() { @Override public void onFailure(Throwable caught) { @@ -469,21 +483,18 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane @Override public void onSuccess(final SwissTimingEventRecordDTO result) { availableSwissTimingRaces.clear(); - if (result != null) + if (result != null) { availableSwissTimingRaces.addAll(result.races); - + } raceList.getList().clear(); raceList.getList().addAll(availableSwissTimingRaces); - filterablePanelEvents.getTextBox().setText(null); filterablePanelEvents.updateAll(result.races); - // store a successful configuration in the database for later retrieval final String hostname = result.trackingDataHost; final Integer port = result.trackingDataPort; final String configName = result.eventName; - - sailingService.storeSwissTimingConfiguration(configName, jsonUrl, hostname, port, + sailingService.storeSwissTimingConfiguration(configName, jsonUrl, hostname, port, updateURL, updateUsername, updatePassword, new AsyncCallback() { @Override public void onFailure(Throwable caught) { @@ -495,7 +506,7 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane public void onSuccess(Void voidResult) { // refresh list of previous configurations SwissTimingConfigurationDTO stConfig = new SwissTimingConfigurationDTO(configName, jsonUrl, - hostname, port); + hostname, port, updateURL, updateUsername, updatePassword); if (previousConfigurations.put(stConfig.getName(), stConfig) == null) { previousConfigurationsComboBox.addItem(stConfig.getName()); } @@ -549,6 +560,9 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane hostnameTextbox.setValue(stConfig.getHostname()); portIntegerbox.setValue(stConfig.getPort()); jsonUrlBox.setValue(stConfig.getJsonURL()); + updateURLBox.setValue(stConfig.getUpdateURL()); + updateUsernameBox.setValue(stConfig.getUpdateUsername()); + updatePasswordBox.setValue(stConfig.getUpdatePassword()); } } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TracTracEventManagementPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TracTracEventManagementPanel.java index 5b7069b09a8..9864e5ac78b 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TracTracEventManagementPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TracTracEventManagementPanel.java @@ -28,6 +28,7 @@ import com.google.gwt.user.client.ui.HTMLTable.ColumnFormatter; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.ListBox; +import com.google.gwt.user.client.ui.PasswordTextBox; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; @@ -79,7 +80,7 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel { private TextBox jsonURLTextBox; private TextBox tracTracUpdateURITextBox; private TextBox tractracUsernameTextBox; - private TextBox tractracPasswordTextBox; + private PasswordTextBox tractracPasswordTextBox; private Label loadingMessageLabel; private LabeledAbstractFilterablePanel racesFilterablePanel; @@ -199,7 +200,7 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel { grid.setWidget(6, 1, tractracUsernameTextBox); // TracTrac Password - tractracPasswordTextBox = new TextBox(); + tractracPasswordTextBox = new PasswordTextBox(); tractracPasswordTextBox.ensureDebugId("TracTracPasswordTextBox"); tractracPasswordTextBox.setVisibleLength(40); @@ -222,10 +223,8 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel { } }); grid.setWidget(9, 1, listRacesButton); - loadingMessageLabel = new Label(); grid.setWidget(9, 2, loadingMessageLabel); - return connectionsPanel; } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java index b45952f0b1e..85f26f24ce0 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java @@ -285,7 +285,7 @@ public interface SailingService extends RemoteService, FileStorageManagementGwtS SwissTimingEventRecordDTO getRacesOfSwissTimingEvent(String eventJsonURL) throws Exception; - void storeSwissTimingConfiguration(String configName, String jsonURL, String hostname, Integer port); + void storeSwissTimingConfiguration(String configName, String jsonURL, String hostname, Integer port, String updateURL, String updateUsername, String updatePassword); String[] getCountryCodes(); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java index 2c5324fc800..db0ff1adb60 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java @@ -333,7 +333,7 @@ public interface SailingServiceAsync extends ServerInfoRetriever, FileStorageMan void getRacesOfSwissTimingEvent(String eventJsonUrl, AsyncCallback asyncCallback); void storeSwissTimingConfiguration(String configName, String jsonURL, String hostname, Integer port, - AsyncCallback asyncCallback); + String updateURL, String updateUsername, String updatePassword, AsyncCallback asyncCallback); void getCountryCodes(AsyncCallback callback); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java index cc7951e05cc..685abe1504a 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java @@ -2093,4 +2093,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, String manage2SailEventIdBoxTooltip(); String manage2SailPort(); String windFinderSpotCollectionsList(); + String swissTimingUpdateURL(); + String swissTimingUpdateUsername(); + String swissTimingUpdatePassword(); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties index 8dd85fc710c..19651a58c72 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties @@ -2086,4 +2086,7 @@ gender=Gender manage2SailEventIdBox=Manage2Sail Event ID manage2SailEventURLBox=Manage2Sail EventURL (json) manage2SailEventIdBoxTooltip=Event ID or a URL that contains the event ID from Manage2Sail -manage2SailPort=Port \ No newline at end of file +manage2SailPort=Port +swissTimingUpdateURL=Update URL (e.g., for start time and course change feedback) +swissTimingUpdateUsername=Username for sending updates +swissTimingUpdatePassword=Password for sending updates diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties index 48ef82f8c55..50f122fc377 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties @@ -2081,4 +2081,7 @@ gender=Geschlecht manage2SailEventId=Manage2Sail Event ID manage2SailEventURL=Manage2Sail Event URL (json) manage2SailEventIdBoxTooltip=Event ID von Manage 2 Sail oder URL die die Event ID beinhaltet -manage2SailPort=Port \ No newline at end of file +manage2SailPort=Port +swissTimingUpdateURL=Update URL (z.B. für Startzeit-Übertragung) +swissTimingUpdateUsername=Benutzername zum Versenden der Updates +swissTimingUpdatePassword=Passwort zum Versenden der Updates \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index 09393c99366..e7d1a59a8f7 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -2829,7 +2829,9 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S Iterable configs = swissTimingAdapterPersistence.getSwissTimingConfigurations(); List result = new ArrayList(); for (SwissTimingConfiguration stConfig : configs) { - result.add(new SwissTimingConfigurationDTO(stConfig.getName(), stConfig.getJsonURL(), stConfig.getHostname(), stConfig.getPort())); + result.add(new SwissTimingConfigurationDTO(stConfig.getName(), stConfig.getJsonURL(), + stConfig.getHostname(), stConfig.getPort(), stConfig.getUpdateURL(), stConfig.getUpdateUsername(), + stConfig.getUpdatePassword())); } return result; } @@ -2867,9 +2869,9 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } @Override - public void storeSwissTimingConfiguration(String configName, String jsonURL, String hostname, Integer port) { + public void storeSwissTimingConfiguration(String configName, String jsonURL, String hostname, Integer port, String updateURL, String updateUsername, String updatePassword) { if (!jsonURL.equalsIgnoreCase("test")) { - swissTimingAdapterPersistence.storeSwissTimingConfiguration(swissTimingFactory.createSwissTimingConfiguration(configName, jsonURL, hostname, port)); + swissTimingAdapterPersistence.storeSwissTimingConfiguration(swissTimingFactory.createSwissTimingConfiguration(configName, jsonURL, hostname, port, updateURL, updateUsername, updatePassword)); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/SwissTimingConfigurationDTO.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/SwissTimingConfigurationDTO.java index 45ebd1fb69b..5d95cc9e2d3 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/SwissTimingConfigurationDTO.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/SwissTimingConfigurationDTO.java @@ -8,14 +8,33 @@ public class SwissTimingConfigurationDTO implements IsSerializable { private String hostname; private Integer port; + /** + * The URL to use for updates fed back to the SwissTiming server, such as changes of race timings + * or course updates. + */ + private String updateURL; + + /** + * The username to use as part of the credentials for requests to the {@link #updateURL}. + */ + private String updateUsername; + + /** + * The password to use as part of the credentials for requests to the {@link #updateURL}. + */ + private String updatePassword; + public SwissTimingConfigurationDTO() {} - public SwissTimingConfigurationDTO(String name, String jsonURL, String hostname, Integer port) { + public SwissTimingConfigurationDTO(String name, String jsonURL, String hostname, Integer port, String updateURL, String updateUsername, String updatePassword) { super(); this.name = name; this.jsonURL = jsonURL; this.hostname = hostname; this.port = port; + this.updateURL = updateURL; + this.updateUsername = updateUsername; + this.updatePassword = updatePassword; } public String getName() { @@ -33,5 +52,16 @@ public class SwissTimingConfigurationDTO implements IsSerializable { public Integer getPort() { return port; } - + + public String getUpdateURL() { + return updateURL; + } + + public String getUpdateUsername() { + return updateUsername; + } + + public String getUpdatePassword() { + return updatePassword; + } } diff --git a/java/com.sap.sse.security.ui/GWT Security SDM.launch b/java/com.sap.sse.security.ui/GWT Security SDM.launch index e3402b6144b..4f18a99815c 100644 --- a/java/com.sap.sse.security.ui/GWT Security SDM.launch +++ b/java/com.sap.sse.security.ui/GWT Security SDM.launch @@ -7,7 +7,7 @@ - + @@ -38,7 +38,6 @@ - @@ -105,7 +104,7 @@ - + From ff33456ccbec1c5069d9ea92e6f9fc7526089d15 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 2 Aug 2018 14:55:31 +0200 Subject: [PATCH 11/53] removed a lot of empty lines Change-Id: I269e227f2f1a66caaf0f71718dc89ee8df900789 --- .../controls/filestorage/FileStoragePanel.java | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/controls/filestorage/FileStoragePanel.java b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/controls/filestorage/FileStoragePanel.java index 36c11588310..38e8dcb9a14 100644 --- a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/controls/filestorage/FileStoragePanel.java +++ b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/controls/filestorage/FileStoragePanel.java @@ -64,7 +64,6 @@ public class FileStoragePanel extends FlowPanel { public FileStoragePanel(FileStorageManagementGwtServiceAsync sailingService, ErrorReporter errorReporter) { this.sailingService = sailingService; this.errorReporter = errorReporter; - Button refreshButton = new Button(stringMessages.refresh()); refreshButton.addClickHandler(new ClickHandler() { @Override @@ -73,12 +72,10 @@ public class FileStoragePanel extends FlowPanel { } }); add(refreshButton); - CaptionPanel activeServicePanel = new CaptionPanel(stringMessages.active()); activeServiceLabel = new Label(); activeServicePanel.add(activeServiceLabel); add(activeServicePanel); - CaptionPanel editServicePanel = new CaptionPanel(stringMessages.edit()); VerticalPanel editServicePanelContent = new VerticalPanel(); editServicePanel.add(editServicePanelContent); @@ -90,10 +87,8 @@ public class FileStoragePanel extends FlowPanel { } }); editServicePanelContent.add(servicesListBox); - serviceDescriptionLabel = new Label(); editServicePanelContent.add(serviceDescriptionLabel); - propertiesTable = new BaseCelltable<>(); propertiesTable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.DISABLED); //allow for default tabbing behaviour propertiesListDataProvider = new ListDataProvider<>(new ArrayList()); @@ -122,7 +117,6 @@ public class FileStoragePanel extends FlowPanel { } }); propertiesTable.addColumn(inputColumn, stringMessages.value()); - TextColumn descriptionColumn = new TextColumn() { @Override public String getValue(FileStorageServicePropertyDTO p) { @@ -130,7 +124,6 @@ public class FileStoragePanel extends FlowPanel { } }; propertiesTable.addColumn(descriptionColumn, stringMessages.description()); - TextColumn errorColumn = new TextColumn() { @Override public String getValue(FileStorageServicePropertyDTO p) { @@ -140,15 +133,11 @@ public class FileStoragePanel extends FlowPanel { }; errorColumn.setCellStyleNames("errorLabel"); propertiesTable.addColumn(errorColumn, stringMessages.error()); - editServicePanelContent.add(propertiesTable); - propertiesErrorLabel = new Label(); propertiesErrorLabel.setStyleName("errorLabel"); editServicePanelContent.add(propertiesErrorLabel); - HorizontalPanel buttonsPanel = new HorizontalPanel(); - Button saveAndTestPropertiesButton = new Button(stringMessages.save()); saveAndTestPropertiesButton.addClickHandler(new ClickHandler() { @Override @@ -157,7 +146,6 @@ public class FileStoragePanel extends FlowPanel { } }); buttonsPanel.add(saveAndTestPropertiesButton); - Button setAsActiveServiceButton = new Button(stringMessages.setAsActive()); setAsActiveServiceButton.addClickHandler(new ClickHandler() { @Override @@ -166,11 +154,8 @@ public class FileStoragePanel extends FlowPanel { } }); buttonsPanel.add(setAsActiveServiceButton); - editServicePanelContent.add(buttonsPanel); - add(editServicePanel); - refresh(); } From 6357c5a07477700984e1c214759d3553ce1d91e4 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 2 Aug 2018 14:56:40 +0200 Subject: [PATCH 12/53] removed more empty lines; coding conventions (single point of exit) Change-Id: If35b90bcb61f324a5982aeb88cec07ae67c9293d --- .../client/controls/filestorage/FileStoragePanel.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/controls/filestorage/FileStoragePanel.java b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/controls/filestorage/FileStoragePanel.java index 38e8dcb9a14..282ab9c769f 100644 --- a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/controls/filestorage/FileStoragePanel.java +++ b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/controls/filestorage/FileStoragePanel.java @@ -94,7 +94,6 @@ public class FileStoragePanel extends FlowPanel { propertiesListDataProvider = new ListDataProvider<>(new ArrayList()); properties = propertiesListDataProvider.getList(); propertiesListDataProvider.addDataDisplay(propertiesTable); - TextColumn nameColumn = new TextColumn() { @Override public String getValue(FileStorageServicePropertyDTO p) { @@ -102,7 +101,6 @@ public class FileStoragePanel extends FlowPanel { } }; propertiesTable.addColumn(nameColumn, stringMessages.name()); - Column inputColumn = new Column( new TabbingTextInputCell()) { @Override @@ -258,12 +256,10 @@ public class FileStoragePanel extends FlowPanel { perPropertyErrors.clear(); serviceDescriptionLabel.setText(""); FileStorageServiceDTO selected = availableServices.get(getSelectedServiceName()); - if (selected == null) { - return; + if (selected != null) { + serviceDescriptionLabel.setText(selected.description); + properties.addAll(Arrays.asList(selected.properties)); } - - serviceDescriptionLabel.setText(selected.description); - properties.addAll(Arrays.asList(selected.properties)); } private String getLocaleInfo() { From 9ee507b246efaba02bd9c90c09933b8caf131e50 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 2 Aug 2018 14:57:26 +0200 Subject: [PATCH 13/53] removed more empty lines Change-Id: I55a06e6894f47840054510c0560fae5ed0904878 --- .../gwt/client/controls/filestorage/FileStoragePanel.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/controls/filestorage/FileStoragePanel.java b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/controls/filestorage/FileStoragePanel.java index 282ab9c769f..7535306d4e4 100644 --- a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/controls/filestorage/FileStoragePanel.java +++ b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/controls/filestorage/FileStoragePanel.java @@ -268,14 +268,12 @@ public class FileStoragePanel extends FlowPanel { private void refresh() { String oldSelectedService = getSelectedServiceName(); - servicesListBox.clear(); servicesListBox.addItem(""); availableServices.clear(); propertiesErrorLabel.setText(""); perPropertyErrors.clear(); onServiceSelectionChanged(); - sailingService.getActiveFileStorageServiceName(new AsyncCallback() { @Override public void onSuccess(String result) { @@ -287,7 +285,6 @@ public class FileStoragePanel extends FlowPanel { errorReporter.reportError(stringMessages.couldNotLoadActiveService() + ": " + caught.getMessage()); } }); - sailingService.getAvailableFileStorageServices(getLocaleInfo(), new AsyncCallback() { @Override public void onSuccess(FileStorageServiceDTO[] result) { @@ -302,14 +299,12 @@ public class FileStoragePanel extends FlowPanel { errorReporter.reportError(stringMessages.couldNotLoadAvailableServices() + ": " + caught.getMessage()); } }); - for (int i = 0; i < servicesListBox.getItemCount(); i++) { if (servicesListBox.getItemText(i).equals(oldSelectedService)) { servicesListBox.setSelectedIndex(i); } } onServiceSelectionChanged(); - testProperties(null); } } From 0633d476c05db0724ef3c85cf90dbefa585b23a8 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 2 Aug 2018 14:59:29 +0200 Subject: [PATCH 14/53] adjusted release notes# Please enter the commit message for your changes. Lines starting Change-Id: I5050ab84465bd49802958dfc911eec02a433cc07 --- java/com.sap.sailing.www/release_notes_admin.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/com.sap.sailing.www/release_notes_admin.html b/java/com.sap.sailing.www/release_notes_admin.html index aff77239787..f5a4d1f5b0d 100755 --- a/java/com.sap.sailing.www/release_notes_admin.html +++ b/java/com.sap.sailing.www/release_notes_admin.html @@ -25,6 +25,10 @@

July 2018

  • The mark passing editor now uses a full date/time format for the mark passing time points.
  • +
  • The TracTrac connector panel no longer shows a password visibly but uses a password text field.
  • +
  • The SwissTiming connector can now handle an "Update URL" together with username/password access + credentials which are used, if present, to send feedback requests about start times, race status + and course changes to that URL.

July 2018

From a61ec3dc511b389897430f0eae9be95b31a146bc Mon Sep 17 00:00:00 2001 From: "service.tip.git" Date: Thu, 2 Aug 2018 16:14:58 +0000 Subject: [PATCH 15/53] [INTERNAL] Translation delivery: commit by SLS Change-Id: I8f7cdca5464efaf89420311fe4b672510ae58545 --- .../gwt/ui/client/StringMessages_es.properties | 16 ++++++++++++---- .../gwt/ui/client/StringMessages_fr.properties | 16 ++++++++++++---- .../gwt/ui/client/StringMessages_ja.properties | 16 ++++++++++++---- .../gwt/ui/client/StringMessages_pt.properties | 16 ++++++++++++---- .../gwt/ui/client/StringMessages_ru.properties | 16 ++++++++++++---- .../gwt/ui/client/StringMessages_zh.properties | 16 ++++++++++++---- 6 files changed, 72 insertions(+), 24 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_es.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_es.properties index e28ec429798..6cddd2a64fb 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_es.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_es.properties @@ -480,6 +480,8 @@ scoringSchemeHighPointFirstGetsTwelveOrEight=Puntuación alta, el ganador obtien scoringSchemeHighPointFirstGetsTwelveOrEightDescription=Calificación en puntos. El ganador obtiene 12 puntos; el segundo, 11 puntos, etc. Si hay un empate, se resuelve a favor del competidor que tiene la mayor puntuación. Si aún persiste el empate, se resuelve mediante la posición obtenida en la última carrera puntuada. scoringSchemeHighPointFirstGetsTwelveOrEight2017=Puntuación alta ESS 2017, el ganador obtiene 12 puntos (u 8) scoringSchemeHighPointFirstGetsTwelveOrEight2017Description=Calificación en puntos. El ganador obtiene 12 puntos; el segundo, 11 puntos, etc. Si hay un empate, se resuelve a favor del competidor que tiene la mayor puntuación. Si aún persiste el empate, se resuelve mediante la posición obtenida en la última carrera puntuada. +scoringSchemeLowPointSystemFirstTwoWins=Sistema de puntuación baja, primero con dos victorias en medallas es ganador +scoringSchemeLowPointSystemFirstTwoWinsDescription=Sistema de puntuación baja. El primero en la serie de medallas que gane dos carreras, gana la serie de medallas. Ser el mejor en la serie premedallas cuenta como una victoria para este. scoringSystem=Sistema de puntuación createFlexibleLeaderboard=Crear tabla de clasificación flexible createRegattaLeaderboard=Crear tabla de clasificación de regata @@ -1276,13 +1278,11 @@ uploadSuccessful=Carga correcta fileUploadResult=Carga de archivos: {0} {1}. En caso de error, compruebe que su servicio de alojamiento de archivos está configurado correctamente. removeUploadedFile=Eliminar archivo showCompetitorBoatColumn=Embarcación del competidor -showCompetitorSailIdColumn=ID de vela -showCompetitorSailIdColumnTooltip=Muestra el ID de vela más la bandera del país o imagen del competidor. Si está disponible, se prioriza la imagen de competidor a la bandera del país. Se mostrarán ambos iconos si se fija "{0}". showCompetitorShortNameColumn=Denominación breve de competidor showCompetitorShortNameColumnTooltip=Muestra el nombre breve más la bandera del país o imagen del competidor. Si está disponible, se prioriza la imagen de competidor a la bandera del país. Se mostrarán ambos iconos si se fija "{0}". showCompetitorFullNameColumn=Nombre completo del competidor -alwaysShowCompetitorNationalityColumn=Siempre mostrar la nacionalidad del competidor -alwaysShowCompetitorNationalityColumnTooltip=Muestra ambos, las banderas de país así como las imágenes de competidor, si están disponibles. +showCompetitorNationalityColumn=Mostrar adicionalmente la nacionalidad del competidor +showCompetitorNationalityColumnTooltip=Mostrar las banderas de nacionalidad junto con las imágenes del competidor si están disponibles loadingDimensionValues=Cargando valores de dimensión inviteBuoyTenders=Invitar a balizadores orMultipleEmails=o varios correos electrónicos separados por una coma @@ -2059,6 +2059,9 @@ multiVideoIdle=Cola de trabajo inactiva multiVideoDoNoAdd=No añadir multiVideoOffsetInput=Offset de vídeo global en milisegundos: multiVideoDescription=El servidor web debe proporcionar una lista de índices (subcarpetas compatibles si están indexadas) para permitir la detección de ficheros. Tras un análisis inicial de los metadatos contenidos en los ficheros mp4, los vídeos que deben añadirse, deben seleccionarse mediante la columna de la casilla de selección a la izquierda. El botón "Añadir audio/vídeo" creará pistas multimedia para todos los ficheros seleccionados y los añadirá a todas las carreras seleccionadas en la columna de la derecha. +jibeAngle=Ángulo de trasluchada +tackAngle=Ángulo de bordo +maneuverAngle=Ángulo de maniobra multiUrlChangeMediaTrack=Ajustar URLs de rastreo múltiple de medios multiUrlChangeReplace=Reemplazar por multiUrlChangeFind=Buscar @@ -2070,6 +2073,11 @@ multiUrlChangeExplain=Este diálogo reemplazará en masa las partes comunes al i resetZoom=Reinicializar zoom lastEvent=Último evento: {0} teaserOverallLinkToolTip=Para visualizar las series generales, haga clic en la esquina amarilla +middleManeuverAngle=Ángulo medio de maniobra +extrapolatedManeuverStartPosition=Posición de inicio de maniobra extrapolada +projectedExtrapolatedManeuverStartPosition=Proyección de posición de inicio de maniobra extrapolada en línea de ángulo medio de maniobra +projectedManeuverEndPosition=Proyección de posición de fin de maniobra en línea de ángulo medio de maniobra +bearingAtManeuverEndPosition=Rumbo en posición de fin de maniobra gender=Sexo manage2SailEventIdBox=ID de evento Manage2Sail manage2SailEventURLBox=URL de evento Manage2Sail (json) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_fr.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_fr.properties index be10af53726..4eceacdde57 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_fr.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_fr.properties @@ -480,6 +480,8 @@ scoringSchemeHighPointFirstGetsTwelveOrEight=Système de points avec bonus, le v scoringSchemeHighPointFirstGetsTwelveOrEightDescription=Score en points. Le vainqueur totalise 12 points, le deuxième 11, etc. En cas d''égalité, la victoire est accordée au concurrent qui a totalisé le plus de points. Si l''égalité persiste, la victoire est accordée en fonction du classement dans la dernière course. scoringSchemeHighPointFirstGetsTwelveOrEight2017=Système de points avec bonus - ESS 2017, le vainqueur obtient 12 points (ou 8) scoringSchemeHighPointFirstGetsTwelveOrEight2017Description=Score en points. Le vainqueur totalise 12 points, le deuxième 11, etc. En cas d''égalité, la victoire est accordée au concurrent qui a totalisé le plus de points. Si l''égalité persiste, la victoire est accordée en fonction du classement dans la dernière course. +scoringSchemeLowPointSystemFirstTwoWins=Système de points a minima. Le premier ayant gagné deux médailles gagne la compétition. +scoringSchemeLowPointSystemFirstTwoWinsDescription=Système de points a minima. Le premier ayant gagné deux courses gagne la série médaillée. Si un concurrent a été le meilleur dans la série pré-médailles, cela compte comme une victoire pour la série médaillée. scoringSystem=Système d''attribution des points createFlexibleLeaderboard=Créer palmarès flexible createRegattaLeaderboard=Créer palmarès régate @@ -1276,13 +1278,11 @@ uploadSuccessful=Chargement réussi fileUploadResult=Chargement du fichier : {0} {1}.\nEn cas d''erreur, vérifiez que votre service de stockage de fichier est correctement configuré. removeUploadedFile=Supprimer fichier chargé showCompetitorBoatColumn=Bateau du concurrent -showCompetitorSailIdColumn=ID de voile -showCompetitorSailIdColumnTooltip=Affiche l''ID de voile ainsi que le drapeau national ou l''image du concurrent. Si les deux sont disponibles, l''image du concurrent aura la priorité sur le drapeau national. Si le code "{0}" est activé, les deux icônes seront affichées. showCompetitorShortNameColumn=Nom court du concurrent showCompetitorShortNameColumnTooltip=Affiche le nom court ainsi que le drapeau national ou l''image du concurrent. Si les deux sont disponibles, l''image du concurrent aura la priorité sur le drapeau national. Si le code "{0}" est activé, les deux icônes seront affichées. showCompetitorFullNameColumn=Nom complet du concurrent -alwaysShowCompetitorNationalityColumn=Afficher toujours la nationalité du concurrent -alwaysShowCompetitorNationalityColumnTooltip=Si disponibles, afficher les deux : le drapeau national ainsi que l''image du concurrent +showCompetitorNationalityColumn=Afficher en plus la nationalité du concurrent +showCompetitorNationalityColumnTooltip=Si disponible, afficher le drapeau national en plus de l''image du concurrent. loadingDimensionValues=Chargement des valeurs de dimension inviteBuoyTenders=Inviter navire baliseur orMultipleEmails=ou plusieurs adresses e-mails séparées par des virgules @@ -2059,6 +2059,9 @@ multiVideoIdle=La réserve de travail est inactive. multiVideoDoNoAdd=Ne pas ajouter multiVideoOffsetInput=Décalage vidéo global en millisecondes : multiVideoDescription=Le serveur Web doit fournir une liste des index (les sous-dossiers sont pris en charge s''ils sont répertoriés) pour permettre la détection de fichier. Après une analyse initiale des métadonnées contenues dans les fichiers MP4, les vidéos à ajouter doivent être sélectionnées en cochant les cases correspondantes dans la colonne de gauche. Le bouton "Ajouter audio/vidéo" va créer des pistes médias pour tous les fichiers sélectionnés, et ajouter ces fichiers à toutes les courses sélectionnées dans la colonne de droite. +jibeAngle=Angle d''amure +tackAngle=Angle de virement de bord +maneuverAngle=Angle de manœuvre multiUrlChangeMediaTrack=Ajuster plusieurs URL de piste média multiUrlChangeReplace=Remplacer par multiUrlChangeFind=Rechercher @@ -2070,6 +2073,11 @@ multiUrlChangeExplain=Cette boîte de dialogue remplacera en masse les élément resetZoom=Réinitialiser le zoom lastEvent=Dernière manifestation : {0} teaserOverallLinkToolTip=Pour afficher l''ensemble des séries, cliquez sur le coin jaune. +middleManeuverAngle=Angle de manœuvre (milieu) +extrapolatedManeuverStartPosition=Position extrapolée du début de la manœuvre +projectedExtrapolatedManeuverStartPosition=Projection de la position extrapolée du début de la manœuvre sur la ligne de l''angle de manœuvre (milieu) +projectedManeuverEndPosition=Projection de la position extrapolée de fin de la manœuvre sur la ligne de l''angle de manœuvre (milieu) +bearingAtManeuverEndPosition=Direction à la position de fin de la manœuvre gender=Sexe manage2SailEventIdBox=ID de manifestation Manage2Sail manage2SailEventURLBox=URL de la manifestation Manage2Sail (json) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ja.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ja.properties index 18e9f91ca5a..6bcbca3f0b9 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ja.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ja.properties @@ -480,6 +480,8 @@ scoringSchemeHighPointFirstGetsTwelveOrEight=高得点方式、1 位が 12 点 ( scoringSchemeHighPointFirstGetsTwelveOrEightDescription=得点数によるスコアです。1 位が 12 点、2 位が 11 点などと得点します。同点となった場合は、(各競技者のレース得点を高い方から比較して) 最多得点の競技者を上位とします。それでも同順位となる場合には、最終レースでの得点でのランクで順位を決定します。 scoringSchemeHighPointFirstGetsTwelveOrEight2017=高得点方式 ESS 2017、1 位が 12 点 (または 8 点) scoringSchemeHighPointFirstGetsTwelveOrEight2017Description=得点数によるスコアです。1 位が 12 点、2 位が 11 点などと得点します。同点となった場合は、(各競技者のレース得点を高い方から比較して) 最多得点の競技者を上位とします。それでも同順位となる場合には、最終レースでの得点でのランクで順位を決定します。 +scoringSchemeLowPointSystemFirstTwoWins=低得点方式、メダルシリーズで最初に 2 勝した者が勝者 +scoringSchemeLowPointSystemFirstTwoWinsDescription=低得点方式。メダルシリーズで最初に 2 レースに勝利した者をメダルシリーズの勝者とします。プレメダルシリーズでの最上位をメダルシリーズの 1 勝としてカウントします。 scoringSystem=得点方式 createFlexibleLeaderboard=フレキシブルリーダーボード登録 createRegattaLeaderboard=レガッタリーダーボード登録 @@ -1276,13 +1278,11 @@ uploadSuccessful=正常にアップロード済 fileUploadResult=ファイルアップロード: {0} {1}\nエラー発生の場合は、ファイルストレージサービスが適切に設定されていることを確認してください。 removeUploadedFile=アップロード済ファイルの削除 showCompetitorBoatColumn=競技者の艇 -showCompetitorSailIdColumn=セール ID -showCompetitorSailIdColumnTooltip=セール ID に加えて国旗または競技者画像を表示します。競技者画像が利用可能な場合はそれを国旗よりも優先させます。"{0}" が設定されている場合、両方のアイコンが表示されます。 showCompetitorShortNameColumn=競技者の名前 (短) showCompetitorShortNameColumnTooltip=名前 (短) に加えて国旗または競技者画像を表示します。競技者画像が利用可能な場合はそれを国旗よりも優先させます。"{0}" が設定されている場合、両方のアイコンが表示されます。 showCompetitorFullNameColumn=競技者氏名 -alwaysShowCompetitorNationalityColumn=競技者国籍を常に表示 -alwaysShowCompetitorNationalityColumnTooltip=国旗と競技者画像 (利用可能な場合) の両方を表示 +showCompetitorNationalityColumn=競技者国籍を追加的に表示 +showCompetitorNationalityColumnTooltip=競技者画像に加え国旗を表示 (利用可能な場合) loadingDimensionValues=次元値ロード中 inviteBuoyTenders=ブイ入札の招待 orMultipleEmails=または複数の電子メールをカンマで区切り @@ -2059,6 +2059,9 @@ multiVideoIdle=ワークキューが無効です multiVideoDoNoAdd=追加しないでください multiVideoOffsetInput=グローバル動画オフセット (msec): multiVideoDescription=Web サーバは、ファイルディスカバリを可能にするため、インデックスリスト (インデックスが作成されている場合はサブフォルダがサポート済) を用意していることが必要です。MP4 ファイルに含まれているメタデータの初期解析後に、追加する動画を左側のチェックボックス列で選択する必要があります。"音声/動画追加" ボタンにより、選択されているすべてのファイルに対してメディアトラックが作成され、右側の列で選択されているすべてのレースに対してそれらのファイルが追加されます。 +jibeAngle=ジャイブ角 +tackAngle=タック角 +maneuverAngle=マニューバー角 multiUrlChangeMediaTrack=複数メディアトラック URL の調整 multiUrlChangeReplace=置換後の文字列 multiUrlChangeFind=検索 @@ -2070,6 +2073,11 @@ multiUrlChangeExplain=このダイアログはメディアトラック URL 先 resetZoom=拡大/縮小のリセット lastEvent=最終イベント: {0} teaserOverallLinkToolTip=シリーズ全体を参照するには、黄色になっている隅の部分をクリックしてください +middleManeuverAngle=マニューバー角の中心 +extrapolatedManeuverStartPosition=推定マニューバー開始位置 +projectedExtrapolatedManeuverStartPosition=マニューバー角の中心線上に推定マニューバー開始位置を投影 +projectedManeuverEndPosition=マニューバー角の中心線上にマニューバー終了位置を投影 +bearingAtManeuverEndPosition=マニューバー終了位置での方位 gender=性別 manage2SailEventIdBox=Manage2Sail イベント ID manage2SailEventURLBox=Manage2Sail イベント URL (JSON) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_pt.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_pt.properties index 78d242a2e15..d13909efea6 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_pt.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_pt.properties @@ -480,6 +480,8 @@ scoringSchemeHighPointFirstGetsTwelveOrEight=Sistema de bônus, o vencedor receb scoringSchemeHighPointFirstGetsTwelveOrEightDescription=Pontuação em pontos. O vencedor pontua 12 pontos, o 2º - 11 pontos, .... Um desempate é efetuado a favor do competidor com a pontuação mais alta, se o empate continuar, então o desempate é efetuado pela posição na última corrida pontuada. scoringSchemeHighPointFirstGetsTwelveOrEight2017=Sistema de bônus ESS 2017, o vencedor recebe 12 pontos (ou 8) scoringSchemeHighPointFirstGetsTwelveOrEight2017Description=Pontuação em pontos. O vencedor pontua 12 pontos, o 2º - 11 pontos, .... Um desempate é efetuado a favor do competidor com a pontuação mais alta, se o empate continuar, então o desempate é efetuado pela posição na última corrida pontuada. +scoringSchemeLowPointSystemFirstTwoWins=Sistema linear, o primeiro com duas vitórias com medalhas é o vencedor. +scoringSchemeLowPointSystemFirstTwoWinsDescription=Sistema linear. O primeiro na série para medalha a vencer duas corridas vence a série para medalha. Ser o melhor na série prévia para medalha conta como uma vitória para este efeito. scoringSystem=Sistema de pontuação createFlexibleLeaderboard=Criar painel de classificação flexível createRegattaLeaderboard=Criar painel de classificação de regata @@ -1276,13 +1278,11 @@ uploadSuccessful=Carregamento efetuado com êxito fileUploadResult=Carregamento de arquivo: {0} {1}.\nEm caso de erro, verifique se seu serviço de armazenamento de arquivos está configurado de modo apropriado. removeUploadedFile=Remover arquivo carregado showCompetitorBoatColumn=Barco do competidor -showCompetitorSailIdColumn=ID da vela -showCompetitorSailIdColumnTooltip=Exibe o ID da vela mais a bandeira de nacionalidade ou a imagem do competidor. Se disponível, é priorizada uma imagem do competidor em relação a uma bandeira da nacionalidade. Se "{0}" estiver definido, ambos os ícones serão exibidos. showCompetitorShortNameColumn=Nome abreviado do competidor showCompetitorShortNameColumnTooltip=Exibe o nome abreviado mais a bandeira de nacionalidade ou a imagem do competidor. Se disponível, é priorizada uma imagem do competidor em relação a uma bandeira da nacionalidade. Se "{0}" estiver definido, ambos os ícones serão exibidos. showCompetitorFullNameColumn=Nome completo do competidor -alwaysShowCompetitorNationalityColumn=Exibir sempre a nacionalidade do competidor -alwaysShowCompetitorNationalityColumnTooltip=Exibir ambos, bandeiras de nacionalidade e imagens do competidor, se disponíveis +showCompetitorNationalityColumn=Exibir adicionalmente a nacionalidade do competidor +showCompetitorNationalityColumnTooltip=Exibir bandeiras de nacionalidade além das imagens do competidor, caso estejam disponíveis loadingDimensionValues=Carregando valores de dimensão inviteBuoyTenders=Convidar navios-balizadores orMultipleEmails=ou vários e-mails separados por vírgula @@ -2059,6 +2059,9 @@ multiVideoIdle=A lista de trabalho está inativa multiVideoDoNoAdd=Não adicionar multiVideoOffsetInput=Deslocamento de vídeo global em milissegundos: multiVideoDescription=O servidor da web é necessário para fornecer a lista de índices (subpastas suportadas se indexadas) de modo a permitir a descoberta de arquivos. Após uma análise inicial dos metadados contidos nos arquivos mp4, os vídeos que deviam ser adicionados precisam ser selecionados mediante a coluna do campo de seleção à esquerda. O botão "Adicionar áudio/vídeo" irá criar faixas de mídia para todos os arquivos selecionados e adicionar esses arquivos a todas as corridas selecionadas na coluna à direita. +jibeAngle=Ângulo de jaibe +tackAngle=Ângulo de cambada +maneuverAngle=Ângulo de manobra multiUrlChangeMediaTrack=Ajustar vários URLs de faixa de mídia multiUrlChangeReplace=Substituir por multiUrlChangeFind=Procurar @@ -2070,6 +2073,11 @@ multiUrlChangeExplain=Este diálogo irá substituir em massa as partes comuns no resetZoom=Reinicializar zoom lastEvent=Último evento: {0} teaserOverallLinkToolTip=Para ver a série completa, clique no canto amarelo +middleManeuverAngle=Ângulo médio de manobra +extrapolatedManeuverStartPosition=Posição inicial de manobra extrapolada +projectedExtrapolatedManeuverStartPosition=Projeção da posição inicial de manobra extrapolada na linha de ângulo médio de manobra +projectedManeuverEndPosition=Projeção da posição final de manobra na linha de ângulo médio de manobra +bearingAtManeuverEndPosition=Rumo na posição final de manobra gender=Sexo manage2SailEventIdBox=ID de evento Manage2Sail manage2SailEventURLBox=URL de evento Manage2Sail (json) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties index e9612321f5a..4bf82159e3e 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties @@ -480,6 +480,8 @@ scoringSchemeHighPointFirstGetsTwelveOrEight=Высокий балл, побед scoringSchemeHighPointFirstGetsTwelveOrEightDescription=Оценка в баллах. Победитель получает 12 баллов, 2-й — 11 баллов, .... Равенство разрешается в пользу участника с наивысшей оценкой. Если равенство сохраняется, оно разрешается по рангу в последней гонке. scoringSchemeHighPointFirstGetsTwelveOrEight2017=Высокий балл ESS 2017, победитель получает 12 баллов (или 8) scoringSchemeHighPointFirstGetsTwelveOrEight2017Description=Оценка в баллах. Победитель получает 12 баллов, 2-й — 11 баллов, .... Равенство разрешается в пользу участника с наивысшей оценкой. Если равенство сохраняется, оно разрешается по рангу в последней гонке. +scoringSchemeLowPointSystemFirstTwoWins=Система низких баллов, первый с двумя победами в гонках на медали является победителем +scoringSchemeLowPointSystemFirstTwoWinsDescription=Система низких баллов. Первый в серии на медали, кто выиграл две гонки, выигрывает серию на медали. Получение статуса "Лучший" в серии, предшествующей медальной, считается одной победой. scoringSystem=Система оценок createFlexibleLeaderboard=Создать гибкую таблицу лидеров createRegattaLeaderboard=Создать таблицу лидеров регаты @@ -1276,13 +1278,11 @@ uploadSuccessful=Отправлено успешно fileUploadResult=Отправка файла: {0} {1}.\nВ случае ошибки проверьте правильность конфигурации службы хранилища файлов. removeUploadedFile=Удалить отправленный файл showCompetitorBoatColumn=Лодка участника -showCompetitorSailIdColumn=Ид. паруса -showCompetitorSailIdColumnTooltip=Показывает ид. паруса плюс государственный флаг или изображение участника. Изображение участника, при наличии, имеет приоритет над государственным флагом. Если установлен параметр "{0}", будут отображены оба значка. showCompetitorShortNameColumn=Краткое имя участника showCompetitorShortNameColumnTooltip=Показывает краткое имя плюс государственный флаг или изображение участника. Изображение участника, при наличии, имеет приоритет над государственным флагом. Если установлен параметр "{0}", будут отображены оба значка. showCompetitorFullNameColumn=Полное имя участника -alwaysShowCompetitorNationalityColumn=Всегда показывать государственную принадлежность участника -alwaysShowCompetitorNationalityColumnTooltip=Показывать и флаги государств, и изображения участников (при наличии) +showCompetitorNationalityColumn=Дополнительно показывать государственную принадлежность участника +showCompetitorNationalityColumnTooltip=Показывать государственные флаги (если есть) дополнительно к фотографии участника loadingDimensionValues=Загрузка значений измерения inviteBuoyTenders=Пригласить лоцманов orMultipleEmails=или несколько адресов эл. почты через запятую @@ -2059,6 +2059,9 @@ multiVideoIdle=Рабочий список неактивен multiVideoDoNoAdd=Не добавлять multiVideoOffsetInput=Смещение глобального видео в мс: multiVideoDescription=Веб-сервер необходим для предоставления списка индекса (подпапки поддерживаются, если проиндексированы) для поиска файлов. После первичного анализа метаданных, содержащихся в файлах mp4, видео, которые должны быть добавлены, необходимо выбрать в столбце с флажками слева. При нажатии кнопки "Добавить аудио/видео" будут созданы медиаканалы для всех выбранных файлов, а файлы будут добавлены ко всем гонкам, выбранным в правом столбце. +jibeAngle=Поворот фордевинд +tackAngle=Галсовый угол +maneuverAngle=Угол маневра multiUrlChangeMediaTrack=Адаптировать URL объектов мультимедиа multiUrlChangeReplace=Заменить на multiUrlChangeFind=Найти @@ -2070,6 +2073,11 @@ multiUrlChangeExplain=В этом диалоговом окне можно вы resetZoom=Сбросить увеличение lastEvent=Последнее событие: {0} teaserOverallLinkToolTip=Чтобы увидеть все серии, нажмите желтый треугольник +middleManeuverAngle=Угол в середине маневра +extrapolatedManeuverStartPosition=Расширенная начальная позиция маневра +projectedExtrapolatedManeuverStartPosition=Проекция расширенной начальной позиции маневра на линии угла в середине маневра +projectedManeuverEndPosition=Проекция конечной позиции маневра на линии угла в середине маневра +bearingAtManeuverEndPosition=Направление в конечной позиции маневра gender=Пол manage2SailEventIdBox=Ид. события Manage2Sail manage2SailEventURLBox=URL события Manage2Sail (json) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties index 16c5f949a2f..e8e848faa28 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties @@ -480,6 +480,8 @@ scoringSchemeHighPointFirstGetsTwelveOrEight=高分,获胜者得 12 分(或 scoringSchemeHighPointFirstGetsTwelveOrEightDescription=得分。获胜者得 12 分、第 2 名 11 分、.... 得分最高的参赛队取得胜利,如果仍有平局,则以最后一个比赛轮次的名次打破平局。 scoringSchemeHighPointFirstGetsTwelveOrEight2017=2017 年极限帆船系列赛高分,获胜者得 12 分(或 8 分) scoringSchemeHighPointFirstGetsTwelveOrEight2017Description=得分。获胜者得 12 分、第 2 名 11 分、.... 得分最高的参赛队取得胜利,如果仍有平局,则以最后一个比赛轮次的名次打破平局。 +scoringSchemeLowPointSystemFirstTwoWins=低分系统,奖牌轮中取得两场胜利的第一名为获胜者 +scoringSchemeLowPointSystemFirstTwoWinsDescription=低分系统。在奖牌轮系列中,在两个比赛轮次中获胜的第一名在奖牌轮系列中获胜。奖牌轮系列预赛中的佼佼者记为获胜。 scoringSystem=记分系统 createFlexibleLeaderboard=创建灵活的积分榜 createRegattaLeaderboard=创建比赛积分榜 @@ -1276,13 +1278,11 @@ uploadSuccessful=上传成功 fileUploadResult=文件上传: {0} {1}。\n如果出错,请检查文件存储服务配置是否正确。 removeUploadedFile=移除上传的文件 showCompetitorBoatColumn=参赛队的船只 -showCompetitorSailIdColumn=帆号 -showCompetitorSailIdColumnTooltip=显示帆号和国籍旗帜或参赛队图像。如果可用,参赛队图像优先于国籍旗帜。如果设置 "{0}",将显示这两种图标。 showCompetitorShortNameColumn=参赛队短名称 showCompetitorShortNameColumnTooltip=显示短名称和国籍旗帜或参赛队图像。如果可用,参赛队图像优先于国籍旗帜。如果设置 "{0}",将显示这两种图标。 showCompetitorFullNameColumn=参赛队全名 -alwaysShowCompetitorNationalityColumn=始终显示参赛队国籍 -alwaysShowCompetitorNationalityColumnTooltip=如果可用,显示两者:国籍旗帜和参赛队图像 +showCompetitorNationalityColumn=另外显示参赛队国籍 +showCompetitorNationalityColumnTooltip=除参赛队图像外还显示国籍旗帜(如果有) loadingDimensionValues=正在加载尺寸值 inviteBuoyTenders=邀请浮标供应船 orMultipleEmails=或使用逗号隔开的多个电子邮件 @@ -2059,6 +2059,9 @@ multiVideoIdle=工作队列空闲 multiVideoDoNoAdd=请勿添加 multiVideoOffsetInput=全球视频偏移量(毫秒): multiVideoDescription=需要 Web 服务器提供索引清单(如果已编入索引,则支持的子文件夹),以允许发现文件。初始分析 mp4 文件中包含的元数据后,需要通过左侧的复选框列选择应添加的视频。“添加音频/视频”按钮将为所有选择的文件创建媒体轨道,并将这些文件添加到右列中选择的所有比赛轮次中。 +jibeAngle=顺风转向角度 +tackAngle=迎风转向角度 +maneuverAngle=操作角度 multiUrlChangeMediaTrack=调整多个媒体轨道 URL multiUrlChangeReplace=替换为 multiUrlChangeFind=查找 @@ -2070,6 +2073,11 @@ multiUrlChangeExplain=此对话框将在媒体轨道 URL 的起始处批量替 resetZoom=重置缩放 lastEvent=上次活动:{0} teaserOverallLinkToolTip=请查看整体系列赛,请点击黄色角落 +middleManeuverAngle=中间操作角度 +extrapolatedManeuverStartPosition=推断的操作开始位置 +projectedExtrapolatedManeuverStartPosition=推断的操作开始位置在中间操作角度线上的投影 +projectedManeuverEndPosition=操作结束位置在中间操作角度线上的投影 +bearingAtManeuverEndPosition=操作结束位置的航向角 gender=性别 manage2SailEventIdBox=Manage2Sail 活动编号 manage2SailEventURLBox=Manage2Sail 活动 URL (json) From 8132371d0f45e9f71ba10d4aeaabf69848c70ef5 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 3 Aug 2018 10:02:02 +0200 Subject: [PATCH 16/53] hooking up the update handlers to the SwissTimingRaceTracker if updateURL is provided Change-Id: I191ce34857aa37ca6c3e9fa402d36c00ffac0378 --- .../SwissTimingConnectivityParamsHandler.java | 11 ++- .../swisstimingadapter/DomainFactory.java | 11 ++- .../SailMasterListener.java | 5 +- .../SwissTimingAdapter.java | 5 +- .../SwissTimingFactory.java | 16 ++-- .../impl/DomainFactoryImpl.java | 31 ++++++- .../impl/SwissTimingAdapterImpl.java | 5 +- .../impl/SwissTimingFactoryImpl.java | 26 +++--- .../impl/SwissTimingRaceTrackerImpl.java | 80 ++++++++++++------- ...sTimingTrackingConnectivityParameters.java | 32 ++++++-- .../impl/DomainFactoryImpl.java | 11 ++- .../impl/RaceCourseReceiver.java | 16 ++-- .../sailing/domain/base/DomainFactory.java | 12 +++ .../domain/base/impl/DomainFactoryImpl.java | 16 ++++ .../gwt/ui/test/SailingServiceImplMock.java | 2 +- .../SwissTimingEventManagementPanel.java | 9 ++- .../sailing/gwt/ui/client/SailingService.java | 5 +- .../gwt/ui/client/SailingServiceAsync.java | 2 +- .../gwt/ui/server/SailingServiceImpl.java | 6 +- ...ingConnectivityParamsLoadAndStoreTest.java | 6 +- 20 files changed, 211 insertions(+), 96 deletions(-) diff --git a/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/SwissTimingConnectivityParamsHandler.java b/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/SwissTimingConnectivityParamsHandler.java index a034257ea2b..5c8dca04bae 100644 --- a/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/SwissTimingConnectivityParamsHandler.java +++ b/java/com.sap.sailing.domain.swisstimingadapter.persistence/src/com/sap/sailing/domain/swisstimingadapter/persistence/impl/SwissTimingConnectivityParamsHandler.java @@ -54,6 +54,9 @@ public class SwissTimingConnectivityParamsHandler extends AbstractRaceTrackingCo private static final String PORT = "port"; private static final String BOAT_CLASS_NAME = "boatClassName"; private static final String HOSTNAME = "hostname"; + private static final String UPDATE_URL = "updateURL"; + private static final String UPDATE_USERNAME = "updateUsername"; + private static final String UPDATE_PASSWORD = "updatePassword"; private final RaceLogStore raceLogStore; private final RegattaLogStore regattaLogStore; private final DomainFactory domainFactory; @@ -78,6 +81,9 @@ public class SwissTimingConnectivityParamsHandler extends AbstractRaceTrackingCo result.put(START_LIST, createStartListDBObject(stParams)); result.put(DELAY_TO_LIVE_IN_MILLIS, stParams.getDelayToLiveInMillis()); result.put(USE_INTERNAL_MARK_PASSING_ALGORITHM, stParams.isUseInternalMarkPassingAlgorithm()); + result.put(UPDATE_URL, stParams.getUpdateURL()); + result.put(UPDATE_USERNAME, stParams.getUpdateUsername()); + result.put(UPDATE_PASSWORD, stParams.getUpdatePassword()); addWindTrackingParameters(stParams, result); return result; } @@ -175,7 +181,10 @@ public class SwissTimingConnectivityParamsHandler extends AbstractRaceTrackingCo map.get(START_LIST) == null ? null : createStartListFromDBObject((String) map.get(RACE_ID), (BasicDBList) map.get(START_LIST)), ((Number) map.get(DELAY_TO_LIVE_IN_MILLIS)).longValue(), swissTimingFactory, domainFactory, raceLogStore, regattaLogStore, - (boolean) map.get(USE_INTERNAL_MARK_PASSING_ALGORITHM), isTrackWind(map), isCorrectWindDirectionByMagneticDeclination(map)); + (boolean) map.get(USE_INTERNAL_MARK_PASSING_ALGORITHM), isTrackWind(map), isCorrectWindDirectionByMagneticDeclination(map), + (String) map.get(UPDATE_URL), + (String) map.get(UPDATE_USERNAME), + (String) map.get(UPDATE_PASSWORD)); } @Override diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/DomainFactory.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/DomainFactory.java index b8036a8adc0..c9a4979fa1f 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/DomainFactory.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/DomainFactory.java @@ -1,6 +1,7 @@ package com.sap.sailing.domain.swisstimingadapter; import java.io.Serializable; +import java.net.URISyntaxException; import java.util.List; import java.util.Map; @@ -18,6 +19,7 @@ import com.sap.sailing.domain.common.tracking.GPSFixMoving; import com.sap.sailing.domain.racelog.RaceLogStore; import com.sap.sailing.domain.regattalog.RegattaLogStore; import com.sap.sailing.domain.swisstimingadapter.impl.DomainFactoryImpl; +import com.sap.sailing.domain.tracking.DynamicTrackedRace; import com.sap.sailing.domain.tracking.MarkPassing; import com.sap.sailing.domain.tracking.RaceTrackingConnectivityParameters; import com.sap.sailing.domain.tracking.TrackedRegattaRegistry; @@ -70,10 +72,17 @@ public interface DomainFactory { RaceTrackingConnectivityParameters createTrackingConnectivityParameters(String hostname, int port, String raceID, String raceName, String raceDescription, BoatClass boatClass, StartList startList, long delayToLiveInMillis, SwissTimingFactory swissTimingFactory, DomainFactory domainFactory, - RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, boolean useInternalMarkPassingAlgorithm, boolean trackWind, boolean correctWindDirectionByMagneticDeclination); + RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, boolean useInternalMarkPassingAlgorithm, boolean trackWind, boolean correctWindDirectionByMagneticDeclination, String updateURL, String updateUsername, String updatePassword); ControlPoint getOrCreateControlPoint(String description, Iterable deviceIds, MarkType markType); RaceDefinition createRaceDefinition(Regatta regatta, String swissTimingRaceID, Map competitorsAndBoats, List courseDefinition, String raceName, String raceIdForRaceDefinition); + + /** + * Adds update handlers that forward events about a race, such as start time changes, course changes + * or postponents, to an update URL using specific REST requests. + */ + void addUpdateHandlers(String updateURL, String username, String password, Serializable eventId, + RaceDefinition raceDefinition, DynamicTrackedRace trackedRace) throws URISyntaxException; } diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SailMasterListener.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SailMasterListener.java index 10f4669c7f5..cdeaf3a7368 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SailMasterListener.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SailMasterListener.java @@ -1,5 +1,6 @@ package com.sap.sailing.domain.swisstimingadapter; +import java.net.URISyntaxException; import java.util.Collection; import java.util.List; @@ -16,9 +17,9 @@ public interface SailMasterListener { void receivedClockAtMark(String raceID, List> markIndicesTimePointsAndBoatIDs); - void receivedStartList(String raceID, StartList startList); + void receivedStartList(String raceID, StartList startList) throws URISyntaxException; - void receivedCourseConfiguration(String raceID, Course course); + void receivedCourseConfiguration(String raceID, Course course) throws URISyntaxException; void receivedAvailableRaces(Iterable races); diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingAdapter.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingAdapter.java index e275b3573c8..36c79299bfd 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingAdapter.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingAdapter.java @@ -28,10 +28,13 @@ public interface SwissTimingAdapter { * @param useInternalMarkPassingAlgorithm use our own instead of the SwissTiming-provided mark passing / split times * @param trackWind TODO * @param correctWindDirectionByMagneticDeclination TODO + * @param updateURL TODO + * @param updateUsername TODO + * @param updatePassword TODO */ RaceHandle addSwissTimingRace(TrackerManager trackerManager, RegattaIdentifier regattaToAddTo, String raceID, String raceName, String raceDescription, BoatClass boatClass, String hostname, int port, - StartList startList, RaceLogStore logStore, RegattaLogStore regattaLogStore, long timeoutInMilliseconds, boolean useInternalMarkPassingAlgorithm, boolean trackWind, boolean correctWindDirectionByMagneticDeclination) + StartList startList, RaceLogStore logStore, RegattaLogStore regattaLogStore, long timeoutInMilliseconds, boolean useInternalMarkPassingAlgorithm, boolean trackWind, boolean correctWindDirectionByMagneticDeclination, String updateURL, String updateUsername, String updatePassword) throws InterruptedException, UnknownHostException, IOException, ParseException, Exception; StartList readStartListForRace(String raceId, RegattaResults regattaResults); diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingFactory.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingFactory.java index 407239168ff..33ea647eaa3 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingFactory.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingFactory.java @@ -51,18 +51,12 @@ public interface SwissTimingFactory { SwissTimingConfiguration createSwissTimingConfiguration(String name, String jsonURL, String hostname, Integer port, String updateURL, String updateUsername, String updatePassword); - SwissTimingRaceTracker createRaceTracker(String raceID, String raceName, String raceDescription, - BoatClass boatClass, String hostname, int port, StartList startList, long delayToLiveInMillis, - RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore, - boolean useInternalMarkPassingAlgorithm, DomainFactory domainFactory, - TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver, SwissTimingTrackingConnectivityParameters connectivityParams) throws InterruptedException, UnknownHostException, - IOException, ParseException; + SwissTimingRaceTracker createRaceTracker(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore, + DomainFactory domainFactory, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver, SwissTimingTrackingConnectivityParameters connectivityParams) + throws InterruptedException, UnknownHostException, IOException, ParseException; - RaceTracker createRaceTracker(Regatta regatta, String raceID, String raceName, String raceDescription, - BoatClass boatClass, String hostname, int port, StartList startList, long delayToLiveInMillis, - WindStore windStore, boolean useInternalMarkPassingAlgorithm, DomainFactory domainFactory, - TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver, RaceLogStore raceLogStore, - RegattaLogStore regattaLogStore, SwissTimingTrackingConnectivityParameters connectivityParams) + RaceTracker createRaceTracker(Regatta regatta, WindStore windStore, DomainFactory domainFactory, TrackedRegattaRegistry trackedRegattaRegistry, + RaceLogResolver raceLogResolver, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, SwissTimingTrackingConnectivityParameters connectivityParams) throws UnknownHostException, InterruptedException, IOException, ParseException; Race createRace(String raceId, String raceName, String description, BoatClass boatClass); diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/DomainFactoryImpl.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/DomainFactoryImpl.java index 5c493877887..758369f0b5b 100644 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/DomainFactoryImpl.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/DomainFactoryImpl.java @@ -1,6 +1,8 @@ package com.sap.sailing.domain.swisstimingadapter.impl; import java.io.Serializable; +import java.net.URI; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; @@ -50,9 +52,14 @@ import com.sap.sailing.domain.swisstimingadapter.RaceType; import com.sap.sailing.domain.swisstimingadapter.RaceType.OlympicRaceCode; import com.sap.sailing.domain.swisstimingadapter.StartList; import com.sap.sailing.domain.swisstimingadapter.SwissTimingFactory; +import com.sap.sailing.domain.tracking.DynamicTrackedRace; import com.sap.sailing.domain.tracking.MarkPassing; import com.sap.sailing.domain.tracking.RaceTrackingConnectivityParameters; import com.sap.sailing.domain.tracking.TrackedRegattaRegistry; +import com.sap.sailing.domain.tracking.impl.CourseDesignUpdateHandler; +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.sse.common.Named; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; @@ -402,9 +409,29 @@ public class DomainFactoryImpl implements DomainFactory { String raceID, String raceName, String raceDescription, BoatClass boatClass, StartList startList, long delayToLiveInMillis, SwissTimingFactory swissTimingFactory, DomainFactory domainFactory, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, boolean useInternalMarkPassingAlgorithm, - boolean trackWind, boolean correctWindDirectionByMagneticDeclination) { + boolean trackWind, boolean correctWindDirectionByMagneticDeclination, String updateURL, + String updateUsername, String updatePassword) { return new SwissTimingTrackingConnectivityParameters(hostname, port, raceID, raceName, raceDescription, boatClass, startList, delayToLiveInMillis, swissTimingFactory, domainFactory, raceLogStore, - regattaLogStore, useInternalMarkPassingAlgorithm, trackWind, correctWindDirectionByMagneticDeclination); + regattaLogStore, useInternalMarkPassingAlgorithm, trackWind, correctWindDirectionByMagneticDeclination, + updateURL, updateUsername, updatePassword); + } + + @Override + public void addUpdateHandlers(String updateURL, String username, String password, Serializable eventId, + RaceDefinition raceDefinition, DynamicTrackedRace trackedRace) throws URISyntaxException { + final URI updateURI = new URI(updateURL); + CourseDesignUpdateHandler courseDesignHandler = new CourseDesignUpdateHandler( + updateURI, username, password, eventId, raceDefinition.getId()); + StartTimeUpdateHandler startTimeHandler = new StartTimeUpdateHandler( + updateURI, username, password, eventId, + raceDefinition.getId(), trackedRace.getTrackedRegatta().getRegatta()); + RaceAbortedHandler raceAbortedHandler = new RaceAbortedHandler( + updateURI, username, password, eventId, + raceDefinition.getId()); + final FinishTimeUpdateHandler finishTimeUpdateHandler = new FinishTimeUpdateHandler(updateURI, username, password, eventId, + raceDefinition.getId(), trackedRace.getTrackedRegatta().getRegatta()); + baseDomainFactory.addUpdateHandlers(trackedRace, courseDesignHandler, startTimeHandler, raceAbortedHandler, + finishTimeUpdateHandler); } } diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingAdapterImpl.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingAdapterImpl.java index 9d386a29c6b..ac1d291a4d8 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingAdapterImpl.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingAdapterImpl.java @@ -69,12 +69,13 @@ public class SwissTimingAdapterImpl implements SwissTimingAdapter { public RaceHandle addSwissTimingRace(TrackerManager trackerManager, RegattaIdentifier regattaToAddTo, String raceID, String raceName, String raceDescription, BoatClass boatClass, String hostname, int port, StartList startList, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, long timeoutInMilliseconds, - boolean useInternalMarkPassingAlgorithm, boolean trackWind, boolean correctWindDirectionByMagneticDeclination) throws Exception { + boolean useInternalMarkPassingAlgorithm, boolean trackWind, boolean correctWindDirectionByMagneticDeclination, + String updateURL, String updateUsername, String updatePassword) throws Exception { return trackerManager.addRace(regattaToAddTo, swissTimingDomainFactory.createTrackingConnectivityParameters(hostname, port, raceID, raceName, raceDescription, boatClass, startList, DEFAULT_SWISSTIMING_LIVE_DELAY_IN_MILLISECONDS, swissTimingFactory, swissTimingDomainFactory, raceLogStore, regattaLogStore, - useInternalMarkPassingAlgorithm, trackWind, correctWindDirectionByMagneticDeclination), + useInternalMarkPassingAlgorithm, trackWind, correctWindDirectionByMagneticDeclination, updateURL, updateUsername, updatePassword), timeoutInMilliseconds); } diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingFactoryImpl.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingFactoryImpl.java index 3ef6ea77427..70236e46404 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingFactoryImpl.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingFactoryImpl.java @@ -17,7 +17,6 @@ import com.sap.sailing.domain.swisstimingadapter.Race; import com.sap.sailing.domain.swisstimingadapter.SailMasterConnector; import com.sap.sailing.domain.swisstimingadapter.SailMasterMessage; import com.sap.sailing.domain.swisstimingadapter.SailMasterTransceiver; -import com.sap.sailing.domain.swisstimingadapter.StartList; import com.sap.sailing.domain.swisstimingadapter.SwissTimingArchiveConfiguration; import com.sap.sailing.domain.swisstimingadapter.SwissTimingConfiguration; import com.sap.sailing.domain.swisstimingadapter.SwissTimingFactory; @@ -83,32 +82,27 @@ public class SwissTimingFactoryImpl implements SwissTimingFactory { } @Override - public SwissTimingConfiguration createSwissTimingConfiguration(String name, String jsonURL, String hostname, Integer port, String updateURL, String updateUsername, String updatePassword) { + public SwissTimingConfiguration createSwissTimingConfiguration(String name, String jsonURL, String hostname, + Integer port, String updateURL, String updateUsername, String updatePassword) { return new SwissTimingConfigurationImpl(name, jsonURL, hostname, port, updateURL, updateUsername, updatePassword); } @Override - public SwissTimingRaceTracker createRaceTracker(String raceID, String raceName, String raceDescription, - BoatClass boatClass, String hostname, int port, StartList startList, long delayToLiveInMillis, - RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore, - boolean useInternalMarkPassingAlgorithm, DomainFactory domainFactory, - TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver, SwissTimingTrackingConnectivityParameters connectivityParams) + public SwissTimingRaceTracker createRaceTracker(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, + WindStore windStore, DomainFactory domainFactory, TrackedRegattaRegistry trackedRegattaRegistry, + RaceLogResolver raceLogResolver, SwissTimingTrackingConnectivityParameters connectivityParams) throws InterruptedException, UnknownHostException, IOException, ParseException { - return new SwissTimingRaceTrackerImpl(raceID, raceName, raceDescription, boatClass, hostname, port, startList, - raceLogStore, regattaLogStore, windStore, domainFactory, this, - trackedRegattaRegistry, raceLogResolver, delayToLiveInMillis, useInternalMarkPassingAlgorithm, connectivityParams); + return new SwissTimingRaceTrackerImpl(raceLogStore, regattaLogStore, windStore, domainFactory, this, + trackedRegattaRegistry, raceLogResolver, connectivityParams); } @Override - public RaceTracker createRaceTracker(Regatta regatta, String raceID, String raceName, String raceDescription, - BoatClass boatClass, String hostname, int port, StartList startList, long delayToLiveInMillis, - WindStore windStore, boolean useInternalMarkPassingAlgorithm, DomainFactory domainFactory, + public RaceTracker createRaceTracker(Regatta regatta, WindStore windStore, DomainFactory domainFactory, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, SwissTimingTrackingConnectivityParameters connectivityParams) throws UnknownHostException, InterruptedException, IOException, ParseException { - return new SwissTimingRaceTrackerImpl(regatta, raceID, raceName, raceDescription, boatClass, hostname, port, - startList, windStore, domainFactory, this, trackedRegattaRegistry, raceLogStore, regattaLogStore, - raceLogResolver, delayToLiveInMillis, useInternalMarkPassingAlgorithm, connectivityParams); + return new SwissTimingRaceTrackerImpl(regatta, windStore, domainFactory, this, trackedRegattaRegistry, + raceLogStore, regattaLogStore, raceLogResolver, connectivityParams); } @Override diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingRaceTrackerImpl.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingRaceTrackerImpl.java index e963f7c5033..8b960a35e78 100644 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingRaceTrackerImpl.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingRaceTrackerImpl.java @@ -3,6 +3,7 @@ package com.sap.sailing.domain.swisstimingadapter.impl; import java.io.IOException; import java.io.Serializable; import java.net.MalformedURLException; +import java.net.URISyntaxException; import java.net.UnknownHostException; import java.text.ParseException; import java.util.Collection; @@ -63,6 +64,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.UpdateHandler; import com.sap.sse.common.Distance; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; @@ -110,23 +112,30 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl private final TMDMessageQueue tmdMessageQueue; private final RaceLogResolver raceLogResolver; + + /** + * If set to a non-{@code null}, non-{@link String#isEmpty() empty} value, updates about start time changes, course + * changes, etc. will be sent as REST requests to this URL, using the {@link #updateUsername} / + * {@link #updatePassword} as credentials. + */ + private final String updateURL; + + private final String updateUsername; + + private final String updatePassword; - protected SwissTimingRaceTrackerImpl(String raceID, String raceName, String raceDescription, BoatClass boatClass, - String hostname, int port, StartList startList, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, + protected SwissTimingRaceTrackerImpl(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore, DomainFactory domainFactory, SwissTimingFactory factory, - TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver, long delayToLiveInMillis, - boolean useInternalMarkPassingAlgorithm, SwissTimingTrackingConnectivityParameters connectivityParams) throws InterruptedException, - UnknownHostException, IOException, ParseException { - this(/* regatta */ null, raceID, raceName, raceDescription, boatClass, hostname, port, startList, windStore, - domainFactory, factory, trackedRegattaRegistry, raceLogStore, regattaLogStore, raceLogResolver, - delayToLiveInMillis, useInternalMarkPassingAlgorithm, connectivityParams); + TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver, + SwissTimingTrackingConnectivityParameters connectivityParams) + throws InterruptedException, UnknownHostException, IOException, ParseException { + this(/* regatta */ null, windStore, domainFactory, factory, trackedRegattaRegistry, raceLogStore, regattaLogStore, raceLogResolver, connectivityParams); } - protected SwissTimingRaceTrackerImpl(Regatta regatta, String raceID, String raceName, String raceDescription, - BoatClass boatClass, String hostname, int port, StartList startList, WindStore windStore, - DomainFactory domainFactory, SwissTimingFactory factory, TrackedRegattaRegistry trackedRegattaRegistry, - RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, RaceLogResolver raceLogResolver, - long delayToLiveInMillis, boolean useInternalMarkPassingAlgorithm, SwissTimingTrackingConnectivityParameters connectivityParams) + protected SwissTimingRaceTrackerImpl(Regatta regatta, WindStore windStore, DomainFactory domainFactory, + SwissTimingFactory factory, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogStore raceLogStore, + RegattaLogStore regattaLogStore, RaceLogResolver raceLogResolver, + SwissTimingTrackingConnectivityParameters connectivityParams) throws InterruptedException, UnknownHostException, IOException, ParseException { super(connectivityParams); this.raceLogResolver = raceLogResolver; @@ -134,29 +143,33 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl final Regatta effectiveRegatta; // Try to find a pre-associated event based on the Race ID if (regatta == null) { - effectiveRegatta = trackedRegattaRegistry.getRememberedRegattaForRace(raceID); + effectiveRegatta = trackedRegattaRegistry.getRememberedRegattaForRace(connectivityParams.getRaceID()); } else { effectiveRegatta = regatta; } // if regatta is still null, no previous assignment of any of the races in this TracTrac event to a Regatta was // found; in this case, create a default regatta based on the TracTrac event data this.regatta = effectiveRegatta == null ? domainFactory.getOrCreateDefaultRegatta(raceLogStore, regattaLogStore, - raceID, boatClass, trackedRegattaRegistry) : effectiveRegatta; - this.connector = factory.getOrCreateSailMasterConnector(hostname, port, raceID, raceName, raceDescription, boatClass); + connectivityParams.getRaceID(), connectivityParams.getBoatClass(), trackedRegattaRegistry) : effectiveRegatta; + this.connector = factory.getOrCreateSailMasterConnector(connectivityParams.getHostname(), connectivityParams.getPort(), + connectivityParams.getRaceID(), connectivityParams.getRaceName(), connectivityParams.getRaceDescription(), connectivityParams.getBoatClass()); this.domainFactory = domainFactory; - this.raceID = raceID; - this.raceName = raceName; - this.startList = startList; - this.startListFromManage2Sail = startList != null; - this.raceDescription = raceDescription; - this.boatClass = boatClass; + this.raceID = connectivityParams.getRaceID(); + this.raceName = connectivityParams.getRaceName(); + this.startList = connectivityParams.getStartList(); + this.startListFromManage2Sail = connectivityParams.getStartList() != null; + this.raceDescription = connectivityParams.getRaceDescription(); + this.boatClass = connectivityParams.getBoatClass(); this.windStore = windStore; - this.id = createID(raceID, hostname, port); + this.id = createID(connectivityParams.getRaceID(), connectivityParams.getHostname(), connectivityParams.getPort()); connector.addSailMasterListener(this); trackedRegatta = trackedRegattaRegistry.getOrCreateTrackedRegatta(this.regatta); - this.delayToLiveInMillis = delayToLiveInMillis; + this.delayToLiveInMillis = connectivityParams.getDelayToLiveInMillis(); this.competitorsByBoatId = new HashMap(); - this.useInternalMarkPassingAlgorithm = useInternalMarkPassingAlgorithm; + this.useInternalMarkPassingAlgorithm = connectivityParams.isUseInternalMarkPassingAlgorithm(); + this.updateURL = connectivityParams.getUpdateURL(); + this.updateUsername = connectivityParams.getUpdateUsername(); + this.updatePassword = connectivityParams.getUpdatePassword(); } @Override @@ -406,7 +419,7 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl } @Override - public void receivedStartList(String raceID, StartList startList) { + public void receivedStartList(String raceID, StartList startList) throws URISyntaxException { // ignore STL messages if the startlist has been already provided by Manage2Sail if (!startListFromManage2Sail && this.raceID.equals(raceID)) { StartList oldStartList = this.startList; @@ -435,7 +448,7 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl } } - private void createRaceDefinition(Course course) { + private void createRaceDefinition(Course course) throws URISyntaxException { assert this.raceID.equals(raceID); assert startList != null; assert course != null; @@ -465,9 +478,20 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl } }, useInternalMarkPassingAlgorithm, raceLogResolver, /* Not needed because the RaceTracker is not active on a replica */ Optional.empty()); + addUpdateHandlers(); notifyRaceCreationListeners(); logger.info("Created SwissTiming RaceDefinition and TrackedRace for "+race.getName()); } + + /** + * If a non-{@code null}, non-{@link String#isEmpty() empty} {@link #updateURL} is set, adds {@link UpdateHandler}s + * to the race that will forward changes to the race such as start time changes or course changes to the URL as REST + * requests. + */ + private void addUpdateHandlers() throws URISyntaxException { + getDomainFactory().addUpdateHandlers(updateURL, updateUsername, updatePassword, + /* TODO using the regatta ID as the "eventId" for now... */ regatta.getId(), trackedRace.getRace(), trackedRace); + } /** * Checks if {@link #getRegatta()} still contains the {@link RaceDefinition} obtained when calling @@ -481,7 +505,7 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl } @Override - public void receivedCourseConfiguration(String raceID, Course course) { + public void receivedCourseConfiguration(String raceID, Course course) throws URISyntaxException { Course oldCourse = this.course; if (trackedRace == null) { if (oldCourse == null && startList != null) { diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingTrackingConnectivityParameters.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingTrackingConnectivityParameters.java index de24889e36e..e14df771fa1 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingTrackingConnectivityParameters.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingTrackingConnectivityParameters.java @@ -31,11 +31,15 @@ public class SwissTimingTrackingConnectivityParameters extends AbstractRaceTrack private final long delayToLiveInMillis; private final StartList startList; private final boolean useInternalMarkPassingAlgorithm; + private final String updateURL; + private final String updateUsername; + private final String updatePassword; public SwissTimingTrackingConnectivityParameters(String hostname, int port, String raceID, String raceName, String raceDescription, BoatClass boatClass, StartList startList, long delayToLiveInMillis, SwissTimingFactory swissTimingFactory, DomainFactory domainFactory, RaceLogStore raceLogStore, - RegattaLogStore regattaLogStore, boolean useInternalMarkPassingAlgorithm, boolean trackWind, boolean correctWindDirectionByMagneticDeclination) { + RegattaLogStore regattaLogStore, boolean useInternalMarkPassingAlgorithm, boolean trackWind, + boolean correctWindDirectionByMagneticDeclination, String updateURL, String updateUsername, String updatePassword) { super(trackWind, correctWindDirectionByMagneticDeclination); this.hostname = hostname; this.port = port; @@ -50,6 +54,9 @@ public class SwissTimingTrackingConnectivityParameters extends AbstractRaceTrack this.raceLogStore = raceLogStore; this.regattaLogStore = regattaLogStore; this.useInternalMarkPassingAlgorithm = useInternalMarkPassingAlgorithm; + this.updateURL = updateURL; + this.updateUsername = updateUsername; + this.updatePassword = updatePassword; } @Override @@ -60,18 +67,15 @@ public class SwissTimingTrackingConnectivityParameters extends AbstractRaceTrack @Override public RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore, RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds) throws Exception { - return swissTimingFactory.createRaceTracker(raceID, raceName, raceDescription, boatClass, hostname, port, - startList, delayToLiveInMillis, raceLogStore, regattaLogStore, windStore, - useInternalMarkPassingAlgorithm, - domainFactory, trackedRegattaRegistry, raceLogResolver, this); + return swissTimingFactory.createRaceTracker(raceLogStore, regattaLogStore, windStore, domainFactory, trackedRegattaRegistry, raceLogResolver, + this); } @Override public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore, RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds) throws Exception { - return swissTimingFactory.createRaceTracker(regatta, raceID, raceName, raceDescription, boatClass, hostname, - port, startList, delayToLiveInMillis, windStore, useInternalMarkPassingAlgorithm, - domainFactory, trackedRegattaRegistry, raceLogResolver, raceLogStore, regattaLogStore, this); + return swissTimingFactory.createRaceTracker(regatta, windStore, domainFactory, trackedRegattaRegistry, raceLogResolver, raceLogStore, + regattaLogStore, this); } @Override @@ -92,6 +96,18 @@ public class SwissTimingTrackingConnectivityParameters extends AbstractRaceTrack return port; } + public String getUpdateURL() { + return updateURL; + } + + public String getUpdateUsername() { + return updateUsername; + } + + public String getUpdatePassword() { + return updatePassword; + } + public String getRaceID() { return raceID; } diff --git a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/DomainFactoryImpl.java b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/DomainFactoryImpl.java index ed867cb4ed8..da49ca9a085 100755 --- a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/DomainFactoryImpl.java +++ b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/DomainFactoryImpl.java @@ -14,8 +14,8 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Map.Entry; +import java.util.Optional; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -680,17 +680,16 @@ public class DomainFactoryImpl implements DomainFactory { TracTracCourseDesignUpdateHandler courseDesignHandler = new TracTracCourseDesignUpdateHandler( tracTracUpdateURI, tracTracUsername, tracTracPassword, tracTracEventUuid, raceDefinition.getId(), tractracRace, this); - trackedRace.addCourseDesignChangedListener(courseDesignHandler); StartTimeUpdateHandler startTimeHandler = new StartTimeUpdateHandler( tracTracUpdateURI, tracTracUsername, tracTracPassword, tracTracEventUuid, raceDefinition.getId(), trackedRace.getTrackedRegatta().getRegatta()); - trackedRace.addStartTimeChangedListener(startTimeHandler); RaceAbortedHandler raceAbortedHandler = new RaceAbortedHandler( tracTracUpdateURI, tracTracUsername, tracTracPassword, tracTracEventUuid, raceDefinition.getId()); - trackedRace.addRaceAbortedListener(raceAbortedHandler); - trackedRace.addListener(new FinishTimeUpdateHandler(tracTracUpdateURI, tracTracUsername, tracTracPassword, tracTracEventUuid, - raceDefinition.getId(), trackedRace.getTrackedRegatta().getRegatta()).getListener()); + final FinishTimeUpdateHandler finishTimeUpdateHandler = new FinishTimeUpdateHandler(tracTracUpdateURI, tracTracUsername, tracTracPassword, tracTracEventUuid, + raceDefinition.getId(), trackedRace.getTrackedRegatta().getRegatta()); + baseDomainFactory.addUpdateHandlers(trackedRace, courseDesignHandler, startTimeHandler, raceAbortedHandler, + finishTimeUpdateHandler); } private DynamicTrackedRace createTrackedRace(TrackedRegatta trackedRegatta, RaceDefinition race, diff --git a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/RaceCourseReceiver.java b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/RaceCourseReceiver.java index bb816ebb05c..2efecd731d8 100755 --- a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/RaceCourseReceiver.java +++ b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/RaceCourseReceiver.java @@ -251,17 +251,19 @@ public class RaceCourseReceiver extends AbstractReceiverWithQueue sidelines, Consumer runAfterCreatingTrackedRace) { - DynamicTrackedRace trackedRace = getTrackedRegatta().createTrackedRace(race, sidelines, - windStore, delayToLiveInMillis, millisecondsOverWhichToAverageWind, - /* time over which to average speed: */ race.getBoatClass().getApproximateManeuverDurationInMilliseconds(), + private DynamicTrackedRace createTrackedRace(RaceDefinition race, Iterable sidelines, + Consumer runAfterCreatingTrackedRace) { + DynamicTrackedRace trackedRace = getTrackedRegatta().createTrackedRace(race, sidelines, windStore, + delayToLiveInMillis, millisecondsOverWhichToAverageWind, + /* time over which to average speed: */ race.getBoatClass() + .getApproximateManeuverDurationInMilliseconds(), raceDefinitionSetToUpdate, useInternalMarkPassingAlgorithm, raceLogResolver, /* Not needed because the RaceTracker is not active on a replica */ Optional.empty()); if (runAfterCreatingTrackedRace != null) { - runAfterCreatingTrackedRace.accept(trackedRace); + runAfterCreatingTrackedRace.accept(trackedRace); } - getDomainFactory().addTracTracUpdateHandlers(tracTracUpdateURI, getTracTracEvent().getId(), tracTracUsername, tracTracPassword, race, trackedRace, - tractracRace); + getDomainFactory().addTracTracUpdateHandlers(tracTracUpdateURI, getTracTracEvent().getId(), tracTracUsername, + tracTracPassword, race, trackedRace, tractracRace); return trackedRace; } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/DomainFactory.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/DomainFactory.java index b81e8e1b1ff..be6b6a144c7 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/DomainFactory.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/DomainFactory.java @@ -21,9 +21,14 @@ import com.sap.sailing.domain.common.dto.TrackedRaceStatisticsDTO; import com.sap.sailing.domain.common.media.MediaTrack; import com.sap.sailing.domain.leaderboard.Leaderboard; import com.sap.sailing.domain.leaderboard.ScoringScheme; +import com.sap.sailing.domain.tracking.DynamicTrackedRace; import com.sap.sailing.domain.tracking.MarkPassing; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.TrackedRegattaRegistry; +import com.sap.sailing.domain.tracking.impl.CourseDesignUpdateHandler; +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.sse.common.IsManagedByCache; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util.Pair; @@ -101,4 +106,11 @@ public interface DomainFactory extends SharedDomainFactory { */ void updateRaceDTOWithTrackedRaceData(TrackedRace trackedRace, RaceDTO raceDTO); + /** + * Adds update handlers to a {@link TrackedRace} which can send updates to a REST service about race status + * changes such as a start time change, a course change, or a postponement. + */ + void addUpdateHandlers(DynamicTrackedRace trackedRace, CourseDesignUpdateHandler courseDesignHandler, + StartTimeUpdateHandler startTimeHandler, RaceAbortedHandler raceAbortedHandler, + final FinishTimeUpdateHandler finishTimeUpdateHandler); } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java index 1185b0861b4..9dfb3feed1e 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java @@ -64,11 +64,16 @@ import com.sap.sailing.domain.leaderboard.impl.LowPointTieBreakBasedOnLastSeries import com.sap.sailing.domain.leaderboard.impl.LowPointWinnerGetsZero; import com.sap.sailing.domain.leaderboard.impl.LowPointWithAutomaticRDG; import com.sap.sailing.domain.leaderboard.impl.LowPointWithEliminationsAndRoundsWinnerGets07; +import com.sap.sailing.domain.tracking.DynamicTrackedRace; import com.sap.sailing.domain.tracking.GPSFixTrack; import com.sap.sailing.domain.tracking.MarkPassing; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.TrackedRegattaRegistry; +import com.sap.sailing.domain.tracking.impl.CourseDesignUpdateHandler; +import com.sap.sailing.domain.tracking.impl.FinishTimeUpdateHandler; import com.sap.sailing.domain.tracking.impl.MarkPassingImpl; +import com.sap.sailing.domain.tracking.impl.RaceAbortedHandler; +import com.sap.sailing.domain.tracking.impl.StartTimeUpdateHandler; import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl; import com.sap.sailing.geocoding.ReverseGeocoder; import com.sap.sse.common.Distance; @@ -394,6 +399,7 @@ public class DomainFactoryImpl extends SharedDomainFactoryImpl implements Domain return result; } + @Override public List getCompetitorDTOList(List> competitors) { List result = new ArrayList<>(); for (Pair competitorAndBoat : competitors) { @@ -401,4 +407,14 @@ public class DomainFactoryImpl extends SharedDomainFactoryImpl implements Domain } return result; } + + @Override + public void addUpdateHandlers(DynamicTrackedRace trackedRace, CourseDesignUpdateHandler courseDesignHandler, + StartTimeUpdateHandler startTimeHandler, RaceAbortedHandler raceAbortedHandler, + final FinishTimeUpdateHandler finishTimeUpdateHandler) { + trackedRace.addCourseDesignChangedListener(courseDesignHandler); + trackedRace.addStartTimeChangedListener(startTimeHandler); + trackedRace.addRaceAbortedListener(raceAbortedHandler); + trackedRace.addListener(finishTimeUpdateHandler.getListener()); + } } diff --git a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/SailingServiceImplMock.java b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/SailingServiceImplMock.java index af633c042ae..74bfa2b601f 100755 --- a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/SailingServiceImplMock.java +++ b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/SailingServiceImplMock.java @@ -75,7 +75,7 @@ public class SailingServiceImplMock extends SailingServiceImpl { public RaceHandle addSwissTimingRace(TrackerManager trackerManager, RegattaIdentifier regattaToAddTo, String raceID, String raceName, String raceDescription, BoatClass boatClass, String hostname, int port, StartList startList, RaceLogStore logStore, - RegattaLogStore regattaLogStore, long timeoutInMilliseconds, boolean useInternalMarkPassingAlgorithm, boolean trackWind, boolean correctWindDirectionByMagneticDeclination) throws InterruptedException, + RegattaLogStore regattaLogStore, long timeoutInMilliseconds, boolean useInternalMarkPassingAlgorithm, boolean trackWind, boolean correctWindDirectionByMagneticDeclination, String updateURL, String updateUsername, String updatePassword) throws InterruptedException, UnknownHostException, IOException, ParseException, Exception { // TODO Auto-generated method stub return null; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SwissTimingEventManagementPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SwissTimingEventManagementPanel.java index b0a2ed089f1..64888dcee32 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SwissTimingEventManagementPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SwissTimingEventManagementPanel.java @@ -518,8 +518,11 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane } private void trackSelectedRaces(boolean trackWind, boolean correctWindByDeclination, boolean useInternalMarkPassingAlgorithm) { - String hostname = hostnameTextbox.getValue(); - Integer port = portIntegerbox.getValue(); + final String hostname = hostnameTextbox.getValue(); + final Integer port = portIntegerbox.getValue(); + final String updateURL = updateURLBox.getValue(); + final String updateUsername = updateUsernameBox.getValue(); + final String updatePassword = updatePasswordBox.getValue(); final List selectedRaces = new ArrayList(); for (final SwissTimingRaceRecordDTO race : this.raceList.getList()) { if (raceTable.getSelectionModel().isSelected(race)) { @@ -537,7 +540,7 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane sailingService.trackWithSwissTiming( /* regattaToAddTo */ regattaIdentifier, selectedRaces, hostname, port, trackWind, correctWindByDeclination, - useInternalMarkPassingAlgorithm, new AsyncCallback() { + useInternalMarkPassingAlgorithm, updateURL, updateUsername, updatePassword, new AsyncCallback() { @Override public void onFailure(Throwable caught) { errorReporter.reportError("Error trying to register races " + selectedRaces + " for tracking: " diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java index 85f26f24ce0..2c5f82f5dec 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java @@ -145,8 +145,9 @@ public interface SailingService extends RemoteService, FileStorageManagementGwtS String storedURI, String courseDesignUpdateURI, boolean trackWind, boolean correctWindByDeclination, Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, String tracTracUsername, String tracTracPassword) throws Exception; - void trackWithSwissTiming(RegattaIdentifier regattaToAddTo, Iterable rrs, String hostname, int port, - boolean trackWind, boolean correctWindByDeclination, boolean useInternalMarkPassingAlgorithm) throws Exception; + void trackWithSwissTiming(RegattaIdentifier regattaToAddTo, Iterable rrs, String hostname, + int port, boolean trackWind, boolean correctWindByDeclination, boolean useInternalMarkPassingAlgorithm, + String updateURL, String updateUsername, String updatePassword) throws Exception; void replaySwissTimingRace(RegattaIdentifier regattaIdentifier, Iterable replayRaces, boolean trackWind, boolean correctWindByDeclination, boolean useInternalMarkPassingAlgorithm); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java index db0ff1adb60..9ae833c78f8 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java @@ -162,7 +162,7 @@ public interface SailingServiceAsync extends ServerInfoRetriever, FileStorageMan void trackWithSwissTiming(RegattaIdentifier regattaToAddTo, Iterable rrs, String hostname, int port, boolean trackWind, boolean correctWindByDeclination, - boolean useInternalMarkPassingAlgorithm, AsyncCallback asyncCallback); + boolean useInternalMarkPassingAlgorithm, String updateURL, String updateUsername, String updatePassword, AsyncCallback asyncCallback); void replaySwissTimingRace(RegattaIdentifier regattaIdentifier, Iterable replayRaces, boolean trackWind, boolean correctWindByDeclination, boolean useInternalMarkPassingAlgorithm, diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index e7d1a59a8f7..a9023abb1a5 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -2887,7 +2887,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S @Override public void trackWithSwissTiming(RegattaIdentifier regattaToAddTo, Iterable rrs, String hostname, int port, - boolean trackWind, final boolean correctWindByDeclination, boolean useInternalMarkPassingAlgorithm) throws Exception { + boolean trackWind, final boolean correctWindByDeclination, boolean useInternalMarkPassingAlgorithm, + String updateURL, String updateUsername, String updatePassword) throws InterruptedException, ParseException, Exception { logger.info("tracWithSwissTiming for regatta " + regattaToAddTo + " for race records " + rrs + " with hostname " + hostname + " and port " + port); Map cachedRegattaEntriesLists = new HashMap(); @@ -2912,7 +2913,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S getSwissTimingAdapter().addSwissTimingRace(getService(), regattaToAddTo, rr.raceId, rr.getName(), raceDescription, boatClass, hostname, port, startList, getRaceLogStore(), getRegattaLogStore(), - RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS, useInternalMarkPassingAlgorithm, trackWind, correctWindByDeclination); + RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS, useInternalMarkPassingAlgorithm, trackWind, + correctWindByDeclination, updateURL, updateUsername, updatePassword); } } diff --git a/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/SwissTimingConnectivityParamsLoadAndStoreTest.java b/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/SwissTimingConnectivityParamsLoadAndStoreTest.java index 9200abde2d4..bb521d61c82 100644 --- a/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/SwissTimingConnectivityParamsLoadAndStoreTest.java +++ b/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/SwissTimingConnectivityParamsLoadAndStoreTest.java @@ -53,7 +53,8 @@ public class SwissTimingConnectivityParamsLoadAndStoreTest extends AbstractConne final SwissTimingTrackingConnectivityParameters stParams = new SwissTimingTrackingConnectivityParameters( hostname, port, raceID, raceName, raceDescription, boatClass, startList, delayToLiveInMillis, SwissTimingFactory.INSTANCE, new SwissTimingAdapterFactoryImpl().getOrCreateSwissTimingAdapter(domainObjectFactory.getBaseDomainFactory()).getSwissTimingDomainFactory(), - /* raceLogStore */ null, /* regattaLogStore */ null, useInternalMarkPassingAlgorithm, trackWind, correctWindDirectionByMagneticDeclination); + /* raceLogStore */ null, /* regattaLogStore */ null, useInternalMarkPassingAlgorithm, trackWind, correctWindDirectionByMagneticDeclination, + /* updateURL */ null, /* updateUsername */ null, /* updatePassword */ null); // store mongoObjectFactory.addConnectivityParametersForRaceToRestore(stParams); // load @@ -103,7 +104,8 @@ public class SwissTimingConnectivityParamsLoadAndStoreTest extends AbstractConne final SwissTimingTrackingConnectivityParameters stParams = new SwissTimingTrackingConnectivityParameters( hostname, port, raceID, raceName, raceDescription, boatClass, startList, delayToLiveInMillis, SwissTimingFactory.INSTANCE, new SwissTimingAdapterFactoryImpl().getOrCreateSwissTimingAdapter(domainObjectFactory.getBaseDomainFactory()).getSwissTimingDomainFactory(), - /* raceLogStore */ null, /* regattaLogStore */ null, useInternalMarkPassingAlgorithm, trackWind, correctWindDirectionByMagneticDeclination); + /* raceLogStore */ null, /* regattaLogStore */ null, useInternalMarkPassingAlgorithm, trackWind, correctWindDirectionByMagneticDeclination, + /* updateURL */ null, /* updateUsername */ null, /* updatePassword */ null); // store mongoObjectFactory.addConnectivityParametersForRaceToRestore(stParams); // load From 297066ea9ef79d68d11347c471a8e69407e06af2 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 3 Aug 2018 10:49:12 +0200 Subject: [PATCH 17/53] removed extra comments Change-Id: Ib8197a8258041adf10025b52d9ff63b127ae7df5 --- .../domain/swisstimingadapter/SwissTimingAdapter.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingAdapter.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingAdapter.java index 36c79299bfd..bcb05fe84c4 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingAdapter.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingAdapter.java @@ -26,11 +26,6 @@ public interface SwissTimingAdapter { * is specified, a regatta lookup is performed with that identifier; if the regatta is found, it is used * to add the races to. Otherwise, a default regatta as described above will be created and used. * @param useInternalMarkPassingAlgorithm use our own instead of the SwissTiming-provided mark passing / split times - * @param trackWind TODO - * @param correctWindDirectionByMagneticDeclination TODO - * @param updateURL TODO - * @param updateUsername TODO - * @param updatePassword TODO */ RaceHandle addSwissTimingRace(TrackerManager trackerManager, RegattaIdentifier regattaToAddTo, String raceID, String raceName, String raceDescription, BoatClass boatClass, String hostname, int port, From 66c5fbf71bb74a6a383e7293df2bd4571462ba3b Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 3 Aug 2018 11:23:15 +0200 Subject: [PATCH 18/53] added null-safety for unknown nationalities; added smarter selection of list entries of known SwissTiming configurations Change-Id: I98717e130aa686ebca306d6c02c1a573a9896d2b --- .../swisstimingadapter/impl/SwissTimingAdapterImpl.java | 4 ++-- .../ui/adminconsole/SwissTimingEventManagementPanel.java | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingAdapterImpl.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingAdapterImpl.java index ac1d291a4d8..a7978a8d466 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingAdapterImpl.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingAdapterImpl.java @@ -119,9 +119,9 @@ public class SwissTimingAdapterImpl implements SwissTimingAdapter { Person person = persons.get(crewMember.getPersonID()); crew.add(new CrewMemberImpl( person.getGivenName() + " " + person.getFamilyName(), - person.getNOC().name(), crewMember.getPosition().name())); + (person.getNOC()==null)?null:(person.getNOC().name()), crewMember.getPosition().name())); } - String nationality = team.getNOC().name(); + String nationality = team.getNOC()==null?null:team.getNOC().name(); CompetitorWithID competitor = new CompetitorWithID(team.getTeamID(), boat.getSailNumber(), nationality, team.getTeamName(), crew); competitors.add(competitor); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SwissTimingEventManagementPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SwissTimingEventManagementPanel.java index 64888dcee32..8f4fd9b38d0 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SwissTimingEventManagementPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SwissTimingEventManagementPanel.java @@ -510,6 +510,12 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane if (previousConfigurations.put(stConfig.getName(), stConfig) == null) { previousConfigurationsComboBox.addItem(stConfig.getName()); } + for (int i=0; i Date: Fri, 3 Aug 2018 11:31:59 +0200 Subject: [PATCH 19/53] bug4700: carrying through finishedTime so AutoplayHelper can evaluate it for live check Change-Id: I6ed7da5579dc43749c26eae5774c34e0769f26d9 --- .../GWT Dashboards DevMode.launch | 88 +++++++++--------- .../GWT Dashboards SDM.launch | 90 +++++++++---------- .../domain/common/dto/BasicRaceDTO.java | 1 + .../domain/base/impl/DomainFactoryImpl.java | 1 + .../autoplay/client/utils/AutoplayHelper.java | 7 +- .../TrackedRacesManagementPanel.java | 35 +++++--- .../gwt/ui/server/SailingServiceImpl.java | 1 + .../gwt/ui/shared/RaceTimesInfoDTO.java | 7 +- 8 files changed, 122 insertions(+), 108 deletions(-) diff --git a/java/com.sap.sailing.dashboards.gwt/GWT Dashboards DevMode.launch b/java/com.sap.sailing.dashboards.gwt/GWT Dashboards DevMode.launch index ee3af9f92cb..7310aa92bc6 100644 --- a/java/com.sap.sailing.dashboards.gwt/GWT Dashboards DevMode.launch +++ b/java/com.sap.sailing.dashboards.gwt/GWT Dashboards DevMode.launch @@ -1,47 +1,47 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/com.sap.sailing.dashboards.gwt/GWT Dashboards SDM.launch b/java/com.sap.sailing.dashboards.gwt/GWT Dashboards SDM.launch index 2ba728716bc..c5fc2f809c2 100644 --- a/java/com.sap.sailing.dashboards.gwt/GWT Dashboards SDM.launch +++ b/java/com.sap.sailing.dashboards.gwt/GWT Dashboards SDM.launch @@ -1,48 +1,48 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/BasicRaceDTO.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/BasicRaceDTO.java index 0af8c31849b..3b8053ea0b5 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/BasicRaceDTO.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/BasicRaceDTO.java @@ -18,6 +18,7 @@ public class BasicRaceDTO extends NamedDTO { public Date startOfRace; public Date endOfRace; + public Date raceFinishedTime; public TrackedRaceDTO trackedRace; public BasicRaceDTO() {} // for GWT serialization only diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java index 01e73aeacfe..67a9bf0ad6f 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java @@ -201,6 +201,7 @@ public class DomainFactoryImpl extends SharedDomainFactoryImpl implements Domain assert trackedRace != null; raceDTO.startOfRace = trackedRace.getStartOfRace() == null ? null : trackedRace.getStartOfRace().asDate(); raceDTO.endOfRace = trackedRace.getEndOfRace() == null ? null : trackedRace.getEndOfRace().asDate(); + raceDTO.raceFinishedTime = trackedRace.getFinishedTime() == null ? null : trackedRace.getFinishedTime().asDate(); raceDTO.status = new RaceStatusDTO(); raceDTO.status.status = trackedRace.getStatus() == null ? null : trackedRace.getStatus().getStatus(); raceDTO.status.loadingProgress = trackedRace.getStatus() == null ? 0.0 : trackedRace.getStatus().getLoadingProgress(); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/utils/AutoplayHelper.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/utils/AutoplayHelper.java index b03b79dc71f..b24e97e74af 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/utils/AutoplayHelper.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/utils/AutoplayHelper.java @@ -137,12 +137,11 @@ public class AutoplayHelper { RaceTimesInfoDTO raceTimes = raceTimesInfos.get(raceIdentifier); boolean notNullInRequiredValues = raceTimes != null && raceTimes.startOfTracking != null && raceTimes.getStartOfRace() != null; - - boolean raceHasNotEndedOrOnlyRecentlyEnded = raceTimes.endOfRace == null + Date endTime = raceTimes.getFinishedTime() != null ? raceTimes.getFinishedTime() : raceTimes.getEndOfRace(); + boolean raceHasNotEndedOrOnlyRecentlyEnded = endTime == null || serverTimeDuringRequest.getTime() - - raceTimes.delayToLiveInMs < raceTimes.endOfRace.getTime() + - raceTimes.delayToLiveInMs < endTime.getTime() + waitTimeAfterRaceEndInMillis; - if (notNullInRequiredValues && raceHasNotEndedOrOnlyRecentlyEnded) { long startTimeInMs = raceTimes.getStartOfRace().getTime(); long startIn = startTimeInMs - serverTimeDuringRequest.getTime() - raceTimes.delayToLiveInMs; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TrackedRacesManagementPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TrackedRacesManagementPanel.java index 1432949153e..948e6a92c71 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TrackedRacesManagementPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TrackedRacesManagementPanel.java @@ -66,10 +66,11 @@ public class TrackedRacesManagementPanel extends AbstractRaceManagementPanel { raceDataGrid.setText(0, 0, stringMessages.startTime()+":"); raceDataGrid.setText(1, 0, stringMessages.endTime()+":"); - raceDataGrid.setText(2, 0, stringMessages.duration()+":"); - raceDataGrid.setText(3, 0, stringMessages.startOfTracking()+":"); - raceDataGrid.setText(4, 0, stringMessages.endOfTracking()+":"); - raceDataGrid.setText(5, 0, stringMessages.delayForLiveMode()+" (ms):"); + raceDataGrid.setText(2, 0, stringMessages.finishingTime()+":"); + raceDataGrid.setText(3, 0, stringMessages.duration()+":"); + raceDataGrid.setText(4, 0, stringMessages.startOfTracking()+":"); + raceDataGrid.setText(5, 0, stringMessages.endOfTracking()+":"); + raceDataGrid.setText(6, 0, stringMessages.delayForLiveMode()+" (ms):"); } @Override @@ -87,26 +88,32 @@ public class TrackedRacesManagementPanel extends AbstractRaceManagementPanel { } else { raceDataGrid.setText(1, 1, ""); } - if(selectedRaceDTO.startOfRace != null && selectedRaceDTO.endOfRace != null) { - Date duration = new Date(selectedRaceDTO.endOfRace.getTime() - selectedRaceDTO.startOfRace.getTime()); - raceDataGrid.setText(2, 1, durationFormatter.render(duration)); + if (selectedRaceDTO.raceFinishedTime != null) { + raceDataGrid.setText(2, 1, dateFormatter.render(selectedRaceDTO.raceFinishedTime) + " " + + timeFormatter.render(selectedRaceDTO.raceFinishedTime)); } else { raceDataGrid.setText(2, 1, ""); } - if (selectedRaceDTO.trackedRace != null && selectedRaceDTO.trackedRace.startOfTracking != null) { - raceDataGrid.setText(3, 1, dateFormatter.render(selectedRaceDTO.trackedRace.startOfTracking) + " " - + timeFormatter.render(selectedRaceDTO.trackedRace.startOfTracking)); + if(selectedRaceDTO.startOfRace != null && selectedRaceDTO.endOfRace != null) { + Date duration = new Date(selectedRaceDTO.endOfRace.getTime() - selectedRaceDTO.startOfRace.getTime()); + raceDataGrid.setText(3, 1, durationFormatter.render(duration)); } else { raceDataGrid.setText(3, 1, ""); } - if (selectedRaceDTO.trackedRace != null && selectedRaceDTO.trackedRace.endOfTracking != null) { - raceDataGrid.setText(4, 1, dateFormatter.render(selectedRaceDTO.trackedRace.endOfTracking) + " " - + timeFormatter.render(selectedRaceDTO.trackedRace.endOfTracking)); + if (selectedRaceDTO.trackedRace != null && selectedRaceDTO.trackedRace.startOfTracking != null) { + raceDataGrid.setText(4, 1, dateFormatter.render(selectedRaceDTO.trackedRace.startOfTracking) + " " + + timeFormatter.render(selectedRaceDTO.trackedRace.startOfTracking)); } else { raceDataGrid.setText(4, 1, ""); } + if (selectedRaceDTO.trackedRace != null && selectedRaceDTO.trackedRace.endOfTracking != null) { + raceDataGrid.setText(5, 1, dateFormatter.render(selectedRaceDTO.trackedRace.endOfTracking) + " " + + timeFormatter.render(selectedRaceDTO.trackedRace.endOfTracking)); + } else { + raceDataGrid.setText(5, 1, ""); + } if (selectedRaceDTO.trackedRace != null) { - raceDataGrid.setText(5, 1, "" + selectedRaceDTO.trackedRace.delayToLiveInMs); + raceDataGrid.setText(6, 1, "" + selectedRaceDTO.trackedRace.delayToLiveInMs); } } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index 09393c99366..838cd676fb0 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -2075,6 +2075,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S raceTimesInfo.newestTrackingEvent = trackedRace.getTimePointOfNewestEvent() == null ? null : trackedRace.getTimePointOfNewestEvent().asDate(); raceTimesInfo.endOfTracking = trackedRace.getEndOfTracking() == null ? null : trackedRace.getEndOfTracking().asDate(); raceTimesInfo.endOfRace = trackedRace.getEndOfRace() == null ? null : trackedRace.getEndOfRace().asDate(); + raceTimesInfo.raceFinishedTime = trackedRace.getFinishedTime() == null ? null : trackedRace.getFinishedTime().asDate(); raceTimesInfo.delayToLiveInMs = trackedRace.getDelayToLiveInMillis(); Iterable>> markPassingsTimes = trackedRace.getMarkPassingsTimes(); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/RaceTimesInfoDTO.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/RaceTimesInfoDTO.java index 8926b48cdd5..eab41710b60 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/RaceTimesInfoDTO.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/RaceTimesInfoDTO.java @@ -19,6 +19,7 @@ public class RaceTimesInfoDTO implements IsSerializable { public Date startOfTracking; public Date endOfTracking; public Date endOfRace; + public Date raceFinishedTime; public Date newestTrackingEvent; /** @@ -83,6 +84,10 @@ public class RaceTimesInfoDTO implements IsSerializable { public Date getEndOfRace() { return endOfRace; } + + public Date getFinishedTime() { + return raceFinishedTime; + } public void setEndOfRace(Date endOfRace) { this.endOfRace = endOfRace; @@ -118,7 +123,7 @@ public class RaceTimesInfoDTO implements IsSerializable { + ", legInfos=" + legInfos + ", markPassingTimes=" + markPassingTimes + ", startOfRace=" + startOfRace + ", startOfTracking=" + startOfTracking + ", endOfTracking=" - + endOfTracking + ", endOfRace=" + endOfRace + + endOfTracking + ", endOfRace=" + endOfRace + ", finishedTime=" + raceFinishedTime + ", newestTrackingEvent=" + newestTrackingEvent + ", currentServerTime=" + currentServerTime + ", delayToLiveInMs=" + delayToLiveInMs + "]"; From 07d978f055b392dbf6ed4e622c398d28c1fbe989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Fri, 3 Aug 2018 16:26:44 +0200 Subject: [PATCH 20/53] bug4700 extended grid to fit new row --- .../gwt/ui/adminconsole/TrackedRacesManagementPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TrackedRacesManagementPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TrackedRacesManagementPanel.java index 948e6a92c71..d7c70fc7ed6 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TrackedRacesManagementPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TrackedRacesManagementPanel.java @@ -61,7 +61,7 @@ public class TrackedRacesManagementPanel extends AbstractRaceManagementPanel { controlsPanel.add(setStartTimeButton); selectedRaceContentPanel.add(controlsPanel); - raceDataGrid = new Grid(6,2); + raceDataGrid = new Grid(7, 2); this.selectedRaceContentPanel.add(raceDataGrid); raceDataGrid.setText(0, 0, stringMessages.startTime()+":"); From 9abfac30b139b0d1c349e5ba82d3423edc4856da Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Sat, 4 Aug 2018 00:39:10 +0200 Subject: [PATCH 21/53] bug 4702: adding boat column presence to the setting to copy for a MultiRaceLeaderboard Change-Id: I9578174713288ba61b745c98f25720629d4aee9f --- .../client/leaderboard/MultiRaceLeaderboardSettings.java | 1 + 1 file changed, 1 insertion(+) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/MultiRaceLeaderboardSettings.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/MultiRaceLeaderboardSettings.java index e166d36801b..74232f6c701 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/MultiRaceLeaderboardSettings.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/MultiRaceLeaderboardSettings.java @@ -63,6 +63,7 @@ public class MultiRaceLeaderboardSettings extends LeaderboardSettings { newSettings.showAddedScores.setValue(this.isShowAddedScores()); newSettings.showCompetitorShortNameColumn.setValue(this.isShowCompetitorShortNameColumn()); newSettings.showCompetitorFullNameColumn.setValue(this.isShowCompetitorFullNameColumn()); + newSettings.showCompetitorBoatInfoColumn.setValue(this.isShowCompetitorBoatInfoColumn()); newSettings.isShowCompetitorNationality.setValue(this.isShowCompetitorNationality()); newSettings.namesOfRaceColumnsToShow.setValues(this.getNamesOfRaceColumnsToShow()); newSettings.namesOfRaceColumnsToShow.setDefaultValues(namesOfRaceColumns); From 3b516bcbc3af9e8cd5295c19b51c88f87d942d95 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Sun, 5 Aug 2018 15:35:57 +0200 Subject: [PATCH 22/53] bug4704: introducing a ReadonlyRaceState cache based on weak identity hash map over RaceLog and RaceLogResolver Change-Id: I33412e6ed72ff732333e4a3ce1be8fc3906a57e5 --- .../race/state/impl/RaceStateImpl.java | 4 --- .../state/impl/ReadonlyRaceStateImpl.java | 34 +++++++++++++++++-- .../impl/DynamicTrackedRaceLogListener.java | 2 +- .../domain/tracking/impl/TrackedRaceImpl.java | 4 +-- .../sailing/gwt/home/server/RaceContext.java | 2 +- .../gwt/ui/server/SailingServiceImpl.java | 2 +- .../impl/RaceStateSerializer.java | 2 +- .../server/impl/RacingEventServiceImpl.java | 4 +-- .../META-INF/MANIFEST.MF | 1 + .../com/sap/sse/util/WeakIdentityHashMap.java | 0 .../sap/sse/util/WeakReferenceWithKey.java | 0 .../src/com/sap/sse/util/WeakValueCache.java | 0 12 files changed, 41 insertions(+), 14 deletions(-) rename java/{com.sap.sse => com.sap.sse.shared.android}/src/com/sap/sse/util/WeakIdentityHashMap.java (100%) rename java/{com.sap.sse => com.sap.sse.shared.android}/src/com/sap/sse/util/WeakReferenceWithKey.java (100%) rename java/{com.sap.sse => com.sap.sse.shared.android}/src/com/sap/sse/util/WeakValueCache.java (100%) diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/RaceStateImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/RaceStateImpl.java index a20fc0ad4ea..6f310aeda6c 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/RaceStateImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/RaceStateImpl.java @@ -55,10 +55,6 @@ public class RaceStateImpl extends ReadonlyRaceStateImpl implements RaceState { private final AbstractLogEventAuthor author; - public static ReadonlyRaceState create(RaceLogResolver raceLogResolver, RaceLog raceLog) { - return create(raceLogResolver, raceLog, /* forRaceLogIdentifier */ null, Collections.emptyMap()); - } - /** * Creates a {@link RaceState} with the initial racing procedure type set to a fallback value and an empty configuration. */ diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java index 67d7140fbf9..4904be72af4 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java @@ -44,6 +44,7 @@ import com.sap.sailing.domain.common.racelog.RacingProcedureType; import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimeRange; import com.sap.sse.common.Util; +import com.sap.sse.util.WeakIdentityHashMap; /** * Implementation of {@link ReadonlyRaceState}. Use the static factory methods to instantiate your race state. @@ -55,8 +56,37 @@ import com.sap.sse.common.Util; * See {@link ReadonlyRaceStateImpl#update()} for the core of the algorithm. */ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedListener { - - public static ReadonlyRaceState create(RaceLogResolver raceLogResolver, RaceLog raceLog) { + private static final WeakIdentityHashMap> raceStateCache = + new WeakIdentityHashMap<>(); + + /** + * Obtains a race state for the combination of {@code raceLog} and {@code raceLogResolver}. The result is + * cache using weak references to the race log and the race log resolver for quick retrieval upon equal + * requests, saving memory, saving listeners and thereby avoiding more synchronization issues. + * + * See also bug4704. + */ + public static ReadonlyRaceState getOrCreate(RaceLogResolver raceLogResolver, RaceLog raceLog) { + WeakIdentityHashMap raceStatesForRaceLog; + ReadonlyRaceState result = null; + synchronized (raceStateCache) { + raceStatesForRaceLog = raceStateCache.get(raceLog); + if (raceStatesForRaceLog == null) { + raceStatesForRaceLog = new WeakIdentityHashMap<>(); + raceStateCache.put(raceLog, raceStatesForRaceLog); + } else { + result = raceStatesForRaceLog.get(raceLogResolver); + } + if (result == null) { + result = createInternal(raceLogResolver, raceLog); + raceStatesForRaceLog.put(raceLogResolver, result); + } + } + return result; + } + + + private static final ReadonlyRaceState createInternal(RaceLogResolver raceLogResolver, RaceLog raceLog) { return create(raceLogResolver, raceLog, /* forRaceLogIdentifier */null, Collections. emptyMap()); } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java index aaa83b444ec..bcc66c88fa7 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java @@ -79,7 +79,7 @@ public class DynamicTrackedRaceLogListener extends BaseRaceLogEventVisitor { logger.severe("Trying to add " + this + " as listener to a null race log for tracked race " + trackedRace.getRace()); } else { raceLog.addListener(this); - final ReadonlyRaceState raceState = ReadonlyRaceStateImpl.create(trackedRace.getRaceLogResolver(), raceLog); + final ReadonlyRaceState raceState = ReadonlyRaceStateImpl.getOrCreate(trackedRace.getRaceLogResolver(), raceLog); raceLogs.put(raceLog, raceState); raceState.addChangedListener(new BaseRaceStateChangedListener() { @Override diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java index 2760bf877ca..86501ccd376 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java @@ -50,7 +50,7 @@ import com.sap.sailing.domain.abstractlog.race.analyzing.impl.TrackingTimesFinde import com.sap.sailing.domain.abstractlog.race.impl.RaceLogGateLineOpeningTimeEventImpl; import com.sap.sailing.domain.abstractlog.race.state.RaceState; import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState; -import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateImpl; +import com.sap.sailing.domain.abstractlog.race.state.impl.ReadonlyRaceStateImpl; import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.ReadonlyRacingProcedure; import com.sap.sailing.domain.abstractlog.regatta.RegattaLog; import com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl.RegattaLogDefinedMarkAnalyzer; @@ -2975,7 +2975,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl synchronized (raceStates) { result = raceStates.get(raceLog); if (result == null) { - result = RaceStateImpl.create(raceLogResolver, raceLog); + result = ReadonlyRaceStateImpl.getOrCreate(raceLogResolver, raceLog); raceStates.put(raceLog, result); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/server/RaceContext.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/server/RaceContext.java index 0cda630cbc8..2e313562472 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/server/RaceContext.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/server/RaceContext.java @@ -104,7 +104,7 @@ public class RaceContext { this.fleet = fleet; trackedRace = raceColumn.getTrackedRace(fleet); raceLog = raceColumn.getRaceLog(fleet); - state = (raceLog == null) ? null : ReadonlyRaceStateImpl.create(raceLogResolver, raceLog); + state = (raceLog == null) ? null : ReadonlyRaceStateImpl.getOrCreate(raceLogResolver, raceLog); } private boolean isShowFleetData() { diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index 5fcc97c8fa3..4d63abbae4c 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -1047,7 +1047,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S final TrackedRace trackedRace = raceColumn.getTrackedRace(fleet); raceInfoDTO.isTracked = trackedRace != null ? true : false; if (raceLog != null) { - ReadonlyRaceState state = ReadonlyRaceStateImpl.create(getService(), raceLog); + ReadonlyRaceState state = ReadonlyRaceStateImpl.getOrCreate(getService(), raceLog); TimePoint startTime = state.getStartTime(); if (startTime != null) { raceInfoDTO.startTime = startTime.asDate(); diff --git a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/RaceStateSerializer.java b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/RaceStateSerializer.java index 5ad592fbc2b..0b87b9c86e4 100644 --- a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/RaceStateSerializer.java +++ b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/RaceStateSerializer.java @@ -45,7 +45,7 @@ public class RaceStateSerializer implements JsonSerializer result; if (leaderboard instanceof HasRegattaLike && raceLog != null) { - ReadonlyRaceState state = ReadonlyRaceStateImpl.create(/* race log resolver */ this, raceLog); + ReadonlyRaceState state = ReadonlyRaceStateImpl.getOrCreate(/* race log resolver */ this, raceLog); result = new com.sap.sse.common.Util.Triple(state.getStartTime(), raceLog.getCurrentPassId(), state.getRacingProcedure().getType()); } else { @@ -3652,7 +3652,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes Leaderboard leaderboard = getLeaderboardByName(leaderboardName); final Triple result; if (leaderboard instanceof HasRegattaLike && raceLog != null) { - ReadonlyRaceState state = ReadonlyRaceStateImpl.create(/* race log resolver */ this, raceLog); + ReadonlyRaceState state = ReadonlyRaceStateImpl.getOrCreate(/* race log resolver */ this, raceLog); result = new com.sap.sse.common.Util.Triple<>(state.getFinishingTime(), state.getFinishedTime(), raceLog.getCurrentPassId()); } else { diff --git a/java/com.sap.sse.shared.android/META-INF/MANIFEST.MF b/java/com.sap.sse.shared.android/META-INF/MANIFEST.MF index 7a9750199c9..35321b45a2f 100644 --- a/java/com.sap.sse.shared.android/META-INF/MANIFEST.MF +++ b/java/com.sap.sse.shared.android/META-INF/MANIFEST.MF @@ -11,6 +11,7 @@ Export-Package: com.sap.sse.concurrent, com.sap.sse.shared.media, com.sap.sse.shared.media.impl, com.sap.sse.shared.settings, + com.sap.sse.util, com.sap.sse.util.impl Import-Package: com.sap.sse.common.settings, com.sap.sse.common.settings.generic, diff --git a/java/com.sap.sse/src/com/sap/sse/util/WeakIdentityHashMap.java b/java/com.sap.sse.shared.android/src/com/sap/sse/util/WeakIdentityHashMap.java similarity index 100% rename from java/com.sap.sse/src/com/sap/sse/util/WeakIdentityHashMap.java rename to java/com.sap.sse.shared.android/src/com/sap/sse/util/WeakIdentityHashMap.java diff --git a/java/com.sap.sse/src/com/sap/sse/util/WeakReferenceWithKey.java b/java/com.sap.sse.shared.android/src/com/sap/sse/util/WeakReferenceWithKey.java similarity index 100% rename from java/com.sap.sse/src/com/sap/sse/util/WeakReferenceWithKey.java rename to java/com.sap.sse.shared.android/src/com/sap/sse/util/WeakReferenceWithKey.java diff --git a/java/com.sap.sse/src/com/sap/sse/util/WeakValueCache.java b/java/com.sap.sse.shared.android/src/com/sap/sse/util/WeakValueCache.java similarity index 100% rename from java/com.sap.sse/src/com/sap/sse/util/WeakValueCache.java rename to java/com.sap.sse.shared.android/src/com/sap/sse/util/WeakValueCache.java From 32d0309a1dfc00c43ea6a1f1ee215e104ac17ff8 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Sun, 5 Aug 2018 15:39:17 +0200 Subject: [PATCH 23/53] bug4074: using ConcurrentHashMap for AbstractRaceColumn.raceLogs; read-mostly will be supported much better by this, and the "corner-case" of reloadRaceLog with its optional update into the map won't hurt a ConcurrentHashMap. Change-Id: Ib3e9973708864f895146753b91e1d949cfaef291 --- .../domain/base/impl/AbstractRaceColumn.java | 46 +++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/AbstractRaceColumn.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/AbstractRaceColumn.java index 1d268d47ff9..92807bed0c6 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/AbstractRaceColumn.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/AbstractRaceColumn.java @@ -11,6 +11,8 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import java.util.logging.Level; import java.util.logging.Logger; @@ -60,15 +62,15 @@ public abstract class AbstractRaceColumn extends SimpleAbstractRaceColumn implem private TrackedRaces trackedRaces; private Map raceIdentifiers; - private Map raceLogs; - + private ConcurrentMap raceLogs; + private transient RaceLogStore raceLogStore; private RegattaLikeIdentifier regattaLikeParent; public AbstractRaceColumn() { this.trackedRaces = new TrackedRaces(); this.raceIdentifiers = new HashMap(); - this.raceLogs = new HashMap(); + this.raceLogs = new ConcurrentHashMap(); } @Override @@ -82,9 +84,7 @@ public abstract class AbstractRaceColumn extends SimpleAbstractRaceColumn implem @Override public RaceLog getRaceLog(Fleet fleet) { - synchronized (raceLogs) { - return raceLogs.get(fleet); - } + return raceLogs.get(fleet); } @Override @@ -197,25 +197,23 @@ public abstract class AbstractRaceColumn extends SimpleAbstractRaceColumn implem @Override public void reloadRaceLog(Fleet fleet) { - synchronized (raceLogs) { - RaceLogIdentifier identifier = getRaceLogIdentifier(fleet); - RaceLog newOrLoadedRaceLog = raceLogStore.getRaceLog(identifier, /* ignoreCache */true); - RaceLog raceLogAvailable = raceLogs.get(fleet); - if (raceLogAvailable == null) { - RaceColumnRaceLogReplicator listener = new RaceColumnRaceLogReplicator(this, identifier); - // FIXME Wouldn't this skip any listener notifications that a merge below would trigger if the race log already existed? - // FIXME For example, how about the race log-provided score corrections that need application to the leaderboard and replication? - newOrLoadedRaceLog.addListener(listener); - raceLogs.put(fleet, newOrLoadedRaceLog); - final TrackedRace trackedRace = getTrackedRace(fleet); - if (trackedRace != null) { - // need to attach race log - trackedRace.attachRaceLog(newOrLoadedRaceLog); - } - } else { - // now add all race log events from newOrLoadedRaceLog that are not already in raceLogAvailable - raceLogAvailable.merge(newOrLoadedRaceLog); + RaceLogIdentifier identifier = getRaceLogIdentifier(fleet); + RaceLog newOrLoadedRaceLog = raceLogStore.getRaceLog(identifier, /* ignoreCache */true); + RaceLog raceLogAvailable = raceLogs.get(fleet); + if (raceLogAvailable == null) { + RaceColumnRaceLogReplicator listener = new RaceColumnRaceLogReplicator(this, identifier); + // FIXME Wouldn't this skip any listener notifications that a merge below would trigger if the race log already existed? + // FIXME For example, how about the race log-provided score corrections that need application to the leaderboard and replication? + newOrLoadedRaceLog.addListener(listener); + raceLogs.put(fleet, newOrLoadedRaceLog); + final TrackedRace trackedRace = getTrackedRace(fleet); + if (trackedRace != null) { + // need to attach race log + trackedRace.attachRaceLog(newOrLoadedRaceLog); } + } else { + // now add all race log events from newOrLoadedRaceLog that are not already in raceLogAvailable + raceLogAvailable.merge(newOrLoadedRaceLog); } } From 424f8c85bdd0c0bd6756cbe626f0a5a1a349a505 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Sun, 5 Aug 2018 17:10:14 +0200 Subject: [PATCH 24/53] use require-bundle in com.sap.sse.security for com.sap.sse because require-package is ambiguous for com.sap.sse.util; both, com.sap.sse and com.sap.sse.shared.android have contributions for that package, and there is a chance that the wrong one is selected; com.sap.sse.security requires ClearStateTestSupport which is found in com.sap.sse. Change-Id: I838757c2bb0639c8d8de91e58f562dcb055de4fb --- java/com.sap.sse.security/META-INF/MANIFEST.MF | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sse.security/META-INF/MANIFEST.MF b/java/com.sap.sse.security/META-INF/MANIFEST.MF index ef37424199c..994486340bc 100644 --- a/java/com.sap.sse.security/META-INF/MANIFEST.MF +++ b/java/com.sap.sse.security/META-INF/MANIFEST.MF @@ -6,8 +6,7 @@ Bundle-Version: 1.0.0.qualifier Bundle-Activator: com.sap.sse.security.impl.Activator Bundle-Vendor: SAP Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Import-Package: com.sap.sse.util, - javax.mail;version="1.4.0", +Import-Package: javax.mail;version="1.4.0", javax.mail.internet;version="1.4.0", javax.ws.rs;version="1.1.1", javax.ws.rs.core;version="1.1.1", @@ -26,6 +25,7 @@ Require-Bundle: javax.servlet;bundle-version="3.1.0", org.apache.shiro.web;bundle-version="1.2.2", org.apache.servicemix.bundles.ehcache;bundle-version="2.6.9", org.apache.servicemix.bundles.scribe;bundle-version="1.3.3", + com.sap.sse, com.sap.sse.common, com.sap.sse.replication, com.sap.sse.operationaltransformation, From e5aab5dd89868645c9a4c58f0ee22bfbc22d1f1a Mon Sep 17 00:00:00 2001 From: Benjamin Barth Date: Mon, 6 Aug 2018 12:58:39 +0200 Subject: [PATCH 25/53] bug4695 Refactored RaceBoardEntryPoint for a better overview on nested asynchronous service calls --- .../gwt/ui/raceboard/RaceBoardEntryPoint.java | 273 ++++++++++-------- 1 file changed, 149 insertions(+), 124 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardEntryPoint.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardEntryPoint.java index 4b6cfbe7256..487d63cf647 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardEntryPoint.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardEntryPoint.java @@ -2,6 +2,9 @@ package com.sap.sailing.gwt.ui.raceboard; import java.util.Collections; +import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.Consumer; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Style.Unit; @@ -12,6 +15,7 @@ import com.google.gwt.user.client.ui.DockLayoutPanel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.RootLayoutPanel; import com.sap.sailing.domain.common.DetailType; +import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; import com.sap.sailing.gwt.common.authentication.FixedSailingAuthentication; import com.sap.sailing.gwt.common.authentication.SAPSailingHeaderWithAuthentication; import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting; @@ -26,13 +30,15 @@ import com.sap.sailing.gwt.ui.client.RemoteServiceMappingConstants; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sailing.gwt.ui.shared.RaceWithCompetitorsAndBoatsDTO; import com.sap.sailing.gwt.ui.shared.RaceboardDataDTO; +import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; +import com.sap.sse.common.settings.Settings; import com.sap.sse.gwt.client.EntryPointHelper; import com.sap.sse.gwt.client.async.AsyncActionsExecutor; import com.sap.sse.gwt.client.formfactor.DeviceDetector; import com.sap.sse.gwt.client.player.Timer; import com.sap.sse.gwt.client.player.Timer.PlayModes; -import com.sap.sse.gwt.client.shared.components.Component; import com.sap.sse.gwt.client.shared.perspective.PerspectiveCompositeSettings; +import com.sap.sse.gwt.client.shared.settings.ComponentContext; import com.sap.sse.gwt.client.shared.settings.DefaultOnSettingsLoadedCallback; import com.sap.sse.gwt.settings.SettingsToUrlSerializer; import com.sap.sse.security.ui.authentication.generic.sapheader.SAPHeaderWithAuthentication; @@ -40,7 +46,6 @@ import com.sap.sse.security.ui.settings.ComponentContextWithSettingsStorage; import com.sap.sse.security.ui.settings.StoredSettingsLocation; public class RaceBoardEntryPoint extends AbstractSailingEntryPoint implements ProvidesLeaderboardRouting { - private RaceWithCompetitorsAndBoatsDTO selectedRace; /** * Controls the predefined mode into which to switch or configure the race viewer. @@ -48,131 +53,83 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint implements Pr private final MediaServiceAsync mediaService = GWT.create(MediaService.class); private RaceboardContextDefinition raceboardContextDefinition; - - private String leaderBoardName; @Override protected void doOnModuleLoad() { super.doOnModuleLoad(); EntryPointHelper.registerASyncService((ServiceDefTarget) mediaService, RemoteServiceMappingConstants.mediaServiceRemotePath); - raceboardContextDefinition = new SettingsToUrlSerializer() - .deserializeFromCurrentLocation(new RaceboardContextDefinition()); - final RaceBoardModes finalMode; - if (raceboardContextDefinition.getMode() != null) { - finalMode = RaceBoardModes.valueOf(raceboardContextDefinition.getMode()); - } else { - finalMode = null; - } - if (raceboardContextDefinition.getRegattaName() == null || raceboardContextDefinition.getRegattaName().isEmpty() - || raceboardContextDefinition.getRaceName() == null - || raceboardContextDefinition.getRaceName().isEmpty() - || raceboardContextDefinition.getLeaderboardName() == null - || raceboardContextDefinition.getLeaderboardName().isEmpty()) { - createErrorPage(getStringMessages().requiresRegattaRaceAndLeaderboard()); - return; - } - - leaderBoardName = raceboardContextDefinition.getLeaderboardName(); - - AsyncCallback asyncCallback = new AsyncCallback() { - @Override - public void onSuccess(RaceboardDataDTO raceboardData) { - if (!raceboardData.isValidLeaderboard()) { - createErrorPage(getStringMessages().noSuchLeaderboard()); - return; - } - if (raceboardContextDefinition.getEventId() != null && !raceboardData.isValidEvent()) { - createErrorPage(getStringMessages().noSuchEvent()); - } - if (raceboardContextDefinition.getLeaderboardGroupName() != null) { - if (!raceboardData.isValidLeaderboardGroup()) { - createErrorPage(getStringMessages().leaderboardNotContainedInLeaderboardGroup( - raceboardContextDefinition.getLeaderboardName(), - raceboardContextDefinition.getLeaderboardGroupName())); - return; - } - if (raceboardContextDefinition.getEventId() != null && raceboardData.isValidLeaderboardGroup() - && !raceboardData.isValidEvent()) { - createErrorPage(getStringMessages().leaderboardGroupNotContainedInEvent( - raceboardContextDefinition.getLeaderboardGroupName(), - raceboardContextDefinition.getEventId().toString())); - return; - } - } - if (raceboardData.getRace() == null) { - createErrorPage(getStringMessages().couldNotFindRaceInRegatta( - raceboardContextDefinition.getRaceName(), raceboardContextDefinition.getRegattaName())); - return; - } - final boolean showChartMarkEditMediaButtonsAndVideo = !DeviceDetector.isMobile(); - final StoredSettingsLocation storageDefinition = StoredSettingsLocationFactory - .createStoredSettingsLocatorForRaceBoard(raceboardContextDefinition, - finalMode != null ? finalMode.name() : null); - // TODO bug2822: also determine regatta's boat change parameter and parameterize Leaderboard settings - // --> show boat info column yes/no? - getSailingService().determineDetailTypesForCompetitorChart( - raceboardContextDefinition.getLeaderboardGroupName(), - raceboardData.getRace().getRaceIdentifier(), new AsyncCallback>() { - - @Override - public void onFailure(Throwable caught) { - reportError("Error trying to create the raceboard: " + caught.getMessage()); - } - - @Override - public void onSuccess(Iterable chartAllowedTypes) { - getSailingService().getAvailableDetailTypesForLeaderboard( - raceboardContextDefinition.getLeaderboardName(), - raceboardData.getRace().getRaceIdentifier(), new AsyncCallback>() { - @Override - public void onFailure(Throwable caught) { - reportError( - "Error trying to create the raceboard: " + caught.getMessage()); - } - - @Override - public void onSuccess(Iterable leaderboardAllowedTypes) { - final RaceBoardPerspectiveLifecycle lifeCycle = new RaceBoardPerspectiveLifecycle( - StringMessages.INSTANCE, chartAllowedTypes, getUserService(), - leaderboardAllowedTypes); - RaceBoardComponentContext componentContext = new RaceBoardComponentContext( - lifeCycle, getUserService(), storageDefinition); - - componentContext.getInitialSettings( - new DefaultOnSettingsLoadedCallback>() { - @Override - public void onSuccess( - PerspectiveCompositeSettings initialSettings) { - Timer timer = new Timer(PlayModes.Replay, 1000l); - final RaceBoardPanel raceBoardPanel = createPerspectivePage( - null, componentContext, initialSettings, - raceboardData, - showChartMarkEditMediaButtonsAndVideo, - lifeCycle, timer, leaderboardAllowedTypes); - if (finalMode != null) { - finalMode.getMode().applyTo(raceBoardPanel); - } - } - }); - } - }); - } + checkRaceboardContextPreConditions(new RaceboardContextDefinition()).ifPresent(raceboardContextDefinition -> { + RaceBoardEntryPoint.this.raceboardContextDefinition = raceboardContextDefinition; + final String modeString = raceboardContextDefinition.getMode(); + final RaceBoardModes mode = modeString == null ? null : RaceBoardModes.valueOf(modeString); + checkRaceboardDataConditions(raceboardData -> { + loadAvailableDetailTypes(raceboardData, (chartDetailTypes, lbDetailTypes) -> { + loadLeaderboardInformation(leaderboard -> { + initLifecycle(mode, chartDetailTypes, lbDetailTypes, leaderboard, (lifecycle, compContext) -> { + loadInitialSettings(compContext, settings -> { + createPerspective(mode, compContext, settings, raceboardData, lifecycle, lbDetailTypes); + }); }); - } + }); + }); + }); + }); + } + + private Optional checkRaceboardContextPreConditions(C settings) { + final C raceboardContext = new SettingsToUrlSerializer().deserializeFromCurrentLocation(settings); + if (raceboardContext.getRegattaName() == null || raceboardContext.getRegattaName().isEmpty() + || raceboardContext.getRaceName() == null || raceboardContext.getRaceName().isEmpty() + || raceboardContext.getLeaderboardName() == null || raceboardContext.getLeaderboardName().isEmpty()) { + createErrorPage(getStringMessages().requiresRegattaRaceAndLeaderboard()); + return Optional.empty(); + } + return Optional.of(raceboardContext); + } - @Override - public void onFailure(Throwable caught) { - reportError("Error trying to create the raceboard: " + caught.getMessage()); - } - }; + private void checkRaceboardDataConditions(final Consumer callback) { getSailingService().getRaceboardData(raceboardContextDefinition.getRegattaName(), raceboardContextDefinition.getRaceName(), raceboardContextDefinition.getLeaderboardName(), raceboardContextDefinition.getLeaderboardGroupName(), raceboardContextDefinition.getEventId(), - asyncCallback); + new AbstractRaceBoardAsyncCallback() { + + @Override + public void onSuccess(RaceboardDataDTO raceboardData) { + if (!raceboardData.isValidLeaderboard()) { + createErrorPage(getStringMessages().noSuchLeaderboard()); + return; + } + if (raceboardContextDefinition.getEventId() != null && !raceboardData.isValidEvent()) { + createErrorPage(getStringMessages().noSuchEvent()); + } + if (raceboardContextDefinition.getLeaderboardGroupName() != null) { + if (!raceboardData.isValidLeaderboardGroup()) { + createErrorPage(getStringMessages().leaderboardNotContainedInLeaderboardGroup( + raceboardContextDefinition.getLeaderboardName(), + raceboardContextDefinition.getLeaderboardGroupName())); + return; + } + if (raceboardContextDefinition.getEventId() != null + && raceboardData.isValidLeaderboardGroup() && !raceboardData.isValidEvent()) { + createErrorPage(getStringMessages().leaderboardGroupNotContainedInEvent( + raceboardContextDefinition.getLeaderboardGroupName(), + raceboardContextDefinition.getEventId().toString())); + return; + } + } + if (raceboardData.getRace() == null) { + createErrorPage(getStringMessages().couldNotFindRaceInRegatta( + raceboardContextDefinition.getRaceName(), + raceboardContextDefinition.getRegattaName())); + return; + } + callback.accept(raceboardData); + } + }); } - + private void createErrorPage(String message) { final DockLayoutPanel vp = new DockLayoutPanel(Unit.PX); final SAPHeaderWithAuthentication header = new SAPSailingHeaderWithAuthentication(); @@ -183,31 +140,99 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint implements Pr infoText.getElement().getStyle().setMargin(1, Unit.EM); vp.add(infoText); // TODO: Styling of error page slightly differs from the other usages of SAPSailingHeaderWithAuthentication - // because of the root font-size. Adjustments are postponed because they might affect the hole page content. + // because of the root font-size. Adjustments are postponed because they might affect the whole page content. } - private RaceBoardPanel createPerspectivePage(Component parent, + private void loadAvailableDetailTypes(final RaceboardDataDTO raceboardData, + final BiConsumer, Iterable> callback) { + final RegattaAndRaceIdentifier raceIdentifier = raceboardData.getRace().getRaceIdentifier(); + getSailingService().determineDetailTypesForCompetitorChart(raceboardContextDefinition.getLeaderboardGroupName(), + raceIdentifier, new AbstractRaceBoardAsyncCallback>() { + + @Override + public void onSuccess(Iterable allowedChartDetailTypes) { + final String leaderboardName = raceboardContextDefinition.getLeaderboardName(); + getSailingService().getAvailableDetailTypesForLeaderboard(leaderboardName, raceIdentifier, + new AbstractRaceBoardAsyncCallback>() { + + @Override + public void onSuccess(Iterable allowedLeaderboardDetailTypes) { + callback.accept(allowedChartDetailTypes, allowedLeaderboardDetailTypes); + } + }); + } + }); + } + + private void loadLeaderboardInformation(final Consumer callback) { + getSailingService().getLeaderboard(raceboardContextDefinition.getLeaderboardName(), + new AbstractRaceBoardAsyncCallback() { + + @Override + public void onSuccess(StrippedLeaderboardDTO result) { + callback.accept(result); + } + }); + } + + private void initLifecycle(final RaceBoardModes raceBoardMode, final Iterable chartDetailTypes, + final Iterable leaderboardDetailTypes, final StrippedLeaderboardDTO leaderboard, + final BiConsumer callback) { + final StoredSettingsLocation storageDefinition = StoredSettingsLocationFactory + .createStoredSettingsLocatorForRaceBoard(raceboardContextDefinition, + raceBoardMode != null ? raceBoardMode.name() : null); + final RaceBoardPerspectiveLifecycle lifeCycle = new RaceBoardPerspectiveLifecycle(leaderboard, + StringMessages.INSTANCE, chartDetailTypes, getUserService(), leaderboardDetailTypes); + RaceBoardComponentContext componentContext = new RaceBoardComponentContext(lifeCycle, getUserService(), + storageDefinition); + callback.accept(lifeCycle, componentContext); + } + + private void loadInitialSettings(final ComponentContext ctx, final Consumer callback) { + ctx.getInitialSettings(new DefaultOnSettingsLoadedCallback() { + + @Override + public void onSuccess(S settings) { + callback.accept(settings); + } + }); + } + + private void createPerspective(final RaceBoardModes raceBoardMode, ComponentContextWithSettingsStorage> context, PerspectiveCompositeSettings settings, RaceboardDataDTO raceboardData, - boolean showChartMarkEditMediaButtonsAndVideo, RaceBoardPerspectiveLifecycle raceLifeCycle, Timer timer, - Iterable availableDetailTypes) { - selectedRace = raceboardData.getRace(); + RaceBoardPerspectiveLifecycle raceLifeCycle, Iterable availableDetailTypes) { + final Timer timer = new Timer(PlayModes.Replay, 1000l); + final boolean showChartMarkEditMediaButtonsAndVideo = !DeviceDetector.isMobile(); + + final RaceWithCompetitorsAndBoatsDTO selectedRace = raceboardData.getRace(); Window.setTitle(selectedRace.getName()); AsyncActionsExecutor asyncActionsExecutor = new AsyncActionsExecutor(); - RaceTimesInfoProvider raceTimesInfoProvider = new RaceTimesInfoProvider(getSailingService(), asyncActionsExecutor, this, - Collections.singletonList(selectedRace.getRaceIdentifier()), 5000l /* requestInterval*/); - RaceBoardPanel raceBoardPerspective = new RaceBoardPanel(parent, context, raceLifeCycle, settings, + RaceTimesInfoProvider raceTimesInfoProvider = new RaceTimesInfoProvider(getSailingService(), + asyncActionsExecutor, this, Collections.singletonList(selectedRace.getRaceIdentifier()), + 5000l /* requestInterval */); + RaceBoardPanel raceBoardPerspective = new RaceBoardPanel(/* parent */ null, context, raceLifeCycle, settings, getSailingService(), mediaService, getUserService(), asyncActionsExecutor, raceboardData.getCompetitorAndTheirBoats(), timer, selectedRace.getRaceIdentifier(), raceboardContextDefinition.getLeaderboardName(), raceboardContextDefinition.getLeaderboardGroupName(), raceboardContextDefinition.getEventId(), RaceBoardEntryPoint.this, getStringMessages(), userAgent, raceTimesInfoProvider, showChartMarkEditMediaButtonsAndVideo, true, availableDetailTypes); RootLayoutPanel.get().add(raceBoardPerspective.getEntryWidget()); - return raceBoardPerspective; + + if (raceBoardMode != null) { + raceBoardMode.getMode().applyTo(raceBoardPerspective); + } } @Override public String getLeaderboardName() { - return leaderBoardName; + return raceboardContextDefinition.getLeaderboardName(); + } + + private abstract class AbstractRaceBoardAsyncCallback implements AsyncCallback { + @Override + public final void onFailure(Throwable caught) { + reportError("Error trying to create the raceboard: " + caught.getMessage()); + } } } \ No newline at end of file From 0fe9ed507e8d81f6c02358daab8965715803b374 Mon Sep 17 00:00:00 2001 From: Benjamin Barth Date: Mon, 6 Aug 2018 12:59:43 +0200 Subject: [PATCH 26/53] bug4695 Boat column default visibility now depends on canBoatsOfCompetitorsChangePerRace flag --- .../RaceBoardPerspectiveLifecycle.java | 10 ++------- .../SingleRaceLeaderboardPanelLifecycle.java | 22 ++++++++++--------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPerspectiveLifecycle.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPerspectiveLifecycle.java index 7125da14d0b..f0f860d7cd0 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPerspectiveLifecycle.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPerspectiveLifecycle.java @@ -28,13 +28,6 @@ public class RaceBoardPerspectiveLifecycle extends AbstractPerspectiveLifecycle< public static final String ID = "rb"; - //constructor used by Standalone RaceBoard - public RaceBoardPerspectiveLifecycle(StringMessages stringMessages, - Iterable competitorChartAllowedDetailTypes, UserService userService, - Iterable availableDetailTypes) { - this(null, stringMessages, competitorChartAllowedDetailTypes, userService, availableDetailTypes); - } - public RaceBoardPerspectiveLifecycle(AbstractLeaderboardDTO leaderboard, StringMessages stringMessages, Iterable competitorChartAllowedDetailTypes, UserService userService, Iterable availableDetailTypes) { @@ -42,7 +35,8 @@ public class RaceBoardPerspectiveLifecycle extends AbstractPerspectiveLifecycle< raceMapLifecycle = new RaceMapLifecycle(stringMessages); windChartLifecycle = new WindChartLifecycle(stringMessages); maneuverTableLifecycle = new ManeuverTableLifecycle(stringMessages); - leaderboardPanelLifecycle = new SingleRaceLeaderboardPanelLifecycle(stringMessages, availableDetailTypes); + leaderboardPanelLifecycle = new SingleRaceLeaderboardPanelLifecycle(stringMessages, availableDetailTypes, + leaderboard.canBoatsOfCompetitorsChangePerRace); multiCompetitorRaceChartLifecycle = new MultiCompetitorRaceChartLifecycle(stringMessages, competitorChartAllowedDetailTypes); mediaPlayerLifecycle = new MediaPlayerLifecycle(stringMessages); raceTimePanelLifecycle = new RaceTimePanelLifecycle(stringMessages, userService); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/SingleRaceLeaderboardPanelLifecycle.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/SingleRaceLeaderboardPanelLifecycle.java index d75f0c8245f..e2bbbad0f13 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/SingleRaceLeaderboardPanelLifecycle.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/SingleRaceLeaderboardPanelLifecycle.java @@ -16,10 +16,13 @@ public class SingleRaceLeaderboardPanelLifecycle extends LeaderboardPanelLifecyc private static final long DEFAULT_REFRESH_INTERVAL = 1000L; private final boolean isScreenLargeEnoughToInitiallyDisplayLeaderboard; + private final boolean canBoatsOfCompetitorsChangePerRace; - public SingleRaceLeaderboardPanelLifecycle(StringMessages stringMessages, Iterable availableDetailTypes) { + public SingleRaceLeaderboardPanelLifecycle(final StringMessages stringMessages, + final Iterable availableDetailTypes, final boolean canBoatsOfCompetitorsChangePerRace) { super(stringMessages, availableDetailTypes); this.isScreenLargeEnoughToInitiallyDisplayLeaderboard = Document.get().getClientWidth() >= 1024; + this.canBoatsOfCompetitorsChangePerRace = canBoatsOfCompetitorsChangePerRace; } @Override @@ -33,25 +36,24 @@ public class SingleRaceLeaderboardPanelLifecycle extends LeaderboardPanelLifecyc List overallDetails = new ArrayList<>(); SingleRaceLeaderboardSettings defaultSettings = new SingleRaceLeaderboardSettings(); + // don't show competitor fullName column if even leaderboard isn't shown initially + final boolean showCompetitorFullNameColumn = isScreenLargeEnoughToInitiallyDisplayLeaderboard; + // the boat info is usually only interesting when boats of competitors can change per race + final boolean showCompetitorBoatInfoColumn = canBoatsOfCompetitorsChangePerRace; SingleRaceLeaderboardSettings settings = new SingleRaceLeaderboardSettings( defaultSettings.getManeuverDetailsToShow(), defaultSettings.getLegDetailsToShow(), defaultSettings.getRaceDetailsToShow(), overallDetails, DEFAULT_REFRESH_INTERVAL, defaultSettings.isShowAddedScores(), /* showCompetitorShortNameColumn */ true, - /* - * don't showCompetitorFullNameColumn in case screen is so small that we don't even display the - * leaderboard initially - */ isScreenLargeEnoughToInitiallyDisplayLeaderboard, - /* showCompetitorBoatInfoColumn */ true, false, false); + showCompetitorFullNameColumn, + showCompetitorBoatInfoColumn, + /* isCompetitorNationalityColumnVisible */ false, + /* showRaceRankColumn */ false); SettingsUtil.copyDefaultsFromValues(settings, settings); return settings; } - public boolean isScreenLargeEnoughToInitiallyDisplayLeaderboard() { - return isScreenLargeEnoughToInitiallyDisplayLeaderboard; - } - @Override public SingleRaceLeaderboardSettings extractDocumentSettings(SingleRaceLeaderboardSettings currentLeaderboardSettings) { SingleRaceLeaderboardSettings defaultLeaderboardSettings = createDefaultSettings(); From 21edec530696567af91f71b040348dec18871c23 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Mon, 6 Aug 2018 21:23:20 +0200 Subject: [PATCH 27/53] bug4708: added a test case that demonstrates that null is passed properly to the StartTimeChangedListener; the problem is rather that null does not lead to the UpdateHandler firing its message Change-Id: I0f8e2204c8d9f894db49a4663ff6e4e3b8449675 --- .../TrackedRaceStartTimeUpdateForDependentStartTimeTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackedRaceStartTimeUpdateForDependentStartTimeTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackedRaceStartTimeUpdateForDependentStartTimeTest.java index 4de312c268a..559d897a47a 100644 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackedRaceStartTimeUpdateForDependentStartTimeTest.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackedRaceStartTimeUpdateForDependentStartTimeTest.java @@ -16,6 +16,7 @@ import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver; import com.sap.sailing.domain.abstractlog.race.impl.RaceLogDependentStartTimeEventImpl; import com.sap.sailing.domain.abstractlog.race.impl.RaceLogImpl; +import com.sap.sailing.domain.abstractlog.race.impl.RaceLogPassChangeEventImpl; import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartTimeEventImpl; import com.sap.sailing.domain.abstractlog.race.impl.SimpleRaceLogIdentifierImpl; import com.sap.sailing.domain.base.CompetitorWithBoat; @@ -73,5 +74,8 @@ public class TrackedRaceStartTimeUpdateForDependentStartTimeTest extends TrackBa assertEquals(r1StartTimeToSet, r1StartTime[0]); assertNotNull(r2StartTime[0]); assertEquals(r1StartTimeToSet.plus(startTimeDiff), r2StartTime[0]); + // bug 4708: test that r2's start time is reverted to null after r1 loses its start time + r1RaceLog.add(new RaceLogPassChangeEventImpl(MillisecondsTimePoint.now(), author, /* pass */ 1)); + assertNull(r2StartTime[0]); } } From d24a58bea8284dd0a968eaf4c6eb77fc5344a19b Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Tue, 7 Aug 2018 00:11:14 +0200 Subject: [PATCH 28/53] add a RaceAbortHandler to send POSTPONED race status after a null start time was received from the Race Manager app Change-Id: I217b189acde27e4baff5a17023a20b2a16ee1c80 --- .../tracking/impl/StartTimeUpdateHandler.java | 29 +++++++++---------- .../domain/tracking/impl/TrackedRaceImpl.java | 2 +- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/StartTimeUpdateHandler.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/StartTimeUpdateHandler.java index 8dab411be13..bf2642d7142 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/StartTimeUpdateHandler.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/StartTimeUpdateHandler.java @@ -23,6 +23,7 @@ import org.apache.http.message.BasicNameValuePair; import org.json.simple.parser.ParseException; import com.sap.sailing.domain.base.Regatta; +import com.sap.sailing.domain.common.racelog.Flags; import com.sap.sailing.domain.tracking.StartTimeChangedListener; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sse.common.TimePoint; @@ -41,10 +42,13 @@ public class StartTimeUpdateHandler extends UpdateHandler implements StartTimeCh * a new start time is received. */ private final Regatta regatta; + + private final RaceAbortedHandler raceAbortedHandler; - public StartTimeUpdateHandler(URI updateURI, String tracTracUsername, String tracTracPassword, + public StartTimeUpdateHandler(URI updateURI, String username, String password, Serializable tracTracEventId, Serializable raceId, Regatta regatta) { - super(updateURI, ACTION, tracTracUsername, tracTracPassword, tracTracEventId, raceId); + super(updateURI, ACTION, username, password, tracTracEventId, raceId); + this.raceAbortedHandler = new RaceAbortedHandler(updateURI, username, password, tracTracEventId, raceId); this.regatta = regatta; } @@ -52,20 +56,13 @@ public class StartTimeUpdateHandler extends UpdateHandler implements StartTimeCh public void startTimeChanged(TimePoint newStartTime) throws MalformedURLException, IOException, URISyntaxException { if (isActive()) { if (newStartTime == null) { - /* - * Do not reset start time based on request by Jorge from TracTrac: - * - * """ - * We have detected that when you want to update the race start time your - * system sends before a message to reset the race start time. When your - * system invokes the first service our system changes the race start time - * to null and this value causes some secondary effects in our side. - * - * Can you just send the update_race_start_time without the - * reset_race_start_time? The reset_race_start_time service has to be used - * if you want to set the value to null. - * """ - */ + raceAbortedHandler.raceAborted(Flags.AP); /* notify race status as POSTPONED according to Jorge's mail + The method that @frank has commented has to work: + + http://em.aws.tractrac.com/update_race_status?eventid=5f2f20f0-6cb2-0136-9eca-60a44ce903c3&raceid=81c082a0-7b1f-0136-166e-028f184941da&username=trac%40sapsailing.com&password=sap0912&race_status=POSTPONED + + This method changes the race start time to null. + */ } else { HashMap additionalParameters = new HashMap(); additionalParameters.put(FIELD_RACE_START_TIME, String.valueOf(newStartTime.asMillis())); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java index 2760bf877ca..aec6ddacb93 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java @@ -949,7 +949,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl } if (newStartTime == null) { logger.finest(()->"No start time found in race logs for race "+getRace().getName()); - newStartTime = getStartTimeReceived(); + newStartTime = getStartTimeReceived(); // TODO bug 4708: wouldn't it be a problem here to use the connector's start time before having sent the start time update to the connector? if (newStartTime != null) { newStartTimeWithoutInferenceFromStartMarkPassings = newStartTime; } From 510ff84700f8f6f8655a253bcd28c3f019b0870d Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Tue, 7 Aug 2018 10:17:59 +0200 Subject: [PATCH 29/53] bug4708: send start time update each time the RaceLog-provided start time differs from getStartOfRace(); Change-Id: Ie5ee01420a6c3733f36cfadf779428168d9e7138 --- .../tracking/impl/DynamicTrackedRaceImpl.java | 5 +++-- .../tracking/impl/StartTimeUpdateHandler.java | 13 ++++++------- .../domain/tracking/impl/TrackedRaceImpl.java | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java index a9e4c107e5b..fc7e042729b 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java @@ -188,8 +188,9 @@ DynamicTrackedRace, GPSTrackListener { public void onStartTimeChanged(ReadonlyRaceState state) { final TimePoint oldStartTime = getStartOfRace(); invalidateStartTime(); - if (!Util.equalsWithNull(oldStartTime, getStartOfRace())) { - onStartTimeChangedByRaceCommittee(getStartOfRace()); + final TimePoint startTimeFromRaceLog = state.getStartTime(); + if (!Util.equalsWithNull(oldStartTime, startTimeFromRaceLog)) { + onStartTimeChangedByRaceCommittee(startTimeFromRaceLog); } } }; diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/StartTimeUpdateHandler.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/StartTimeUpdateHandler.java index bf2642d7142..b33650f08d4 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/StartTimeUpdateHandler.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/StartTimeUpdateHandler.java @@ -56,13 +56,12 @@ public class StartTimeUpdateHandler extends UpdateHandler implements StartTimeCh public void startTimeChanged(TimePoint newStartTime) throws MalformedURLException, IOException, URISyntaxException { if (isActive()) { if (newStartTime == null) { - raceAbortedHandler.raceAborted(Flags.AP); /* notify race status as POSTPONED according to Jorge's mail - The method that @frank has commented has to work: - - http://em.aws.tractrac.com/update_race_status?eventid=5f2f20f0-6cb2-0136-9eca-60a44ce903c3&raceid=81c082a0-7b1f-0136-166e-028f184941da&username=trac%40sapsailing.com&password=sap0912&race_status=POSTPONED - - This method changes the race start time to null. - */ + /* notify race status as POSTPONED according to Jorge's comment https://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=4708#c5 : + * The method that @frank has commented has to work: + * http://em.aws.tractrac.com/update_race_status?eventid=5f2f20f0-6cb2-0136-9eca-60a44ce903c3&raceid=81c082a0-7b1f-0136-166e-028f184941da&username=trac%40sapsailing.com&password=sap0912&race_status=POSTPONED + * This method changes the race start time to null. + */ + raceAbortedHandler.raceAborted(Flags.AP); // will send POSTPONED } else { HashMap additionalParameters = new HashMap(); additionalParameters.put(FIELD_RACE_START_TIME, String.valueOf(newStartTime.asMillis())); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java index aec6ddacb93..2760bf877ca 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java @@ -949,7 +949,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl } if (newStartTime == null) { logger.finest(()->"No start time found in race logs for race "+getRace().getName()); - newStartTime = getStartTimeReceived(); // TODO bug 4708: wouldn't it be a problem here to use the connector's start time before having sent the start time update to the connector? + newStartTime = getStartTimeReceived(); if (newStartTime != null) { newStartTimeWithoutInferenceFromStartMarkPassings = newStartTime; } From ad425e07778885ac66ddc92dcbe51d5b85c62493 Mon Sep 17 00:00:00 2001 From: Frank Mittag Date: Tue, 7 Aug 2018 12:59:31 +0200 Subject: [PATCH 30/53] added DCT and RCT as new MaxPointReasons --- .../src/com/sap/sailing/domain/common/MaxPointsReason.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/MaxPointsReason.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/MaxPointsReason.java index 8feb72a69a2..b868a3623c3 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/MaxPointsReason.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/MaxPointsReason.java @@ -46,7 +46,11 @@ public enum MaxPointsReason { /** Time limit Expired */ TLE(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ true, /* appliesAtStartOfRace */ false), /** Standard Penalty by Race Committee; gives a certain number of penalty points on top of rank-inferred score */ - STP(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ false, /* appliesAtStartOfRace */ true); + STP(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ false, /* appliesAtStartOfRace */ true), + /** Disqualified after causing a tangle in an incident */ + DCT(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ true, /* appliesAtStartOfRace */ false), + /** Retired after causing a tangle */ + RCT(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ true, /* appliesAtStartOfRace */ false); private final boolean discardable; From 67a66453a97a67d84c53e89667bb0b696e8cbfd1 Mon Sep 17 00:00:00 2001 From: Benjamin Barth Date: Tue, 7 Aug 2018 13:31:41 +0200 Subject: [PATCH 31/53] bug4695 Formatting and constructor visibility changes only --- .../client/leaderboard/LeaderboardPanelLifecycle.java | 2 +- .../leaderboard/LeaderboardSettingsDialogComponent.java | 3 ++- .../OverallLeaderboardSettingsDialogComponent.java | 6 ++++-- .../SingleRaceLeaderboardSettingsDialogComponent.java | 7 ++++--- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardPanelLifecycle.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardPanelLifecycle.java index f533c6d71e8..381b304b9c5 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardPanelLifecycle.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardPanelLifecycle.java @@ -12,7 +12,7 @@ public abstract class LeaderboardPanelLifecycle protected final Iterable availableDetailTypes; - public LeaderboardPanelLifecycle(StringMessages stringMessages, Iterable availableDetailTypes) { + protected LeaderboardPanelLifecycle(StringMessages stringMessages, Iterable availableDetailTypes) { this.stringMessages = stringMessages; this.availableDetailTypes = availableDetailTypes; } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardSettingsDialogComponent.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardSettingsDialogComponent.java index 285bfba3f93..1b02fe8b583 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardSettingsDialogComponent.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardSettingsDialogComponent.java @@ -46,7 +46,8 @@ public abstract class LeaderboardSettingsDialogComponent availableDetailTypes; - public LeaderboardSettingsDialogComponent(T initialSettings, StringMessages stringMessages, Iterable availableDetailTypes, boolean canBoatInfoBeShown) { + protected LeaderboardSettingsDialogComponent(T initialSettings, StringMessages stringMessages, + Iterable availableDetailTypes, boolean canBoatInfoBeShown) { this.initialSettings = initialSettings; this.stringMessages = stringMessages; this.canBoatInfoBeShown = canBoatInfoBeShown; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/OverallLeaderboardSettingsDialogComponent.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/OverallLeaderboardSettingsDialogComponent.java index a66666974f9..be79914e79e 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/OverallLeaderboardSettingsDialogComponent.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/OverallLeaderboardSettingsDialogComponent.java @@ -9,8 +9,10 @@ import com.sap.sse.gwt.client.dialog.DataEntryDialog; public class OverallLeaderboardSettingsDialogComponent extends MultiRaceLeaderboardSettingsDialogComponent { - public OverallLeaderboardSettingsDialogComponent(MultiRaceLeaderboardSettings initialSettings, List allRaceColumnNames, StringMessages stringMessages, Iterable availableDetailTypes) { - super(initialSettings, allRaceColumnNames, stringMessages, availableDetailTypes, false); + public OverallLeaderboardSettingsDialogComponent(MultiRaceLeaderboardSettings initialSettings, + List allRaceColumnNames, StringMessages stringMessages, Iterable availableDetailTypes) { + super(initialSettings, allRaceColumnNames, stringMessages, availableDetailTypes, + /* canBoatInfoBeShown */ false); } @Override diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/SingleRaceLeaderboardSettingsDialogComponent.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/SingleRaceLeaderboardSettingsDialogComponent.java index 3f40d626b88..e911ec0cc11 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/SingleRaceLeaderboardSettingsDialogComponent.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/SingleRaceLeaderboardSettingsDialogComponent.java @@ -13,11 +13,11 @@ import com.sap.sse.gwt.client.dialog.DataEntryDialog.Validator; public class SingleRaceLeaderboardSettingsDialogComponent extends LeaderboardSettingsDialogComponent { - protected CheckBox showRaceRankColumn; + private CheckBox showRaceRankColumn; public SingleRaceLeaderboardSettingsDialogComponent(SingleRaceLeaderboardSettings initialSettings, StringMessages stringMessages, Iterable availableDetailTypes) { - super(initialSettings, stringMessages, availableDetailTypes, true /*canBoatInfoBeShown*/); + super(initialSettings, stringMessages, availableDetailTypes, /* canBoatInfoBeShown */ true); } @Override @@ -33,7 +33,8 @@ public class SingleRaceLeaderboardSettingsDialogComponent 1000l * (delayBetweenAutoAdvancesValue == null ? 0l : delayBetweenAutoAdvancesValue.longValue()), /* showAddedScores */ showAddedScoresCheckBox.getValue().booleanValue(), showCompetitorShortNameColumnCheckBox.getValue(), showCompetitorFullNameColumnCheckBox.getValue(), - showCompetitorBoatInfoColumnCheckBox.getValue(), isCompetitorNationalityColumnVisible.getValue(), showRaceRankColumn.getValue()); + showCompetitorBoatInfoColumnCheckBox.getValue(), isCompetitorNationalityColumnVisible.getValue(), + showRaceRankColumn.getValue()); return newSettings; } From 1d55b53ec44834bfcfd427db7c4654a7b6cdd6da Mon Sep 17 00:00:00 2001 From: Benjamin Barth Date: Tue, 7 Aug 2018 14:31:50 +0200 Subject: [PATCH 32/53] bug4695 Disabled boat info columns in overall leaderboards (always) and multi-race leaderboard (when boat can change per race) --- .../leaderboard/MultiRaceLeaderboardPanelLifecycle.java | 5 ++++- .../gwt/ui/leaderboard/MultiRaceLeaderboardPanel.java | 8 +++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/MultiRaceLeaderboardPanelLifecycle.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/MultiRaceLeaderboardPanelLifecycle.java index 4e45d743d51..29a5b5a89e6 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/MultiRaceLeaderboardPanelLifecycle.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/MultiRaceLeaderboardPanelLifecycle.java @@ -11,11 +11,13 @@ import com.sap.sse.common.settings.generic.support.SettingsUtil; public class MultiRaceLeaderboardPanelLifecycle extends LeaderboardPanelLifecycle { protected final List namesOfRaceColumns; + private final boolean canBoatInfoBeShown; public MultiRaceLeaderboardPanelLifecycle(AbstractLeaderboardDTO leaderboard, StringMessages stringMessages, Iterable availableDetailTypes) { super(stringMessages, availableDetailTypes); this.namesOfRaceColumns = leaderboard != null ? leaderboard.getNamesOfRaceColumns() : new ArrayList(); + this.canBoatInfoBeShown = leaderboard != null ? !leaderboard.canBoatsOfCompetitorsChangePerRace : false; } @Override public MultiRaceLeaderboardSettings extractUserSettings(MultiRaceLeaderboardSettings currentLeaderboardSettings) { @@ -55,7 +57,8 @@ public class MultiRaceLeaderboardPanelLifecycle extends LeaderboardPanelLifecycl @Override public MultiRaceLeaderboardSettingsDialogComponent getSettingsDialogComponent(MultiRaceLeaderboardSettings settings) { - return new MultiRaceLeaderboardSettingsDialogComponent(settings, namesOfRaceColumns, stringMessages, availableDetailTypes, false); + return new MultiRaceLeaderboardSettingsDialogComponent(settings, namesOfRaceColumns, stringMessages, + availableDetailTypes, canBoatInfoBeShown); } @Override diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/MultiRaceLeaderboardPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/MultiRaceLeaderboardPanel.java index 8c5dadc347a..42c94961eee 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/MultiRaceLeaderboardPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/MultiRaceLeaderboardPanel.java @@ -6,7 +6,6 @@ import java.util.List; import java.util.Map; import com.sap.sailing.domain.common.DetailType; -import com.sap.sailing.domain.common.LeaderboardType; import com.sap.sailing.domain.common.dto.AbstractLeaderboardDTO; import com.sap.sailing.domain.common.dto.CompetitorDTO; import com.sap.sailing.domain.common.dto.LeaderboardDTO; @@ -96,8 +95,7 @@ public class MultiRaceLeaderboardPanel extends LeaderboardPanel getSettingsDialogComponent( MultiRaceLeaderboardSettings useTheseSettings) { - return new MultiRaceLeaderboardSettingsDialogComponent((MultiRaceLeaderboardSettings) useTheseSettings, - leaderboard.getNamesOfRaceColumns(), stringMessages, availableDetailTypes, !leaderboard.canBoatsOfCompetitorsChangePerRace); + return new MultiRaceLeaderboardSettingsDialogComponent(useTheseSettings, leaderboard.getNamesOfRaceColumns(), + stringMessages, availableDetailTypes, canShowCompetitorBoatInfo()); } @Override From 124466ed57273c42ba471dbd4e1f92828990d8c4 Mon Sep 17 00:00:00 2001 From: Vladislav Chumak Date: Tue, 7 Aug 2018 14:56:51 +0200 Subject: [PATCH 33/53] Fixed bug in maneuver curve extension validation --- .../domain/maneuverdetection/impl/ManeuverDetectorImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java index a9ba715c9e4..95001430ae9 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java @@ -959,8 +959,8 @@ public class ManeuverDetectorImpl extends AbstractManeuverDetectorImpl { if (curveBoundaryExtension == null) { return false; } - return Math.abs(curveBoundaryExtension.getCourseChangeInDegreesWithinExtensionArea()) > Math - .abs(curveBoundaryExtension.getCourseChangeInDegreesWithinExtensionArea()) / 3.0; + return Math.abs(maneuverMainCurveDetails.getDirectionChangeInDegrees()) / 3.0 > Math + .abs(curveBoundaryExtension.getCourseChangeInDegreesWithinExtensionArea()); } /** From 86e0cf82f7bf436f20bf4efa9c1ca82bc580b772 Mon Sep 17 00:00:00 2001 From: Vladislav Chumak Date: Tue, 7 Aug 2018 16:59:28 +0200 Subject: [PATCH 34/53] Refined course change limits for maneuver curve extension --- .../domain/maneuverdetection/impl/ManeuverDetectorImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java index 95001430ae9..e0a25f03865 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java @@ -959,7 +959,7 @@ public class ManeuverDetectorImpl extends AbstractManeuverDetectorImpl { if (curveBoundaryExtension == null) { return false; } - return Math.abs(maneuverMainCurveDetails.getDirectionChangeInDegrees()) / 3.0 > Math + return Math.abs(maneuverMainCurveDetails.getDirectionChangeInDegrees()) / 2.0 > Math .abs(curveBoundaryExtension.getCourseChangeInDegreesWithinExtensionArea()); } From ddea4386577f0735586e561f9d27d017f99eab16 Mon Sep 17 00:00:00 2001 From: Vladislav Chumak Date: Tue, 7 Aug 2018 17:05:50 +0200 Subject: [PATCH 35/53] Restored stable course analysis for extension of maneuver beginning --- .../impl/ManeuverDetectorImpl.java | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java index e0a25f03865..54cb3a4aeb6 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java @@ -698,8 +698,9 @@ public class ManeuverDetectorImpl extends AbstractManeuverDetectorImpl { } catch (NoWindException e) { tackAfterManeuver = null; } - maneuver = new ManeuverWithMainCurveBoundariesImpl(maneuverType, tackAfterManeuver, maneuverPosition, maneuverMainCurveDetails.getTimePoint(), - maneuverMainCurveDetails.extractCurveBoundariesOnly(), maneuverUnstableCourseAndSpeedBoundaries, + maneuver = new ManeuverWithMainCurveBoundariesImpl(maneuverType, tackAfterManeuver, maneuverPosition, + maneuverMainCurveDetails.getTimePoint(), maneuverMainCurveDetails.extractCurveBoundariesOnly(), + maneuverUnstableCourseAndSpeedBoundaries, maneuverMainCurveDetails.getMaxTurningRateInDegreesPerSecond(), markPassing, maneuverLoss); } return maneuver; @@ -723,7 +724,8 @@ public class ManeuverDetectorImpl extends AbstractManeuverDetectorImpl { // For upwind/downwind legs, find the mean course between inbound and outbound course and project actual // and // extrapolated positions onto it: - Bearing middleManeuverAngle = speedWithBearingWhenSpeedStartedToDrop.getBearing().middle(speedWithBearingAfterManeuver.getBearing()); + Bearing middleManeuverAngle = speedWithBearingWhenSpeedStartedToDrop.getBearing() + .middle(speedWithBearingAfterManeuver.getBearing()); // extrapolate maximum speed before maneuver to time point of maximum speed after maneuver and project // resulting position // onto the average maneuver course; compare to the projected position actually reached at the time @@ -731,9 +733,9 @@ public class ManeuverDetectorImpl extends AbstractManeuverDetectorImpl { // maneuver: Position positionWhenSpeedStartedToDrop = track.getEstimatedPosition(timePointWhenSpeedStartedToDrop, /* extrapolate */ false); - Position extrapolatedPositionAtTimePointOfMaxSpeedAfterManeuver = speedWithBearingWhenSpeedStartedToDrop.travelTo( - positionWhenSpeedStartedToDrop, timePointWhenSpeedStartedToDrop, - timePointWhenSpeedLevelledOffAfterManeuver); + Position extrapolatedPositionAtTimePointOfMaxSpeedAfterManeuver = speedWithBearingWhenSpeedStartedToDrop + .travelTo(positionWhenSpeedStartedToDrop, timePointWhenSpeedStartedToDrop, + timePointWhenSpeedLevelledOffAfterManeuver); Position actualPositionAtTimePointOfMaxSpeedAfterManeuver = track .getEstimatedPosition(timePointWhenSpeedLevelledOffAfterManeuver, /* extrapolate */ false); Position projectedExtrapolatedPositionAtTimePointOfMaxSpeedAfterManeuver = extrapolatedPositionAtTimePointOfMaxSpeedAfterManeuver @@ -745,9 +747,8 @@ public class ManeuverDetectorImpl extends AbstractManeuverDetectorImpl { Distance projectedDistanceSailedIfNotManeuvering = positionWhenSpeedStartedToDrop .getDistance(projectedExtrapolatedPositionAtTimePointOfMaxSpeedAfterManeuver); return new ManeuverLoss(projectedDistanceSailed, projectedDistanceSailedIfNotManeuvering, - positionWhenSpeedStartedToDrop, - actualPositionAtTimePointOfMaxSpeedAfterManeuver, maneuverDuration, speedWithBearingWhenSpeedStartedToDrop, - middleManeuverAngle); + positionWhenSpeedStartedToDrop, actualPositionAtTimePointOfMaxSpeedAfterManeuver, maneuverDuration, + speedWithBearingWhenSpeedStartedToDrop, middleManeuverAngle); } protected Duration getDurationForDouglasPeuckerExtensionForMainCurveAnalysis(Duration approximateManeuverDuration) { @@ -938,11 +939,25 @@ public class ManeuverDetectorImpl extends AbstractManeuverDetectorImpl { if (isCourseChangeLimitExceededForCurveExtension(maneuverMainCurveDetails, maneuverStart)) { maneuverStart = null; } - // Stable course analysis is considered as not necessary for preparation phase of maneuver because no - // oversteering is usually performed before maneuver + TimePoint stableBearingAnalysisUntil = maneuverStart == null ? maneuverMainCurveDetails.getTimePointBefore() + : maneuverStart.getExtensionTimePoint(); Speed lowestSpeed = maneuverStart == null ? null : maneuverStart.getLowestSpeedWithinExtensionArea(); double courseChangeSinceManeuverMainCurveInDegrees = maneuverStart == null ? 0 : maneuverStart.getCourseChangeInDegreesWithinExtensionArea(); + stepsToAnalyze = getSpeedWithBearingStepsWithinTimeRange(stepsToAnalyze, earliestTimePointForSpeedTrendAnalysis, + stableBearingAnalysisUntil); + ManeuverCurveBoundaryExtension stableBearingExtension = findStableBearingWithMaxAbsCourseChangeSpeed( + stepsToAnalyze, true, MAX_TURNING_RATE_IN_DEG_PER_SECOND_FOR_STABLE_COURSE_ANALYSIS); + if (stableBearingExtension != null + && !isCourseChangeLimitExceededForCurveExtension(maneuverMainCurveDetails, stableBearingExtension)) { + maneuverStart = stableBearingExtension; + courseChangeSinceManeuverMainCurveInDegrees += stableBearingExtension + .getCourseChangeInDegreesWithinExtensionArea(); + if (lowestSpeed == null + || lowestSpeed.compareTo(stableBearingExtension.getLowestSpeedWithinExtensionArea()) > 0) { + lowestSpeed = stableBearingExtension.getLowestSpeedWithinExtensionArea(); + } + } return maneuverStart != null ? new ManeuverCurveBoundaryExtension(maneuverStart.getExtensionTimePoint(), maneuverStart.getSpeedWithBearingAtExtensionTimePoint(), From 71c4162cbb62d54605a3281f495b3163720180e2 Mon Sep 17 00:00:00 2001 From: Vladislav Chumak Date: Wed, 8 Aug 2018 13:00:49 +0200 Subject: [PATCH 36/53] Fixed isCourseChangeLimitExceededForCurveExtension comparison --- .../domain/maneuverdetection/impl/ManeuverDetectorImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java index 54cb3a4aeb6..fd6580496be 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorImpl.java @@ -974,7 +974,7 @@ public class ManeuverDetectorImpl extends AbstractManeuverDetectorImpl { if (curveBoundaryExtension == null) { return false; } - return Math.abs(maneuverMainCurveDetails.getDirectionChangeInDegrees()) / 2.0 > Math + return Math.abs(maneuverMainCurveDetails.getDirectionChangeInDegrees()) / 2.0 < Math .abs(curveBoundaryExtension.getCourseChangeInDegreesWithinExtensionArea()); } From c435d082df6313c4a06b81ad5468470aaa6d60bd Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 9 Aug 2018 08:49:44 +0200 Subject: [PATCH 37/53] bug4713: added a failing test case Change-Id: I476037f021ee2a84170b5dd90b6bf8cab11157ae --- .../test/RaceStatusAnalyzerTest.java | 37 +++++++++++++++++-- .../race/state/impl/RaceStateImpl.java | 2 +- .../state/impl/ReadonlyRaceStateImpl.java | 20 ++-------- .../racingprocedure/RacingProcedure.java | 9 +++++ .../basic/impl/BasicRacingProcedureImpl.java | 2 +- .../ess/impl/ESSRacingProcedureImpl.java | 2 +- .../impl/GateStartRacingProcedureImpl.java | 2 +- .../impl/BaseRacingProcedure.java | 2 - .../impl/LeagueRacingProcedureImpl.java | 2 +- ...rableStartModeFlagRacingProcedureImpl.java | 3 -- .../line/impl/RRS26RacingProcedureImpl.java | 2 +- .../line/impl/SWCRacingProcedureImpl.java | 2 +- 12 files changed, 53 insertions(+), 32 deletions(-) diff --git a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/RaceStatusAnalyzerTest.java b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/RaceStatusAnalyzerTest.java index 288fa7f2f0f..a8ea8066150 100644 --- a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/RaceStatusAnalyzerTest.java +++ b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/RaceStatusAnalyzerTest.java @@ -7,6 +7,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.util.Arrays; +import java.util.Collections; import org.junit.Test; import org.mockito.invocation.InvocationOnMock; @@ -18,11 +19,20 @@ import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor; import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent; +import com.sap.sailing.domain.abstractlog.race.RaceLogStartProcedureChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceStatusAnalyzer; +import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartProcedureChangedEventImpl; +import com.sap.sailing.domain.abstractlog.race.impl.SimpleRaceLogIdentifierImpl; +import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState; +import com.sap.sailing.domain.abstractlog.race.state.impl.ReadonlyRaceStateImpl; import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedure; +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.impl.ReadonlyRacingProcedureFactory; +import com.sap.sailing.domain.base.configuration.impl.EmptyRegattaConfiguration; import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus; +import com.sap.sailing.domain.common.racelog.RacingProcedureType; +import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; import com.sap.sse.common.impl.MillisecondsTimePoint; @@ -112,15 +122,36 @@ public class RaceStatusAnalyzerTest extends PassAwareRaceLogAnalyzerTestemptyMap(), /* update */ true); + Collections.emptyMap()); this.author = author; } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java index 4904be72af4..beb3f16c06b 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java @@ -187,7 +187,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL SimpleRaceLogIdentifier forRaceLogIdentifier, RacingProcedureFactory procedureFactory, Map dependentRaceStates) { this(raceLogResolver, raceLog, forRaceLogIdentifier, new RaceStatusAnalyzer.StandardClock(), - procedureFactory, dependentRaceStates, /* update */true); + procedureFactory, dependentRaceStates); } /** @@ -196,14 +196,11 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL * new race state. This can help avoid endless recursions because this race state can be passed along * together with the identifier so that when again along a dependent call chain a race state is required * for that race log identifier, this one can be used. - * @param update - * if true, the race state will be updated whenever the underlying raceLog - * changes. */ protected ReadonlyRaceStateImpl(RaceLogResolver raceLogResolver, RaceLog raceLog, SimpleRaceLogIdentifier forRaceLogIdentifier, Clock analyzersClock, RacingProcedureFactory procedureFactory, - final Map dependentRaceStates, boolean update) { + final Map dependentRaceStates) { this.raceLog = raceLog; this.raceLogResolver = raceLogResolver; this.procedureFactory = procedureFactory; @@ -325,6 +322,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL @Override public RaceLogRaceStatus getStatus() { + // TODO bug4713: check clock and invalidate/recalculate if clock passed status invalidation time point return cachedRaceStatus; } @@ -463,13 +461,11 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL recreateRacingProcedure(dependentRaceStates); changedListeners.onRacingProcedureChanged(this); } - RaceLogRaceStatus status = statusAnalyzer.analyze(); if (!Util.equalsWithNull(cachedRaceStatus, status)) { cachedRaceStatus = status; changedListeners.onStatusChanged(this); } - int passId = raceLog.getCurrentPassId(); if (cachedPassId != passId) { cachedPassId = passId; @@ -478,38 +474,32 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL cachedRacingProcedureType = null; cachedRacingProcedureTypeNoFallback = null; } - StartTimeFinderResult startTimeFinderResult = startTimeAnalyzer.analyze(); if (!Util.equalsWithNull(cachedStartTimeFinderResult, startTimeFinderResult)) { cachedStartTimeFinderResult = startTimeFinderResult; changedListeners.onStartTimeChanged(this); } adjustObserverForRelativeStartTime(startTimeFinderResult, dependentRaceStates); - TimePoint finishingTime = finishingTimeAnalyzer.analyze(); if (!Util.equalsWithNull(cachedFinishingTime, finishingTime)) { cachedFinishingTime = finishingTime; changedListeners.onFinishingTimeChanged(this); } - TimePoint finishedTime = finishedTimeAnalyzer.analyze(); if (!Util.equalsWithNull(cachedFinishedTime, finishedTime)) { cachedFinishedTime = finishedTime; changedListeners.onFinishedTimeChanged(this); } - TimeRange protest = protestTimeAnalyzer.analyze(); if (!Util.equalsWithNull(cachedProtest, protest)) { cachedProtest = protest; changedListeners.onProtestTimeChanged(this); } - CompetitorResults positionedCompetitors = finishPositioningListAnalyzer.analyze(); if (!Util.equalsWithNull(cachedPositionedCompetitors, positionedCompetitors)) { cachedPositionedCompetitors = positionedCompetitors; changedListeners.onFinishingPositioningsChanged(this); } - CompetitorResults confirmedPositionedCompetitors = confirmedFinishPositioningListAnalyzer.analyze(); if (!Util.equalsWithNull(cachedConfirmedPositionedCompetitors, confirmedPositionedCompetitors)) { cachedConfirmedPositionedCompetitors = confirmedPositionedCompetitors; @@ -517,13 +507,11 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL changedListeners.onFinishingPositionsConfirmed(this); } } - CourseBase courseDesign = courseDesignerAnalyzer.analyze(); if (!Util.equalsWithNull(cachedCourseDesign, courseDesign)) { cachedCourseDesign = courseDesign; changedListeners.onCourseDesignChanged(this); } - Wind windFix = lastWindFixAnalyzer.analyze(); if (!Util.equalsWithNull(cachedWindFix, windFix)) { cachedWindFix = windFix; @@ -539,10 +527,8 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL racingProcedure = procedureFactory.createRacingProcedure(cachedRacingProcedureType, raceLog, raceLogResolver); racingProcedure.setStateEventScheduler(scheduler); addChangedListener(racingProcedure); - statusAnalyzer = new RaceStatusAnalyzer(raceLogResolver, raceLog, statusAnalyzerClock, racingProcedure); // let's do an update because status might have changed with new procedure update(dependentRaceStates); } - } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/RacingProcedure.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/RacingProcedure.java index 1eba9f3b8fc..dbc6d40861d 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/RacingProcedure.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/RacingProcedure.java @@ -1,5 +1,8 @@ package com.sap.sailing.domain.abstractlog.race.state.racingprocedure; +import java.util.Collection; + +import com.sap.sailing.domain.abstractlog.race.state.RaceStateEvent; import com.sap.sse.common.TimePoint; /** @@ -17,4 +20,10 @@ public interface RacingProcedure extends ReadonlyRacingProcedure { */ void removeIndividualRecall(TimePoint now); + /** + * Delivers the time points and types of the events around the start, each optionally + * leading to a change in race status. + */ + Collection createStartStateEvents(TimePoint startTime); + } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/basic/impl/BasicRacingProcedureImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/basic/impl/BasicRacingProcedureImpl.java index ffea26c734a..feaa5aeb464 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/basic/impl/BasicRacingProcedureImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/basic/impl/BasicRacingProcedureImpl.java @@ -66,7 +66,7 @@ public class BasicRacingProcedureImpl extends BaseRacingProcedure { } @Override - protected Collection createStartStateEvents(TimePoint startTime) { + public Collection createStartStateEvents(TimePoint startTime) { return Arrays.asList(new RaceStateEventImpl(startTime, RaceStateEvents.START)); } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/ess/impl/ESSRacingProcedureImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/ess/impl/ESSRacingProcedureImpl.java index ea009a6554f..0ae3f36f013 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/ess/impl/ESSRacingProcedureImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/ess/impl/ESSRacingProcedureImpl.java @@ -64,7 +64,7 @@ public class ESSRacingProcedureImpl extends BaseRacingProcedure implements ESSRa } @Override - protected Collection createStartStateEvents(TimePoint startTime) { + public Collection createStartStateEvents(TimePoint startTime) { return Arrays. asList(new RaceStateEventImpl(startTime.minus(startPhaseAPDownInterval), RaceStateEvents.ESS_AP_DOWN), new RaceStateEventImpl(startTime.minus(startPhaseESSThreeUpInterval), RaceStateEvents.ESS_THREE_UP), new RaceStateEventImpl(startTime.minus(startPhaseESSTwoUpInterval), diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/gate/impl/GateStartRacingProcedureImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/gate/impl/GateStartRacingProcedureImpl.java index fddb5aad31a..6a6d89679f2 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/gate/impl/GateStartRacingProcedureImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/gate/impl/GateStartRacingProcedureImpl.java @@ -119,7 +119,7 @@ public class GateStartRacingProcedureImpl extends BaseRacingProcedure implements } @Override - protected Collection createStartStateEvents(TimePoint startTime) { + public Collection createStartStateEvents(TimePoint startTime) { return Arrays. asList( new RaceStateEventImpl(startTime.minus(startPhaseClassOverGolfUpInterval), RaceStateEvents.GATE_CLASS_OVER_GOLF_UP), diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/impl/BaseRacingProcedure.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/impl/BaseRacingProcedure.java index 1bccfd7b31b..017d0065bf8 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/impl/BaseRacingProcedure.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/impl/BaseRacingProcedure.java @@ -276,8 +276,6 @@ public abstract class BaseRacingProcedure extends BaseRaceStateChangedListener i return configuration; } - protected abstract Collection createStartStateEvents(TimePoint startTime); - @Override public void onStartTimeChanged(ReadonlyRaceState state) { getChangedListeners().onActiveFlagsChanged(this); diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/impl/LeagueRacingProcedureImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/impl/LeagueRacingProcedureImpl.java index a7098a8d0e5..703c2244571 100755 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/impl/LeagueRacingProcedureImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/impl/LeagueRacingProcedureImpl.java @@ -81,7 +81,7 @@ public class LeagueRacingProcedureImpl extends BaseRacingProcedure implements Le } @Override - protected Collection createStartStateEvents(TimePoint startTime) { + public Collection createStartStateEvents(TimePoint startTime) { // Remark: We are reusing here CLASS_UP, STARTMODE_UP and STARTMODE_DOWN from the RRS26 procedure // The question is why there are no generic CLASS_UP, STARTMODE_UP and STARTMODE_DOWN events return Arrays. asList( diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/ConfigurableStartModeFlagRacingProcedureImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/ConfigurableStartModeFlagRacingProcedureImpl.java index 1e85749df58..684fe233401 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/ConfigurableStartModeFlagRacingProcedureImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/ConfigurableStartModeFlagRacingProcedureImpl.java @@ -28,17 +28,14 @@ public abstract class ConfigurableStartModeFlagRacingProcedureImpl extends BaseR public ConfigurableStartModeFlagRacingProcedureImpl(RaceLog raceLog, AbstractLogEventAuthor author, ConfigurableStartModeFlagRacingProcedureConfiguration configuration, RaceLogResolver raceLogResolver) { super(raceLog, author, configuration, raceLogResolver); - RacingProcedureTypeAnalyzer procedureAnalyzer = new RacingProcedureTypeAnalyzer(raceLog); if (configuration.getStartModeFlags() != null) { this.startModeFlagAnalyzer = new StartModeFlagFinder(procedureAnalyzer, raceLog, configuration.getStartModeFlags()); } else { this.startModeFlagAnalyzer = new StartModeFlagFinder(procedureAnalyzer, raceLog, getDefaultStartModeFlags()); } - this.cachedStartmodeFlag = getDefaultStartMode(); this.startmodeFlagHasBeenSet = false; - update(); } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/RRS26RacingProcedureImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/RRS26RacingProcedureImpl.java index 198b00ecc63..a2780f3daad 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/RRS26RacingProcedureImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/RRS26RacingProcedureImpl.java @@ -64,7 +64,7 @@ public class RRS26RacingProcedureImpl extends ConfigurableStartModeFlagRacingPro } @Override - protected Collection createStartStateEvents(TimePoint startTime) { + public Collection createStartStateEvents(TimePoint startTime) { return Arrays. asList( new RaceStateEventImpl(startTime.minus(startPhaseClassUpInterval), RaceStateEvents.RRS26_CLASS_UP), new RaceStateEventImpl(startTime.minus(startPhaseStartModeUpInterval), RaceStateEvents.RRS26_STARTMODE_UP), diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/SWCRacingProcedureImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/SWCRacingProcedureImpl.java index 2a72bcddb68..18000930a16 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/SWCRacingProcedureImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/SWCRacingProcedureImpl.java @@ -69,7 +69,7 @@ public class SWCRacingProcedureImpl extends ConfigurableStartModeFlagRacingProce } @Override - protected Collection createStartStateEvents(TimePoint startTime) { + public Collection createStartStateEvents(TimePoint startTime) { return Arrays. asList( new RaceStateEventImpl(startTime.minus(CLASS_AND_STARTMODE_UP_INTERVAL), RaceStateEvents.SWC_CLASS_AND_STARTMODE_UP), new RaceStateEventImpl(startTime.minus(FIVE_MINUTES_FLAG_UP_INTERVAL), RaceStateEvents.SWC_FIVE_UP), From b43879ab29ab336bf633246335aa0637c50ded21 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 9 Aug 2018 11:07:23 +0200 Subject: [PATCH 38/53] bug4713: ReadonlyRaceState now updates its status if a status change was possible between last cache calculation time point and the request time point Change-Id: Iba391e2894951e19097e2ea30cdba9c4b4bed815 --- .../test/PassAwareRaceLogAnalyzerTest.java | 2 - .../test/RaceStatusAnalyzerTest.java | 49 +++++++---- .../racelog/state/test/RaceStateTest.java | 27 +++--- .../analyzing/impl/RaceStatusAnalyzer.java | 42 +++++---- .../race/state/RaceStateEventScheduler.java | 4 +- .../state/impl/ReadonlyRaceStateImpl.java | 87 +++++++++++++++++-- .../racingprocedure/RacingProcedure.java | 9 -- .../ReadonlyRacingProcedure.java | 8 ++ .../basic/impl/BasicRacingProcedureImpl.java | 3 +- .../ess/impl/ESSRacingProcedureImpl.java | 3 +- .../impl/GateStartRacingProcedureImpl.java | 3 +- .../impl/LeagueRacingProcedureImpl.java | 3 +- .../line/impl/RRS26RacingProcedureImpl.java | 3 +- .../line/impl/SWCRacingProcedureImpl.java | 3 +- .../RaceStateEventSchedulerOnService.java | 4 +- 15 files changed, 169 insertions(+), 81 deletions(-) diff --git a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/PassAwareRaceLogAnalyzerTest.java b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/PassAwareRaceLogAnalyzerTest.java index b200b547f9d..74818b821de 100644 --- a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/PassAwareRaceLogAnalyzerTest.java +++ b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/PassAwareRaceLogAnalyzerTest.java @@ -67,10 +67,8 @@ public abstract class PassAwareRaceLogAnalyzerTest { +public class RaceStatusAnalyzerTest extends PassAwareRaceLogAnalyzerTest> { private RacingProcedure racingProcedure = mock(RacingProcedure.class); + private TimePoint now = MillisecondsTimePoint.now(); + private Clock constantTimeClock = ()->now; @Override protected RaceStatusAnalyzer createAnalyzer(RaceLog raceLog) { - return new RaceStatusAnalyzer(mock(RaceLogResolver.class), raceLog, racingProcedure); + return new RaceStatusAnalyzer(mock(RaceLogResolver.class), raceLog, constantTimeClock, racingProcedure); } @Override @@ -50,7 +55,7 @@ public class RaceStatusAnalyzerTest extends PassAwareRaceLogAnalyzerTest(event.getNextStatus(), now)); } @Override @@ -59,14 +64,14 @@ public class RaceStatusAnalyzerTest extends PassAwareRaceLogAnalyzerTest(event.getNextStatus(), now)); } @Test public void testUnscheduldedForNone() { RaceLogEvent event1 = createEvent(RaceLogEvent.class, 1); raceLog.add(event1); - assertEquals(RaceLogRaceStatus.UNSCHEDULED, analyzer.analyze()); + assertEquals(RaceLogRaceStatus.UNSCHEDULED, analyzer.analyze().getA()); } @Test @@ -80,7 +85,7 @@ public class RaceStatusAnalyzerTest extends PassAwareRaceLogAnalyzerTest { diff --git a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/state/test/RaceStateTest.java b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/state/test/RaceStateTest.java index a1d5062a69a..0881da8cd97 100644 --- a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/state/test/RaceStateTest.java +++ b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/state/test/RaceStateTest.java @@ -140,33 +140,33 @@ public class RaceStateTest { } @Test - public void testAdvancePass() { + public void testAdvancePass() throws InterruptedException { state.addChangedListener(listener); int oldPassId = raceLog.getCurrentPassId(); - + Thread.sleep(1); // ensure that a status update is triggered due to the calculation time stamps between set-up and pass advance vary state.setAdvancePass(mock(TimePoint.class)); - assertEquals(oldPassId + 1, raceLog.getCurrentPassId()); verify(listener).onAdvancePass(state); + verify(listener).onStatusChanged(state); verifyNoMoreInteractions(listener); } @Test - public void testAbort() { + public void testAbort() throws InterruptedException { state.addChangedListener(listener); - + Thread.sleep(1); // ensure that a status update is triggered due to the calculation time stamps between set-up and pass advance vary state.setAborted(mock(TimePoint.class), false, Flags.NONE); - + verify(listener).onStatusChanged(state); // TODO: change test when interface is complete verifyNoMoreInteractions(listener); } @Test - public void testGeneralRecall() { + public void testGeneralRecall() throws InterruptedException { state.addChangedListener(listener); - + Thread.sleep(1); // ensure that a status update is triggered due to the calculation time stamps between set-up and pass advance vary state.setGeneralRecall(mock(TimePoint.class)); - + verify(listener).onStatusChanged(state); // TODO: change test when interface is complete verifyNoMoreInteractions(listener); } @@ -174,20 +174,21 @@ public class RaceStateTest { @Test public void testInvalidateAfterAdvancePass() throws InterruptedException { state.addChangedListener(listener); - + Thread.sleep(1); // ensure that a status update is triggered due to the calculation time stamps between set-up and pass advance vary state.forceNewStartTime(nowMock, new MillisecondsTimePoint(1)); Thread.sleep(100); + Thread.sleep(1); // ensure that a status update is triggered due to the calculation time stamps between set-up and pass advance vary state.setFinishedTime(new MillisecondsTimePoint(10)); + Thread.sleep(1); // ensure that a status update is triggered due to the calculation time stamps between set-up and pass advance vary state.setCourseDesign(nowMock, mock(CourseBase.class), CourseDesignerMode.ADMIN_CONSOLE); - + Thread.sleep(1); // ensure that a status update is triggered due to the calculation time stamps between set-up and pass advance vary state.setAdvancePass(mock(TimePoint.class)); - assertNull(state.getStartTime()); assertEquals(RaceLogRaceStatus.UNSCHEDULED, state.getStatus()); verify(listener, times(1)).onAdvancePass(state); verify(listener, times(2)).onStartTimeChanged(state); verify(listener, times(2)).onFinishedTimeChanged(state); - verify(listener, times(3)).onStatusChanged(state); + verify(listener, times(5)).onStatusChanged(state); verify(listener, times(1)).onCourseDesignChanged(state); verifyNoMoreInteractions(listener); } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/RaceStatusAnalyzer.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/RaceStatusAnalyzer.java index 5c7410afa56..617fb2c4e69 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/RaceStatusAnalyzer.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/RaceStatusAnalyzer.java @@ -10,11 +10,19 @@ import com.sap.sailing.domain.abstractlog.race.impl.RaceLogRaceStatusEventCompar import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.ReadonlyRacingProcedure; import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus; import com.sap.sse.common.TimePoint; +import com.sap.sse.common.Util.Pair; import com.sap.sse.common.impl.MillisecondsTimePoint; import com.sap.sse.util.impl.ArrayListNavigableSet; -public class RaceStatusAnalyzer extends RaceLogAnalyzer { - +/** + * Returns the status and the clock {@link TimePoint} at which it was calculated. That time point is obtained + * from the {@link Clock} passed to this analyzer at construction time. It is queried at the time the analysis + * takes place ({@link #performAnalysis()}. + * + * @author Axel Uhl (d043530) + * + */ +public class RaceStatusAnalyzer extends RaceLogAnalyzer> { public interface Clock { TimePoint now(); } @@ -24,26 +32,25 @@ public class RaceStatusAnalyzer extends RaceLogAnalyzer { public TimePoint now() { return MillisecondsTimePoint.now(); } - } - private final EventDispatcher eventDispatcher; - private RaceLogResolver resolver; + private final RaceLogResolver resolver; + private final Clock clock; + private final ReadonlyRacingProcedure racingProcedure; public RaceStatusAnalyzer(RaceLogResolver resolver, RaceLog raceLog, ReadonlyRacingProcedure racingProcedure) { - super(raceLog); - this.eventDispatcher = new EventDispatcher(new StandardClock(), racingProcedure); - this.resolver = resolver; + this(resolver, raceLog, new StandardClock(), racingProcedure); } public RaceStatusAnalyzer(RaceLogResolver resolver, RaceLog raceLog, Clock clock, ReadonlyRacingProcedure racingProcedure) { super(raceLog); - this.eventDispatcher = new EventDispatcher(clock, racingProcedure); this.resolver = resolver; + this.clock = clock; + this.racingProcedure = racingProcedure; } @Override - protected RaceLogRaceStatus performAnalysis() { + protected Pair performAnalysis() { ArrayListNavigableSet statusEvents = new ArrayListNavigableSet<>( RaceLogRaceStatusEventComparator.INSTANCE); for (RaceLogEvent event : getPassEvents()) { @@ -51,21 +58,25 @@ public class RaceStatusAnalyzer extends RaceLogAnalyzer { statusEvents.add((RaceLogRaceStatusEvent) event); } } + final TimePoint now = clock.now(); + final EventDispatcher eventDispatcher = new EventDispatcher(now, racingProcedure); + RaceLogRaceStatus result = RaceLogRaceStatus.UNSCHEDULED; for (RaceLogRaceStatusEvent event : statusEvents.descendingSet()) { event.accept(eventDispatcher); - return eventDispatcher.nextStatus; + result = eventDispatcher.nextStatus; + break; } - return RaceLogRaceStatus.UNSCHEDULED; + return new Pair<>(result, now); } private class EventDispatcher extends BaseRaceLogEventVisitor { - private final Clock clock; + private final TimePoint now; private final ReadonlyRacingProcedure racingProcedure; public RaceLogRaceStatus nextStatus; - public EventDispatcher(Clock clock, ReadonlyRacingProcedure racingProcedure) { - this.clock = clock; + public EventDispatcher(TimePoint now, ReadonlyRacingProcedure racingProcedure) { + this.now = now; this.racingProcedure = racingProcedure; this.nextStatus = RaceLogRaceStatus.UNKNOWN; } @@ -80,7 +91,6 @@ public class RaceStatusAnalyzer extends RaceLogAnalyzer { if (startTime == null) { nextStatus = RaceLogRaceStatus.PRESCHEDULED; } else { - TimePoint now = clock.now(); if (racingProcedure.isStartphaseActive(startTime, now)) { nextStatus = RaceLogRaceStatus.STARTPHASE; } else if (now.before(startTime)) { diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/RaceStateEventScheduler.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/RaceStateEventScheduler.java index 0129123d77b..3637f3cdb3d 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/RaceStateEventScheduler.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/RaceStateEventScheduler.java @@ -1,12 +1,10 @@ package com.sap.sailing.domain.abstractlog.race.state; -import java.util.Collection; - import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateEvents; public interface RaceStateEventScheduler { - void scheduleStateEvents(Collection stateEvents); + void scheduleStateEvents(Iterable stateEvents); void unscheduleStateEvent(RaceStateEvents stateEventName); diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java index beb3f16c06b..fd74cd0fea6 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java @@ -2,6 +2,8 @@ package com.sap.sailing.domain.abstractlog.race.state.impl; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; import java.util.Map; import com.sap.sailing.domain.abstractlog.race.CompetitorResults; @@ -44,6 +46,8 @@ import com.sap.sailing.domain.common.racelog.RacingProcedureType; import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimeRange; import com.sap.sse.common.Util; +import com.sap.sse.common.Util.Pair; +import com.sap.sse.common.impl.TimeRangeImpl; import com.sap.sse.util.WeakIdentityHashMap; /** @@ -139,7 +143,8 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL private RaceStateEventScheduler scheduler; /** - * We need one for each change in {@link RacingProcedureType}. + * We need one for each change in {@link RacingProcedureType}. The analyzer uses the {@link #statusAnalyzerClock} + * as its time source. */ private RaceStatusAnalyzer statusAnalyzer; private final RacingProcedureTypeAnalyzer racingProcedureAnalyzer; @@ -168,6 +173,22 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL private RacingProcedureType cachedRacingProcedureTypeNoFallback; private RaceLogRaceStatus cachedRaceStatus; + + /** + * The time taken from {@link #statusAnalyzerClock} when the race status was last updated. Set to a valid + * value whenever {@link #cachedRaceStatus} is set. + */ + private TimePoint clockTimePointWhenCachedRaceStatusWasSet; + + /** + * Time points determined during {@link #updateCachedRaceStatusAndValidity(RaceLogRaceStatus)} at which + * the race status may change. If the time range between {@link #clockTimePointWhenCachedRaceStatusWasSet} and + * the current {@link #statusAnalyzerClock clock} time point spans any of these, the {@link #cachedRaceStatus} + * is to be considered invalid and needs to be re-calculated. Set to a valid but possibly empty iterable + * whenever {@link #cachedRaceStatus} is set. + */ + private Iterable timePointsWhenRaceStatusMayChange; + private int cachedPassId; private StartTimeFinderResult cachedStartTimeFinderResult; private TimePoint cachedFinishingTime; @@ -323,9 +344,30 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL @Override public RaceLogRaceStatus getStatus() { // TODO bug4713: check clock and invalidate/recalculate if clock passed status invalidation time point + final TimePoint timePointForAnalysis = statusAnalyzerClock.now(); + final TimeRange timeRangeSinceLastStatusUpdate = new TimeRangeImpl(clockTimePointWhenCachedRaceStatusWasSet, timePointForAnalysis); + if (overlapsTimePointForPotentialStatusChange(timeRangeSinceLastStatusUpdate)) { + analyzeAndUpdateCachedRaceStatus(); + } return cachedRaceStatus; } + /** + * Finds out whether any of the time points in {@link #timePointsWhenRaceStatusMayChange} falls into the time range + * provided. In this case we assume that a race status update may have happened between the time point when the + * {@link #cachedRaceStatus} was updated last and the current request time point, forming the time range provided + * as parameter here. + */ + private boolean overlapsTimePointForPotentialStatusChange(TimeRange timeRangeSinceLastStatusUpdate) { + for (final TimePoint e : timePointsWhenRaceStatusMayChange) { + if (timeRangeSinceLastStatusUpdate.includes(e)) { + return true; + } + } + return false; + } + + @Override public TimePoint getStartTime() { return cachedStartTimeFinderResult.getStartTime(); @@ -461,11 +503,6 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL recreateRacingProcedure(dependentRaceStates); changedListeners.onRacingProcedureChanged(this); } - RaceLogRaceStatus status = statusAnalyzer.analyze(); - if (!Util.equalsWithNull(cachedRaceStatus, status)) { - cachedRaceStatus = status; - changedListeners.onStatusChanged(this); - } int passId = raceLog.getCurrentPassId(); if (cachedPassId != passId) { cachedPassId = passId; @@ -480,6 +517,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL changedListeners.onStartTimeChanged(this); } adjustObserverForRelativeStartTime(startTimeFinderResult, dependentRaceStates); + analyzeAndUpdateCachedRaceStatus(); TimePoint finishingTime = finishingTimeAnalyzer.analyze(); if (!Util.equalsWithNull(cachedFinishingTime, finishingTime)) { cachedFinishingTime = finishingTime; @@ -519,6 +557,43 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL } } + /** + * This method has protected visibility (and not private) to allow instrumenting by test cases + */ + protected void analyzeAndUpdateCachedRaceStatus() { + Pair statusAndTimePoint = statusAnalyzer.analyze(); + if (!Util.equalsWithNull(cachedRaceStatus, statusAndTimePoint)) { + updateCachedRaceStatusAndValidity(statusAndTimePoint); + } + } + + /** + * Updates the {@link #cachedRaceStatus} and calculates and remembers its validity, based on + * {@link ReadonlyRacingProcedure#createStartStateEvents(TimePoint)} and which of those have already + * passed at the current clock time and which ones are still lying ahead. + */ + private void updateCachedRaceStatusAndValidity(Pair statusAndTimePoint) { + cachedRaceStatus = statusAndTimePoint.getA(); + clockTimePointWhenCachedRaceStatusWasSet = statusAndTimePoint.getB(); + if (getStartTimeFinderResult() == null || getStartTime() == null) { + timePointsWhenRaceStatusMayChange = Collections.emptyList(); + } else { + final TimePoint startTime = getStartTime(); + List newTimePointsWhenRaceStatusMayChange = new LinkedList<>(); + for (final RaceStateEvent e : racingProcedure.createStartStateEvents(startTime)) { + newTimePointsWhenRaceStatusMayChange.add(e.getTimePoint()); + } + if (getFinishingTime() != null) { + newTimePointsWhenRaceStatusMayChange.add(getFinishingTime()); + } + if (getFinishedTime() != null) { + newTimePointsWhenRaceStatusMayChange.add(getFinishedTime()); + } + timePointsWhenRaceStatusMayChange = newTimePointsWhenRaceStatusMayChange; + } + changedListeners.onStatusChanged(this); + } + private void recreateRacingProcedure(Map dependentRaceStates) { if (racingProcedure != null) { removeChangedListener(racingProcedure); diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/RacingProcedure.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/RacingProcedure.java index dbc6d40861d..1eba9f3b8fc 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/RacingProcedure.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/RacingProcedure.java @@ -1,8 +1,5 @@ package com.sap.sailing.domain.abstractlog.race.state.racingprocedure; -import java.util.Collection; - -import com.sap.sailing.domain.abstractlog.race.state.RaceStateEvent; import com.sap.sse.common.TimePoint; /** @@ -20,10 +17,4 @@ public interface RacingProcedure extends ReadonlyRacingProcedure { */ void removeIndividualRecall(TimePoint now); - /** - * Delivers the time points and types of the events around the start, each optionally - * leading to a change in race status. - */ - Collection createStartStateEvents(TimePoint startTime); - } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/ReadonlyRacingProcedure.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/ReadonlyRacingProcedure.java index 92613aa02d7..323f21ea714 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/ReadonlyRacingProcedure.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/ReadonlyRacingProcedure.java @@ -4,6 +4,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogAnalyzer; import com.sap.sailing.domain.abstractlog.race.state.RaceState; import com.sap.sailing.domain.abstractlog.race.state.RaceStateChangedListener; +import com.sap.sailing.domain.abstractlog.race.state.RaceStateEvent; import com.sap.sailing.domain.abstractlog.race.state.RaceStateEventProcessor; import com.sap.sailing.domain.abstractlog.race.state.RaceStateEventScheduler; import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState; @@ -122,6 +123,13 @@ public interface ReadonlyRacingProcedure extends RaceStateEventProcessor, RaceSt RacingProcedurePrerequisite checkPrerequisitesForStart(TimePoint now, TimePoint startTime, RacingProcedurePrerequisite.FulfillmentFunction function); + + /** + * Delivers the time points and types of the events around the start, each optionally + * leading to a change in race status. + */ + Iterable createStartStateEvents(TimePoint startTime); + /** * This method is called by the framework. You don't need to call it. */ diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/basic/impl/BasicRacingProcedureImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/basic/impl/BasicRacingProcedureImpl.java index feaa5aeb464..da6f0efee9d 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/basic/impl/BasicRacingProcedureImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/basic/impl/BasicRacingProcedureImpl.java @@ -1,7 +1,6 @@ package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.basic.impl; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; @@ -66,7 +65,7 @@ public class BasicRacingProcedureImpl extends BaseRacingProcedure { } @Override - public Collection createStartStateEvents(TimePoint startTime) { + public Iterable createStartStateEvents(TimePoint startTime) { return Arrays.asList(new RaceStateEventImpl(startTime, RaceStateEvents.START)); } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/ess/impl/ESSRacingProcedureImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/ess/impl/ESSRacingProcedureImpl.java index 0ae3f36f013..7be1ec4160b 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/ess/impl/ESSRacingProcedureImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/ess/impl/ESSRacingProcedureImpl.java @@ -1,7 +1,6 @@ package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.ess.impl; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; @@ -64,7 +63,7 @@ public class ESSRacingProcedureImpl extends BaseRacingProcedure implements ESSRa } @Override - public Collection createStartStateEvents(TimePoint startTime) { + public Iterable createStartStateEvents(TimePoint startTime) { return Arrays. asList(new RaceStateEventImpl(startTime.minus(startPhaseAPDownInterval), RaceStateEvents.ESS_AP_DOWN), new RaceStateEventImpl(startTime.minus(startPhaseESSThreeUpInterval), RaceStateEvents.ESS_THREE_UP), new RaceStateEventImpl(startTime.minus(startPhaseESSTwoUpInterval), diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/gate/impl/GateStartRacingProcedureImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/gate/impl/GateStartRacingProcedureImpl.java index 6a6d89679f2..5daae5a52ec 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/gate/impl/GateStartRacingProcedureImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/gate/impl/GateStartRacingProcedureImpl.java @@ -1,7 +1,6 @@ package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.gate.impl; import java.util.Arrays; -import java.util.Collection; import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; import com.sap.sailing.domain.abstractlog.race.RaceLog; @@ -119,7 +118,7 @@ public class GateStartRacingProcedureImpl extends BaseRacingProcedure implements } @Override - public Collection createStartStateEvents(TimePoint startTime) { + public Iterable createStartStateEvents(TimePoint startTime) { return Arrays. asList( new RaceStateEventImpl(startTime.minus(startPhaseClassOverGolfUpInterval), RaceStateEvents.GATE_CLASS_OVER_GOLF_UP), diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/impl/LeagueRacingProcedureImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/impl/LeagueRacingProcedureImpl.java index 703c2244571..7dab122f8fb 100755 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/impl/LeagueRacingProcedureImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/impl/LeagueRacingProcedureImpl.java @@ -1,7 +1,6 @@ package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.impl; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; @@ -81,7 +80,7 @@ public class LeagueRacingProcedureImpl extends BaseRacingProcedure implements Le } @Override - public Collection createStartStateEvents(TimePoint startTime) { + public Iterable createStartStateEvents(TimePoint startTime) { // Remark: We are reusing here CLASS_UP, STARTMODE_UP and STARTMODE_DOWN from the RRS26 procedure // The question is why there are no generic CLASS_UP, STARTMODE_UP and STARTMODE_DOWN events return Arrays. asList( diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/RRS26RacingProcedureImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/RRS26RacingProcedureImpl.java index a2780f3daad..bb728fda311 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/RRS26RacingProcedureImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/RRS26RacingProcedureImpl.java @@ -1,7 +1,6 @@ package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.line.impl; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.List; @@ -64,7 +63,7 @@ public class RRS26RacingProcedureImpl extends ConfigurableStartModeFlagRacingPro } @Override - public Collection createStartStateEvents(TimePoint startTime) { + public Iterable createStartStateEvents(TimePoint startTime) { return Arrays. asList( new RaceStateEventImpl(startTime.minus(startPhaseClassUpInterval), RaceStateEvents.RRS26_CLASS_UP), new RaceStateEventImpl(startTime.minus(startPhaseStartModeUpInterval), RaceStateEvents.RRS26_STARTMODE_UP), diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/SWCRacingProcedureImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/SWCRacingProcedureImpl.java index 18000930a16..57f5428d08b 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/SWCRacingProcedureImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/line/impl/SWCRacingProcedureImpl.java @@ -1,7 +1,6 @@ package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.line.impl; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.List; @@ -69,7 +68,7 @@ public class SWCRacingProcedureImpl extends ConfigurableStartModeFlagRacingProce } @Override - public Collection createStartStateEvents(TimePoint startTime) { + public Iterable createStartStateEvents(TimePoint startTime) { return Arrays. asList( new RaceStateEventImpl(startTime.minus(CLASS_AND_STARTMODE_UP_INTERVAL), RaceStateEvents.SWC_CLASS_AND_STARTMODE_UP), new RaceStateEventImpl(startTime.minus(FIVE_MINUTES_FLAG_UP_INTERVAL), RaceStateEvents.SWC_FIVE_UP), diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/services/RaceStateEventSchedulerOnService.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/services/RaceStateEventSchedulerOnService.java index 29ac1d61ec8..0a22ca93ba4 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/services/RaceStateEventSchedulerOnService.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/services/RaceStateEventSchedulerOnService.java @@ -1,7 +1,5 @@ package com.sap.sailing.racecommittee.app.services; -import java.util.Collection; - import com.sap.sailing.domain.abstractlog.race.state.RaceStateEvent; import com.sap.sailing.domain.abstractlog.race.state.RaceStateEventScheduler; import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateEvents; @@ -18,7 +16,7 @@ public class RaceStateEventSchedulerOnService implements RaceStateEventScheduler } @Override - public void scheduleStateEvents(Collection stateEvents) { + public void scheduleStateEvents(Iterable stateEvents) { for (RaceStateEvent stateEvent : stateEvents) { service.setAlarm(race, stateEvent); } From 6aac0335df626b3dcf865a15e880b001bba5f549 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 9 Aug 2018 11:28:14 +0200 Subject: [PATCH 39/53] bug4713: avoid phony race status updates if only the meta-attributes for caching have changed Change-Id: If2263925f9e15684cebb5be4f692d6ca69cda459 --- .../domain/racelog/state/test/RaceStateTest.java | 12 +----------- .../race/state/impl/ReadonlyRaceStateImpl.java | 7 +++++-- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/state/test/RaceStateTest.java b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/state/test/RaceStateTest.java index 0881da8cd97..357ae765a9e 100644 --- a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/state/test/RaceStateTest.java +++ b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/state/test/RaceStateTest.java @@ -143,20 +143,16 @@ public class RaceStateTest { public void testAdvancePass() throws InterruptedException { state.addChangedListener(listener); int oldPassId = raceLog.getCurrentPassId(); - Thread.sleep(1); // ensure that a status update is triggered due to the calculation time stamps between set-up and pass advance vary state.setAdvancePass(mock(TimePoint.class)); assertEquals(oldPassId + 1, raceLog.getCurrentPassId()); verify(listener).onAdvancePass(state); - verify(listener).onStatusChanged(state); verifyNoMoreInteractions(listener); } @Test public void testAbort() throws InterruptedException { state.addChangedListener(listener); - Thread.sleep(1); // ensure that a status update is triggered due to the calculation time stamps between set-up and pass advance vary state.setAborted(mock(TimePoint.class), false, Flags.NONE); - verify(listener).onStatusChanged(state); // TODO: change test when interface is complete verifyNoMoreInteractions(listener); } @@ -164,9 +160,7 @@ public class RaceStateTest { @Test public void testGeneralRecall() throws InterruptedException { state.addChangedListener(listener); - Thread.sleep(1); // ensure that a status update is triggered due to the calculation time stamps between set-up and pass advance vary state.setGeneralRecall(mock(TimePoint.class)); - verify(listener).onStatusChanged(state); // TODO: change test when interface is complete verifyNoMoreInteractions(listener); } @@ -174,21 +168,17 @@ public class RaceStateTest { @Test public void testInvalidateAfterAdvancePass() throws InterruptedException { state.addChangedListener(listener); - Thread.sleep(1); // ensure that a status update is triggered due to the calculation time stamps between set-up and pass advance vary state.forceNewStartTime(nowMock, new MillisecondsTimePoint(1)); Thread.sleep(100); - Thread.sleep(1); // ensure that a status update is triggered due to the calculation time stamps between set-up and pass advance vary state.setFinishedTime(new MillisecondsTimePoint(10)); - Thread.sleep(1); // ensure that a status update is triggered due to the calculation time stamps between set-up and pass advance vary state.setCourseDesign(nowMock, mock(CourseBase.class), CourseDesignerMode.ADMIN_CONSOLE); - Thread.sleep(1); // ensure that a status update is triggered due to the calculation time stamps between set-up and pass advance vary state.setAdvancePass(mock(TimePoint.class)); assertNull(state.getStartTime()); assertEquals(RaceLogRaceStatus.UNSCHEDULED, state.getStatus()); verify(listener, times(1)).onAdvancePass(state); verify(listener, times(2)).onStartTimeChanged(state); verify(listener, times(2)).onFinishedTimeChanged(state); - verify(listener, times(5)).onStatusChanged(state); + verify(listener, times(3)).onStatusChanged(state); verify(listener, times(1)).onCourseDesignChanged(state); verifyNoMoreInteractions(listener); } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java index fd74cd0fea6..0479340334b 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java @@ -517,7 +517,6 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL changedListeners.onStartTimeChanged(this); } adjustObserverForRelativeStartTime(startTimeFinderResult, dependentRaceStates); - analyzeAndUpdateCachedRaceStatus(); TimePoint finishingTime = finishingTimeAnalyzer.analyze(); if (!Util.equalsWithNull(cachedFinishingTime, finishingTime)) { cachedFinishingTime = finishingTime; @@ -528,6 +527,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL cachedFinishedTime = finishedTime; changedListeners.onFinishedTimeChanged(this); } + analyzeAndUpdateCachedRaceStatus(); // do this after start and finishing times have been updated TimeRange protest = protestTimeAnalyzer.analyze(); if (!Util.equalsWithNull(cachedProtest, protest)) { cachedProtest = protest; @@ -573,6 +573,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL * passed at the current clock time and which ones are still lying ahead. */ private void updateCachedRaceStatusAndValidity(Pair statusAndTimePoint) { + final RaceLogRaceStatus oldRaceStatus = cachedRaceStatus; cachedRaceStatus = statusAndTimePoint.getA(); clockTimePointWhenCachedRaceStatusWasSet = statusAndTimePoint.getB(); if (getStartTimeFinderResult() == null || getStartTime() == null) { @@ -591,7 +592,9 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL } timePointsWhenRaceStatusMayChange = newTimePointsWhenRaceStatusMayChange; } - changedListeners.onStatusChanged(this); + if (!Util.equalsWithNull(oldRaceStatus, cachedRaceStatus)) { + changedListeners.onStatusChanged(this); + } } private void recreateRacingProcedure(Map dependentRaceStates) { From f3fbc463fabb9583aff1e2f02e357bf0f15c239d Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 9 Aug 2018 12:57:40 +0200 Subject: [PATCH 40/53] consider only race log events valid at request time point Change-Id: Ica33a29f0a3b653b8f0b803c1e7b37dd5f2b0acd --- .../race/analyzing/impl/RaceStatusAnalyzer.java | 9 ++++++--- .../race/state/impl/ReadonlyRaceStateImpl.java | 1 - 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/RaceStatusAnalyzer.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/RaceStatusAnalyzer.java index 617fb2c4e69..5197e22dd25 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/RaceStatusAnalyzer.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/RaceStatusAnalyzer.java @@ -62,9 +62,12 @@ public class RaceStatusAnalyzer extends RaceLogAnalyzer(result, now); } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java index 0479340334b..c6e847315d4 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java @@ -343,7 +343,6 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL @Override public RaceLogRaceStatus getStatus() { - // TODO bug4713: check clock and invalidate/recalculate if clock passed status invalidation time point final TimePoint timePointForAnalysis = statusAnalyzerClock.now(); final TimeRange timeRangeSinceLastStatusUpdate = new TimeRangeImpl(clockTimePointWhenCachedRaceStatusWasSet, timePointForAnalysis); if (overlapsTimePointForPotentialStatusChange(timeRangeSinceLastStatusUpdate)) { From 648198cfc2d9b2d4dc9e8671a2b8c260a358727b Mon Sep 17 00:00:00 2001 From: Steffen Schaefer Date: Thu, 9 Aug 2018 13:20:38 +0200 Subject: [PATCH 41/53] Bug 4695: Code format only change --- .../client/leaderboard/SingleRaceLeaderboardSettings.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/SingleRaceLeaderboardSettings.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/SingleRaceLeaderboardSettings.java index edf6c10639a..509a76681f9 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/SingleRaceLeaderboardSettings.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/SingleRaceLeaderboardSettings.java @@ -17,8 +17,9 @@ public class SingleRaceLeaderboardSettings extends LeaderboardSettings { public SingleRaceLeaderboardSettings(Collection maneuverDetailsToShow, Collection legDetailsToShow, Collection raceDetailsToShow, Collection overallDetailsToShow, Long delayBetweenAutoAdvancesInMilliseconds, - boolean showAddedScores, boolean showCompetitorShortNameColumn, - boolean showCompetitorFullNameColumn, boolean showCompetitorBoatInfoColumn, boolean isCompetitorNationalityColumnVisible,boolean showRaceRankColumn) { + boolean showAddedScores, boolean showCompetitorShortNameColumn, boolean showCompetitorFullNameColumn, + boolean showCompetitorBoatInfoColumn, boolean isCompetitorNationalityColumnVisible, + boolean showRaceRankColumn) { super(maneuverDetailsToShow, legDetailsToShow, raceDetailsToShow, overallDetailsToShow, delayBetweenAutoAdvancesInMilliseconds, showAddedScores, showCompetitorShortNameColumn, showCompetitorFullNameColumn, showCompetitorBoatInfoColumn, isCompetitorNationalityColumnVisible); From 67d12dd282e7b9e3d5aa25b6138073570a10620c Mon Sep 17 00:00:00 2001 From: Steffen Schaefer Date: Thu, 9 Aug 2018 14:10:59 +0200 Subject: [PATCH 42/53] Bug 4695: Ensures that SingleRaceLeaderboardPanelLifecycle.createDefaultSettings sets the correct default for showCompetitorBoatInfoColumn to make the serialization does not always explicitly saves showCompetitorBoatInfoColumn in case of a leaderboard having canBoatsOfCompetitorsChangePerRace == true --- .../settings/client/leaderboard/LeaderboardSettings.java | 3 ++- .../client/leaderboard/LeaderboardSettingsFactory.java | 2 +- .../client/leaderboard/MultiRaceLeaderboardSettings.java | 3 ++- .../client/leaderboard/SingleRaceLeaderboardSettings.java | 4 ++-- .../ui/raceboard/SingleRaceLeaderboardPanelLifecycle.java | 6 ++---- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardSettings.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardSettings.java index 99ad8b70c2e..1409a1046d9 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardSettings.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardSettings.java @@ -66,7 +66,8 @@ public abstract class LeaderboardSettings extends AbstractGenericSerializableSet showCompetitorBoatInfoColumn = new BooleanSetting("showCompetitorBoatInfoColumn", this, false); } - public LeaderboardSettings() { + public LeaderboardSettings(boolean showCompetitorBoatInfoColumnDefault) { + showCompetitorBoatInfoColumn.setDefaultValue(showCompetitorBoatInfoColumnDefault); } /** diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardSettingsFactory.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardSettingsFactory.java index 1dd0fb242a0..4f4778b2336 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardSettingsFactory.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardSettingsFactory.java @@ -44,7 +44,7 @@ public class LeaderboardSettingsFactory { } public SingleRaceLeaderboardSettings createNewSettingsWithCustomRaceDetails(List raceDetailsToShow) { - SingleRaceLeaderboardSettings defaultSettings = new SingleRaceLeaderboardSettings(); + SingleRaceLeaderboardSettings defaultSettings = new SingleRaceLeaderboardSettings(true); return new SingleRaceLeaderboardSettings( defaultSettings.getManeuverDetailsToShow(), defaultSettings.getLegDetailsToShow(), diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/MultiRaceLeaderboardSettings.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/MultiRaceLeaderboardSettings.java index 74232f6c701..fc9714d71fd 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/MultiRaceLeaderboardSettings.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/MultiRaceLeaderboardSettings.java @@ -28,7 +28,7 @@ public class MultiRaceLeaderboardSettings extends LeaderboardSettings { public MultiRaceLeaderboardSettings() { - super(); + super(false); } public MultiRaceLeaderboardSettings(Collection maneuverDetailsToShow, @@ -48,6 +48,7 @@ public class MultiRaceLeaderboardSettings extends LeaderboardSettings { } public MultiRaceLeaderboardSettings(Iterable namesOfRaceColumnsToShow) { + super(false); this.namesOfRaceColumnsToShow.setValues(namesOfRaceColumnsToShow); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/SingleRaceLeaderboardSettings.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/SingleRaceLeaderboardSettings.java index 509a76681f9..5c85a5d8a37 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/SingleRaceLeaderboardSettings.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/SingleRaceLeaderboardSettings.java @@ -10,8 +10,8 @@ public class SingleRaceLeaderboardSettings extends LeaderboardSettings { private BooleanSetting showRaceRankColumn; - public SingleRaceLeaderboardSettings() { - super(); + public SingleRaceLeaderboardSettings(boolean showCompetitorBoatInfoColumnDefault) { + super(showCompetitorBoatInfoColumnDefault); } public SingleRaceLeaderboardSettings(Collection maneuverDetailsToShow, diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/SingleRaceLeaderboardPanelLifecycle.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/SingleRaceLeaderboardPanelLifecycle.java index e2bbbad0f13..6e06ca8f3eb 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/SingleRaceLeaderboardPanelLifecycle.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/SingleRaceLeaderboardPanelLifecycle.java @@ -34,19 +34,17 @@ public class SingleRaceLeaderboardPanelLifecycle extends LeaderboardPanelLifecyc raceDetails.add(DetailType.NUMBER_OF_MANEUVERS); raceDetails.add(DetailType.RACE_DISPLAY_LEGS); List overallDetails = new ArrayList<>(); - SingleRaceLeaderboardSettings defaultSettings = new SingleRaceLeaderboardSettings(); + SingleRaceLeaderboardSettings defaultSettings = new SingleRaceLeaderboardSettings(canBoatsOfCompetitorsChangePerRace); // don't show competitor fullName column if even leaderboard isn't shown initially final boolean showCompetitorFullNameColumn = isScreenLargeEnoughToInitiallyDisplayLeaderboard; - // the boat info is usually only interesting when boats of competitors can change per race - final boolean showCompetitorBoatInfoColumn = canBoatsOfCompetitorsChangePerRace; SingleRaceLeaderboardSettings settings = new SingleRaceLeaderboardSettings( defaultSettings.getManeuverDetailsToShow(), defaultSettings.getLegDetailsToShow(), defaultSettings.getRaceDetailsToShow(), overallDetails, DEFAULT_REFRESH_INTERVAL, defaultSettings.isShowAddedScores(), /* showCompetitorShortNameColumn */ true, showCompetitorFullNameColumn, - showCompetitorBoatInfoColumn, + /* showCompetitorBoatInfoColumn */ canBoatsOfCompetitorsChangePerRace, /* isCompetitorNationalityColumnVisible */ false, /* showRaceRankColumn */ false); SettingsUtil.copyDefaultsFromValues(settings, settings); From 6dbbbb1834c533717759402d183833996b113fc5 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 9 Aug 2018 17:17:53 +0200 Subject: [PATCH 43/53] bug4713: implemented fix for comment 9; tests locally green Change-Id: I9466ad6d383bc2072f18cb5ca278eaeb73a48fe3 --- .../analyzing/test/RaceLogAnalyzerTest.java | 3 +- .../test/RaceStatusAnalyzerTest.java | 29 ++++++++++++------- .../analyzing/impl/RaceStatusAnalyzer.java | 24 +++++++++++++-- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/RaceLogAnalyzerTest.java b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/RaceLogAnalyzerTest.java index a40cda33219..a390a8fcd96 100644 --- a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/RaceLogAnalyzerTest.java +++ b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/RaceLogAnalyzerTest.java @@ -30,7 +30,8 @@ public abstract class RaceLogAnalyzerTest T createEvent(Class type, long milliseconds) { - return createEvent(/* priority */ 0, type, milliseconds); + final T result = createEvent(/* priority */ 0, type, milliseconds); + return result; } protected static T createEvent(int priority, Class type, long milliseconds) { diff --git a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/RaceStatusAnalyzerTest.java b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/RaceStatusAnalyzerTest.java index 4262010bd36..b564f94ac9c 100644 --- a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/RaceStatusAnalyzerTest.java +++ b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/RaceStatusAnalyzerTest.java @@ -24,6 +24,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceStatusAnalyzer; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceStatusAnalyzer.Clock; +import com.sap.sailing.domain.abstractlog.race.impl.RaceLogRaceStatusEventImpl; import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartProcedureChangedEventImpl; import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartTimeEventImpl; import com.sap.sailing.domain.abstractlog.race.impl.SimpleRaceLogIdentifierImpl; @@ -76,25 +77,33 @@ public class RaceStatusAnalyzerTest extends PassAwareRaceLogAnalyzerTest statusTypesToIgnoreIfEventNotValidYet = new HashSet<>(Arrays.asList( + new RaceLogRaceStatus[] { RaceLogRaceStatus.FINISHED, RaceLogRaceStatus.FINISHING })); @Override protected Pair performAnalysis() { ArrayListNavigableSet statusEvents = new ArrayListNavigableSet<>( @@ -60,10 +66,24 @@ public class RaceStatusAnalyzer extends RaceLogAnalyzer statusesToIgnore = new HashSet<>(); RaceLogRaceStatus result = RaceLogRaceStatus.UNSCHEDULED; for (RaceLogRaceStatusEvent event : statusEvents.descendingSet()) { - // consider race log status events that are valid already at the time point we use as "now" - if (!event.getLogicalTimePoint().after(now)) { + // We need to read across a not yet valid FINISHED event and record that other FINISHED + // events need to be ignored; if we find a not yet valid FINISHING event, ignore further FINISHING + // events; but dispatch all other events (particularly start-related events) to the dispatcher: + final boolean dispatch; + if (statusTypesToIgnoreIfEventNotValidYet.contains(event.getNextStatus())) { + if (event.getLogicalTimePoint().after(now)) { // event not valid yet + statusesToIgnore.add(event.getNextStatus()); // but ignore events of same status with lesser relevance + dispatch = false; + } else { + dispatch = true; + } + } else { + dispatch = true; + } + if (dispatch) { event.accept(eventDispatcher); result = eventDispatcher.nextStatus; break; From 72b4aca18c1198386c3ef26bc8a30f96009dc6d7 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 9 Aug 2018 18:12:26 +0200 Subject: [PATCH 44/53] formatting only Change-Id: I5d742bacad55125735f4d9be3739803e3b18d01c --- .../sailing/server/gateway/jaxrs/spi/MasterDataResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/spi/MasterDataResource.java b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/spi/MasterDataResource.java index 793c1a068cd..0bd41e30623 100644 --- a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/spi/MasterDataResource.java +++ b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/spi/MasterDataResource.java @@ -91,7 +91,7 @@ public class MasterDataResource extends AbstractSailingServerResource { getService().getSensorFixStore(), exportWind, deviceConfigurations); final StreamingOutput streamingOutput; if (compress) { - streamingOutput= new CompressingStreamingOutput(masterData, competitorIds, startTime); + streamingOutput = new CompressingStreamingOutput(masterData, competitorIds, startTime); } else { streamingOutput = new NonCompressingStreamingOutput(masterData, competitorIds, startTime); } From 1be37adf0ed3b3571466ec2b706b4fb30271faba Mon Sep 17 00:00:00 2001 From: "service.tip.git" Date: Thu, 9 Aug 2018 16:17:01 +0000 Subject: [PATCH 45/53] [INTERNAL] Translation delivery: commit by SLS Change-Id: I07339b01f6bc9f4073bc49fadfa1047e3a568a1d --- .../stringmessages/Sailing_StringMessages_es.properties | 3 ++- .../stringmessages/Sailing_StringMessages_fr.properties | 1 + .../stringmessages/Sailing_StringMessages_ja.properties | 1 + .../stringmessages/Sailing_StringMessages_pt.properties | 3 ++- .../stringmessages/Sailing_StringMessages_ru.properties | 3 ++- .../stringmessages/Sailing_StringMessages_zh.properties | 1 + 6 files changed, 9 insertions(+), 3 deletions(-) diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_es.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_es.properties index 038c4898bc2..22d67d92adb 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_es.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_es.properties @@ -188,7 +188,7 @@ AbsRelativeBearingToNextMarkAfterManeuver=Rumbo relativo absoluto a la siguiente RatioBetweenDistanceSailedWithAndWithoutManeuver=Ratio entre distancia navegada con y sin maniobra RatioBetweenDistanceSailedTowardMiddleAngleProjectionWithAndWithoutManeuver=Ratio entre distancia navegada hacia la proyección del ángulo medio con y sin maniobra DurationLostByManeuver=Tiempo perdido por maniobra -DurationLostByManeuverTowardMiddleAngleProjection=tiempo perdido por maniobra hacia la proyección del ángulo medio +DurationLostByManeuverTowardMiddleAngleProjection=Tiempo perdido por maniobra hacia la proyección del ángulo medio JibingCount=Recuento de trasluchadas TackingCount=Recuento de viradas AbsTwaAtMaxTurningRate=TWA absoluto en velocidad máxima de giro @@ -199,3 +199,4 @@ PercentageOfMainCurveProgressUntilHighestSpeed=Porcentaje de progreso de curva p PercentageOfMainCurveProgressUntilMaxTurningRate=Porcentaje de progreso de curva principal hasta velocidad máxima de giro AbsTwaAtManeuverMiddle=TWA absoluto en mitad de maniobra GpsSamplingRate=Velocidad de muestreo de GPS +RaceDuration=Duración de carrera diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_fr.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_fr.properties index 6d9e3781cb4..3c9baf274ae 100755 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_fr.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_fr.properties @@ -199,3 +199,4 @@ PercentageOfMainCurveProgressUntilHighestSpeed=Pourcentage de progression de la PercentageOfMainCurveProgressUntilMaxTurningRate=Pourcentage de progression de la courbe principale jusqu''à la vitesse angulaire max. AbsTwaAtManeuverMiddle=TWA absolu au milieu de la manœuvre GpsSamplingRate=Fréquence d''échantillonage GPS +RaceDuration=Durée de la course diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_ja.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_ja.properties index 153c78f1b5f..af7b95d25a7 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_ja.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_ja.properties @@ -199,3 +199,4 @@ PercentageOfMainCurveProgressUntilHighestSpeed=最高速度までの主曲線進 PercentageOfMainCurveProgressUntilMaxTurningRate=回転率最大速度までの主曲線進行の比率 (%) AbsTwaAtManeuverMiddle=マニューバー中間での絶対 TWA GpsSamplingRate=GPS サンプリング率 +RaceDuration=レース持続時間 diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_pt.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_pt.properties index 48c61759887..46904285579 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_pt.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_pt.properties @@ -188,7 +188,7 @@ AbsRelativeBearingToNextMarkAfterManeuver=Rumo relativo absoluto até a marca se RatioBetweenDistanceSailedWithAndWithoutManeuver=Proporção entre distância navegada com e sem manobra RatioBetweenDistanceSailedTowardMiddleAngleProjectionWithAndWithoutManeuver=Proporção entre distância navegada em direção à projeção do ângulo médio com e sem manobra DurationLostByManeuver=Duração perdida por manobra -DurationLostByManeuverTowardMiddleAngleProjection=duração perdida por manobra em direção à projeção do ângulo médio +DurationLostByManeuverTowardMiddleAngleProjection=Duração perdida por manobra em direção à projeção do ângulo médio JibingCount=Contagem de jaibe TackingCount=Contagem de cambada AbsTwaAtMaxTurningRate=TWA absoluto na taxa de viragem máxima @@ -199,3 +199,4 @@ PercentageOfMainCurveProgressUntilHighestSpeed=Porcentagem de progresso da curva PercentageOfMainCurveProgressUntilMaxTurningRate=Porcentagem de progresso da curva principal até velocidade de taxa de viragem máxima AbsTwaAtManeuverMiddle=TWA absoluto no meio da manobra GpsSamplingRate=Taxa de amostra de GPS +RaceDuration=Duração da corrida diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_ru.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_ru.properties index bc36275620f..01ef682a6e3 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_ru.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_ru.properties @@ -188,7 +188,7 @@ AbsRelativeBearingToNextMarkAfterManeuver=Абс. относительное н RatioBetweenDistanceSailedWithAndWithoutManeuver=Соотношение пройденного расстояния с маневром и без RatioBetweenDistanceSailedTowardMiddleAngleProjectionWithAndWithoutManeuver=Соотношение пройденного расстояния на срединную угловую проекцию с маневром и без DurationLostByManeuver=Потеря длительности за счет маневра -DurationLostByManeuverTowardMiddleAngleProjection=потеря длительности за счет маневра на срединную угловую проекцию +DurationLostByManeuverTowardMiddleAngleProjection=Потеря длительности за счет маневра на срединную угловую проекцию JibingCount=Поворотов фордевинд TackingCount=Поворотов оверштаг AbsTwaAtMaxTurningRate=Абс. TWA при макс. скорости поворота @@ -199,3 +199,4 @@ PercentageOfMainCurveProgressUntilHighestSpeed=Процент прохожден PercentageOfMainCurveProgressUntilMaxTurningRate=Процент прохождения основной кривой до макс. скорости поворота AbsTwaAtManeuverMiddle=Абс. TWA в середине маневра GpsSamplingRate=Частота дискретизации GPS +RaceDuration=Длительность гонки diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_zh.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_zh.properties index 3c6a3559da7..4156966e834 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_zh.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_zh.properties @@ -199,3 +199,4 @@ PercentageOfMainCurveProgressUntilHighestSpeed=最高速度前主要曲线进度 PercentageOfMainCurveProgressUntilMaxTurningRate=最大回转率速度前主要曲线进度的百分比 AbsTwaAtManeuverMiddle=操作中间的绝对实际风向角 GpsSamplingRate=GPS 采样率 +RaceDuration=比赛轮次持续时间 From aa64815bb750ded80642e8a5e4e2f04e7202f209 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 9 Aug 2018 18:41:02 +0200 Subject: [PATCH 46/53] bug4719: start with an empty course for SwissTimingRaceTrackerImpl, no longer depends on early CCG message Change-Id: If7b06e3ba2248e9c5d0660c6ee763ee8ba493639 --- .../swisstimingadapter/impl/SwissTimingRaceTrackerImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingRaceTrackerImpl.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingRaceTrackerImpl.java index 8b960a35e78..6d5bdcf9076 100644 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingRaceTrackerImpl.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingRaceTrackerImpl.java @@ -155,6 +155,8 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl connectivityParams.getRaceID(), connectivityParams.getRaceName(), connectivityParams.getRaceDescription(), connectivityParams.getBoatClass()); this.domainFactory = domainFactory; this.raceID = connectivityParams.getRaceID(); + // start out with an empty course, so we don't depend on receiving the CCG message before the timeout + this.course = new CourseImpl(this.raceID, /* start with empty marks list */ Collections.emptyList()); this.raceName = connectivityParams.getRaceName(); this.startList = connectivityParams.getStartList(); this.startListFromManage2Sail = connectivityParams.getStartList() != null; From 2458a231cf4cabbe6ae166e18110b313240dc097 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 9 Aug 2018 22:15:16 +0200 Subject: [PATCH 47/53] bug4704: added caching also for another overload of ReadonlyRaceStateImpl.create Change-Id: I8e231f62d5d091c028d4dc0f1de42730384f3e56 --- .../race/state/impl/ReadonlyRaceStateImpl.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java index c6e847315d4..accf15e0227 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java @@ -71,6 +71,13 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL * See also bug4704. */ public static ReadonlyRaceState getOrCreate(RaceLogResolver raceLogResolver, RaceLog raceLog) { + return getOrCreate(raceLogResolver, raceLog, /* forRaceLogIdentifier */null, + Collections. emptyMap()); + } + + public static ReadonlyRaceState getOrCreate(RaceLogResolver raceLogResolver, RaceLog raceLog, + SimpleRaceLogIdentifier forRaceLogIdentifier, + Map dependentRaceStates) { WeakIdentityHashMap raceStatesForRaceLog; ReadonlyRaceState result = null; synchronized (raceStateCache) { @@ -82,7 +89,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL result = raceStatesForRaceLog.get(raceLogResolver); } if (result == null) { - result = createInternal(raceLogResolver, raceLog); + result = createInternal(raceLogResolver, raceLog, forRaceLogIdentifier, dependentRaceStates); raceStatesForRaceLog.put(raceLogResolver, result); } } @@ -90,9 +97,10 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL } - private static final ReadonlyRaceState createInternal(RaceLogResolver raceLogResolver, RaceLog raceLog) { - return create(raceLogResolver, raceLog, /* forRaceLogIdentifier */null, - Collections. emptyMap()); + private static final ReadonlyRaceState createInternal(RaceLogResolver raceLogResolver, RaceLog raceLog, + SimpleRaceLogIdentifier forRaceLogIdentifier, + Map dependentRaceStates) { + return create(raceLogResolver, raceLog, forRaceLogIdentifier, dependentRaceStates); } /** @@ -473,7 +481,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL } else { RaceLog resolvedRaceLog = raceLogResolver.resolve(dependentOnRaceIdentifier); if (resolvedRaceLog != null) { - raceStateToObserve = ReadonlyRaceStateImpl.create(raceLogResolver, resolvedRaceLog, + raceStateToObserve = ReadonlyRaceStateImpl.getOrCreate(raceLogResolver, resolvedRaceLog, dependentOnRaceIdentifier, dependentRaceStates); raceStateToObserve.addChangedListener(raceStateToObserveListener); } From 7443901277e1ab439c5ff3bb34ceef221235c025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Sch=C3=A4fer?= Date: Fri, 10 Aug 2018 09:00:49 +0200 Subject: [PATCH 48/53] Bug 4695: Ensures that showCompetitorBoatInfoColumn is set to the default value for mode patching --- .../settings/client/leaderboard/LeaderboardSettingsFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardSettingsFactory.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardSettingsFactory.java index 4f4778b2336..1fa2202485b 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardSettingsFactory.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardSettingsFactory.java @@ -44,7 +44,7 @@ public class LeaderboardSettingsFactory { } public SingleRaceLeaderboardSettings createNewSettingsWithCustomRaceDetails(List raceDetailsToShow) { - SingleRaceLeaderboardSettings defaultSettings = new SingleRaceLeaderboardSettings(true); + SingleRaceLeaderboardSettings defaultSettings = new SingleRaceLeaderboardSettings(false); return new SingleRaceLeaderboardSettings( defaultSettings.getManeuverDetailsToShow(), defaultSettings.getLegDetailsToShow(), From 2f18f08a312862be75e8a3a746049cb637e728de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Fri, 10 Aug 2018 10:27:50 +0200 Subject: [PATCH 49/53] bug4695 show boat column in sixty inch live leaderboard, if the race has changing boats --- ...ithRacemapAndLeaderBoardPresenterImpl.java | 41 ++++++++++++++++--- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/liveraceloop/racemapwithleaderboard/LiveRaceWithRacemapAndLeaderBoardPresenterImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/liveraceloop/racemapwithleaderboard/LiveRaceWithRacemapAndLeaderBoardPresenterImpl.java index 3debae7a209..2177bfcbf95 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/liveraceloop/racemapwithleaderboard/LiveRaceWithRacemapAndLeaderBoardPresenterImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/liveraceloop/racemapwithleaderboard/LiveRaceWithRacemapAndLeaderBoardPresenterImpl.java @@ -12,16 +12,20 @@ import com.google.gwt.i18n.client.NumberFormat; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.AcceptsOneWidget; import com.sap.sailing.domain.common.DetailType; +import com.sap.sailing.domain.common.RaceIdentifier; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; import com.sap.sailing.domain.common.WindSource; import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sailing.domain.common.dto.LeaderboardDTO; import com.sap.sailing.domain.common.dto.LeaderboardRowDTO; +import com.sap.sailing.domain.common.dto.RaceColumnDTO; import com.sap.sailing.gwt.autoplay.client.app.AnimationPanel; import com.sap.sailing.gwt.autoplay.client.app.AutoPlayClientFactory; import com.sap.sailing.gwt.autoplay.client.app.AutoPlayPresenterConfigured; import com.sap.sailing.gwt.autoplay.client.utils.AutoplayHelper; import com.sap.sailing.gwt.settings.client.leaderboard.SingleRaceLeaderboardSettings; import com.sap.sailing.gwt.ui.client.FlagImageResolverImpl; +import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sailing.gwt.ui.client.shared.racemap.RaceCompetitorSet; @@ -152,12 +156,7 @@ public class LiveRaceWithRacemapAndLeaderBoardPresenterImpl view.showErrorNoLive(this, panel, new IllegalStateException("No race is live")); return; } - final SingleRaceLeaderboardSettings leaderboardSettings = new SingleRaceLeaderboardSettings( - /* maneuverDetailsToShow */ null, /* legDetailsToShow */ null, /* raceDetailsToShow */ null, - /* overallDetailsToShow */ null, /* delayBetweenAutoAdvancesInMilliseconds */ null, - /* showAddedScores */ false, /* showCompetitorShortNameColumn */ true, - /* showCompetitorFullNameColumn */ false, /* isCompetitorNationalityColumnVisible */ false, - /* showCompetitorBoatInfoColumn */ false, /* showRaceRankColumn */ true); + final SingleRaceLeaderboardSettings leaderboardSettings = getLeaderboardSettings(false); timer = new com.sap.sse.gwt.client.player.Timer( // perform the first request as "live" but don't by default auto-play PlayModes.Live, PlayStates.Playing, @@ -167,12 +166,42 @@ public class LiveRaceWithRacemapAndLeaderBoardPresenterImpl getSlideCtx().getContextDefinition().getLeaderboardName(), errorReporter, StringMessages.INSTANCE, false, null, false, null, false, true, false, false, false, new SixtyInchLeaderboardStyle(true), FlagImageResolverImpl.get(), Arrays.asList(DetailType.values())); + + leaderboardPanel.addLeaderboardUpdateListener(new LeaderboardUpdateListener() { + + @Override + public void updatedLeaderboard(LeaderboardDTO leaderboard) { + // if this is a changing boat race, enable the boat column + if (leaderboardPanel.getLeaderboard() != null) { + LeaderboardDTO leaderboardDTO = leaderboardPanel.getLeaderboard(); + boolean boatsRequired = leaderboardDTO.canBoatsOfCompetitorsChangePerRace; + if (leaderboardPanel.getSettings().isShowCompetitorBoatInfoColumn() != boatsRequired) { + leaderboardPanel.updateSettings(getLeaderboardSettings(boatsRequired)); + } + } + } + + @Override + public void currentRaceSelected(RaceIdentifier raceIdentifier, RaceColumnDTO raceColumn) { + } + }); + getPlace().getRaceMap().setQuickRanksDTOProvider(new QuickRanksDTOFromLeaderboardDTOProvider( new RaceCompetitorSet(getPlace().getRaceMapSelectionProvider()), liveRace)); view.startingWith(this, panel, getPlace().getRaceMap(), leaderboardPanel); selectionTimer.schedule(SWITCH_COMPETITOR_DELAY + AnimationPanel.ANIMATION_DURATION + AnimationPanel.DELAY); } + private SingleRaceLeaderboardSettings getLeaderboardSettings(boolean showBoatColumn) { + final SingleRaceLeaderboardSettings leaderboardSettings = new SingleRaceLeaderboardSettings( + /* maneuverDetailsToShow */ null, /* legDetailsToShow */ null, /* raceDetailsToShow */ null, + /* overallDetailsToShow */ null, /* delayBetweenAutoAdvancesInMilliseconds */ null, + /* showAddedScores */ false, /* showCompetitorShortNameColumn */ true, + /* showCompetitorFullNameColumn */ false, showBoatColumn, + /* showCompetitorBoatInfoColumn */ false, /* showRaceRankColumn */ true); + return leaderboardSettings; + } + @Override public void onStop() { if (timer != null) { From fbc79d131ad89b2b9aa8797735dfbc13b9f95325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Sch=C3=A4fer?= Date: Fri, 10 Aug 2018 14:49:40 +0200 Subject: [PATCH 50/53] Fixed dashboards startup due to split packages com.sap.sse.util being used. This regression was introduced with commit 3b516bcbc3af9e8cd5295c19b51c88f87d942d95 --- java/com.sap.sailing.dashboards.gwt/META-INF/MANIFEST.MF | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/java/com.sap.sailing.dashboards.gwt/META-INF/MANIFEST.MF b/java/com.sap.sailing.dashboards.gwt/META-INF/MANIFEST.MF index 904e059fb74..84eb7093503 100644 --- a/java/com.sap.sailing.dashboards.gwt/META-INF/MANIFEST.MF +++ b/java/com.sap.sailing.dashboards.gwt/META-INF/MANIFEST.MF @@ -26,10 +26,10 @@ Require-Bundle: com.sap.sailing.domain, com.googlecode.mgwt;bundle-version="2.0.0";resolution:=optional, com.sap.sse.gwt.adminconsole, org.apache.commons.math;bundle-version="2.1.0", - com.sap.sse.security.ui + com.sap.sse.security.ui, + com.sap.sse Bundle-ActivationPolicy: lazy -Import-Package: com.sap.sse.util, - javax.servlet;version="3.1.0", +Import-Package: javax.servlet;version="3.1.0", javax.servlet.descriptor;version="3.1.0", javax.servlet.http;version="3.1.0", org.apache.commons.io, From 90a0630863109b38dfd6536d58bdb3eec71917b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20B=C3=B6rnert?= Date: Fri, 10 Aug 2018 15:40:41 +0200 Subject: [PATCH 51/53] bug4721 added non null default ErrorReporter to RaceMap and RaceTimeInfoProvider constructor calls --- .../gwt/client/RibDashboardEntryPoint.java | 2 +- .../gwt/client/dashboardpanel/DashboardPanel.java | 5 +++-- .../startanalysis/StartAnalysisWidget.java | 13 ++++++++----- .../startanalysis/card/StartAnalysisCard.java | 15 ++++++++++----- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardEntryPoint.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardEntryPoint.java index 82aabb4338f..e1d65f16d70 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardEntryPoint.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardEntryPoint.java @@ -21,7 +21,7 @@ public class RibDashboardEntryPoint extends AbstractEntryPoint { public void doOnModuleLoad() { applyMGWTSettings(); DashboardClientFactory dashboardClientFactory = new DashboardClientFactoryImpl(); - DashboardPanel rootPanel = new DashboardPanel(dashboardClientFactory); + DashboardPanel rootPanel = new DashboardPanel(dashboardClientFactory, this); RootLayoutPanel.get().add(rootPanel); WindBotDataRetriever windBotDataRetriever = new WindBotDataRetriever(dashboardClientFactory); windBotDataRetriever.addNumberOfWindBotsChangeListeners(rootPanel); diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dashboardpanel/DashboardPanel.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dashboardpanel/DashboardPanel.java index 56c672e0951..bb4caa36a73 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dashboardpanel/DashboardPanel.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dashboardpanel/DashboardPanel.java @@ -36,6 +36,7 @@ import com.sap.sailing.dashboards.gwt.shared.dto.RaceIdDTO; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sailing.gwt.ui.shared.EventDTO; +import com.sap.sse.gwt.client.ErrorReporter; import com.sap.sse.gwt.client.media.ImageDTO; /** @@ -88,12 +89,12 @@ public class DashboardPanel extends Composite implements NumberOfWindBotsChangeL DashboardClientFactory dashboardClientFactory; private static final Logger logger = Logger.getLogger(DashboardPanel.class.getName()); - public DashboardPanel(DashboardClientFactory dashboardClientFactory) { + public DashboardPanel(DashboardClientFactory dashboardClientFactory, ErrorReporter errorReporter) { DashboardPanelResources.INSTANCE.style().ensureInjected(); this.dashboardClientFactory = dashboardClientFactory; leftWindBotWidget = new WindBotWidget(dashboardClientFactory); rightWindBotWidget = new WindBotWidget(dashboardClientFactory); - startanalysisComponent = new StartAnalysisWidget(this.dashboardClientFactory); + startanalysisComponent = new StartAnalysisWidget(this.dashboardClientFactory, errorReporter); startlineAdvantagesByWindComponent = new StartlineAdvantagesByWindWidget(this.dashboardClientFactory); startlineAdvantageByGeometryWidget = new StartlineAdvantageByGeometryWidget(this.dashboardClientFactory); stringConstants = StringMessages.INSTANCE; diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/widgets/startanalysis/StartAnalysisWidget.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/widgets/startanalysis/StartAnalysisWidget.java index 787fe700495..f5d3c783b83 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/widgets/startanalysis/StartAnalysisWidget.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/widgets/startanalysis/StartAnalysisWidget.java @@ -43,6 +43,7 @@ import com.sap.sailing.dashboards.gwt.shared.dto.StartAnalysisDTO; import com.sap.sailing.domain.common.dto.CompetitorDTO; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapResources; +import com.sap.sse.gwt.client.ErrorReporter; /** * The class contains an collection of {@link StartAnalysisCard}s that are displayed in horizontal aligned pages. It @@ -112,11 +113,12 @@ public class StartAnalysisWidget extends Composite implements HasWidgets, PollsL * */ private int numberOfStartAnalysisCards = 0; private boolean displaysCards; - private List starts; - private List pageChangeListener; + private final List starts; + private final List pageChangeListener; private BottomNotification bottomNotification; private CompetitorSelectionPopup competitorSelectionPopup; - private DashboardClientFactory dashboardClientFactory; + private final DashboardClientFactory dashboardClientFactory; + private final ErrorReporter errorReporter; private final String cookieKeyForSelectedCompetitorInLeaderboard; @@ -131,8 +133,9 @@ public class StartAnalysisWidget extends Composite implements HasWidgets, PollsL /** * Component that contains handles, displays and loads startanalysis cards. * */ - public StartAnalysisWidget(DashboardClientFactory dashboardClientFactory) { + public StartAnalysisWidget(DashboardClientFactory dashboardClientFactory, ErrorReporter errorReporter) { StartAnalysisWidgetResources.INSTANCE.gss().ensureInjected(); + this.errorReporter = errorReporter; dashboardWidgetHeaderAndNoDataMessage = new DashboardWidgetHeaderAndNoDataMessage(); selectedCompetitorWithSettingsButton = new SettingsButtonWithSelectionIndicationLabel(); selectedCompetitorWithSettingsButton.disable(); @@ -378,7 +381,7 @@ public class StartAnalysisWidget extends Composite implements HasWidgets, PollsL } final StartAnalysisCard startlineAnalysisCard = new StartAnalysisCard(numberOfStartAnalysisCards * SCROLL_OFFSET_STARTANALYSIS_CARDS + MARGIN_LEFT_STARTANALYSIS_CARD, numberOfStartAnalysisCards, - startAnalysisDTO, dashboardClientFactory.getSailingService(), raceMapResources); + startAnalysisDTO, dashboardClientFactory.getSailingService(), errorReporter, raceMapResources); startanalysis_card_container.add(startlineAnalysisCard); startlineAnalysisCard.startAnalysisComponentPageChangedToIndexAndStartAnalysis(page, startAnalysisDTO); registerPageChangeListener(startlineAnalysisCard); diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/widgets/startanalysis/card/StartAnalysisCard.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/widgets/startanalysis/card/StartAnalysisCard.java index 497dc402680..6c2442ab7a4 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/widgets/startanalysis/card/StartAnalysisCard.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/widgets/startanalysis/card/StartAnalysisCard.java @@ -38,6 +38,7 @@ import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapResources; import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapSettings; import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapZoomSettings; import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapZoomSettings.ZoomTypes; +import com.sap.sse.gwt.client.ErrorReporter; import com.sap.sse.gwt.client.async.AsyncActionsExecutor; import com.sap.sse.gwt.client.player.Timer.PlayModes; @@ -70,8 +71,9 @@ public class StartAnalysisCard extends Composite implements HasWidgets, StartAna private StartAnalysisDTO startAnalysisDTO; private RaceMap raceMap; - private SailingServiceAsync sailingServiceAsync; - private StringMessages stringMessages; + private final SailingServiceAsync sailingServiceAsync; + private final ErrorReporter errorReporter; + private final StringMessages stringMessages; private final RaceCompetitorSelectionModel competitorSelectionModel; private final double WIND_LINE_ADVANTAGE_DIV_WIDTH_IN_PT = 185; @@ -80,9 +82,11 @@ public class StartAnalysisCard extends Composite implements HasWidgets, StartAna private RaceMapResources raceMapResources; - public StartAnalysisCard(double leftCSSProperty, int cardId, StartAnalysisDTO startAnalysisDTO, SailingServiceAsync sailingServiceAsync, RaceMapResources raceMapResources) { + public StartAnalysisCard(double leftCSSProperty, int cardId, StartAnalysisDTO startAnalysisDTO, + SailingServiceAsync sailingServiceAsync, ErrorReporter errorReporter, RaceMapResources raceMapResources) { stringMessages = StringMessages.INSTANCE; this.sailingServiceAsync = sailingServiceAsync; + this.errorReporter = errorReporter; this.raceMapResources = raceMapResources; competitorSelectionModel = new RaceCompetitorSelectionModel(/* hasMultiSelection */true); competitorSelectionModel.setCompetitors(startAnalysisDTO.getCompetitorDTOsFromStartAnaylsisCompetitorDTOs(), raceMap); @@ -167,10 +171,11 @@ public class StartAnalysisCard extends Composite implements HasWidgets, StartAna RaceTimesInfoProvider raceTimesInfoProvider = new RaceTimesInfoProvider(sailingServiceAsync, - asyncActionsExecutor, null, Collections.singletonList(startAnalysisDTO.regattaAndRaceIdentifier), 5000l /* requestInterval */); + asyncActionsExecutor, errorReporter, + Collections.singletonList(startAnalysisDTO.regattaAndRaceIdentifier), 5000l /* requestInterval */); raceMap = new RaceMap(null, null, new RaceMapLifecycle(StringMessages.INSTANCE), raceMapSettings, sailingServiceAsync, - asyncActionsExecutor, null, timer, competitorSelectionModel, + asyncActionsExecutor, errorReporter, timer, competitorSelectionModel, new RaceCompetitorSet(competitorSelectionModel), StringMessages.INSTANCE, startAnalysisDTO.regattaAndRaceIdentifier, raceMapResources, /* showHeaderPanel */ true, new DefaultQuickRanksDTOProvider()); raceTimesInfoProvider.addRaceTimesInfoProviderListener(raceMap); From 59389244b5f5056817f4710a18f79037243febba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Sch=C3=A4fer?= Date: Fri, 10 Aug 2018 15:48:18 +0200 Subject: [PATCH 52/53] Fixed a bug that caused RibDashboards to not find the SailingService --- .../gwt/ui/client/SailingServiceHelper.java | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceHelper.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceHelper.java index 261db38393a..c4400b452d4 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceHelper.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceHelper.java @@ -2,14 +2,13 @@ package com.sap.sailing.gwt.ui.client; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.rpc.ServiceDefTarget; +import com.sap.sse.gwt.client.EntryPointHelper; import com.sap.sse.gwt.client.ServiceRoutingProvider; /** * Set of convenience factory methods that create a {@link SailingServiceAsync} instance. */ public abstract class SailingServiceHelper { - private final static String moduleBaseURL = GWT.getModuleBaseURL(); - private SailingServiceHelper() { } @@ -41,20 +40,20 @@ public abstract class SailingServiceHelper { * @param sameBundle {@code false} if using {@link SailingService} from a different OSGi bundle (e.g. dashboards), {@code true} otherwise */ public static SailingServiceAsync createSailingServiceInstance(boolean sameBundle, ServiceRoutingProvider routingProvider) { - SailingServiceAsync service = GWT.create(SailingService.class); - ServiceDefTarget serviceToRegister = (ServiceDefTarget) service; - StringBuilder baseURL = new StringBuilder(); - baseURL.append(moduleBaseURL.substring(0, moduleBaseURL.lastIndexOf('/', moduleBaseURL.length() - 2) + 1)); - if (!sameBundle) { - baseURL.append(RemoteServiceMappingConstants.WEB_CONTEXT_PATH).append("/"); - } - - baseURL.append(RemoteServiceMappingConstants.sailingServiceRemotePath); + final SailingServiceAsync service = GWT.create(SailingService.class); + final ServiceDefTarget serviceToRegister = (ServiceDefTarget) service; + final StringBuilder servicePath = new StringBuilder(RemoteServiceMappingConstants.sailingServiceRemotePath); if (routingProvider != null) { - baseURL.append(routingProvider.routingSuffixPath()); + servicePath.append(routingProvider.routingSuffixPath()); + } + + final String servicePathWithRoutingSuffix = servicePath.toString(); + if (sameBundle) { + EntryPointHelper.registerASyncService(serviceToRegister, servicePathWithRoutingSuffix); + } else { + EntryPointHelper.registerASyncService(serviceToRegister, RemoteServiceMappingConstants.WEB_CONTEXT_PATH, servicePathWithRoutingSuffix); } - serviceToRegister.setServiceEntryPoint(baseURL.toString()); return service; } } From bef23514c533f4fce8667064920bc351edf66a0b Mon Sep 17 00:00:00 2001 From: Alessandro Stoltenberg Date: Sun, 12 Aug 2018 10:57:52 +0200 Subject: [PATCH 53/53] Added 470 Men and 470 Women as aliases to the BoatClassMasterdata --- .../src/com/sap/sailing/domain/common/BoatClassMasterdata.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/BoatClassMasterdata.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/BoatClassMasterdata.java index a5d8736439f..b20c3ac4b5a 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/BoatClassMasterdata.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/BoatClassMasterdata.java @@ -17,7 +17,7 @@ public enum BoatClassMasterdata { _49ER ("49er", true, 4.88, 1.93, BoatHullType.MONOHULL, true), _49ERFX ("49erFX", true, 4.88, 1.93, BoatHullType.MONOHULL, true, "49FX"), _420 ("420", true, 4.20, 1.65, BoatHullType.MONOHULL, true, "420er", "420M", "420W"), - _470 ("470", true, 4.70, 1.68, BoatHullType.MONOHULL, true, "470er", "470M", "470W", "470 - M", "470 - W"), + _470 ("470", true, 4.70, 1.68, BoatHullType.MONOHULL, true, "470er", "470M", "470W", "470 - M", "470 - W", "470 Men", "470 Women"), _5O5 ("5O5", true, 5.03, 1.88, BoatHullType.MONOHULL, true, "505", "5o5", "505er", "5o5er"), _5_5MR ("5.5mR", true, 9.50, 1.92, BoatHullType.MONOHULL, true, "5.5 Meter", "5.5 Metre", "5.5", "5.5M", "5.5-metre", "5.5 metre"), _6MR ("6mR", true, 11, 2.2, BoatHullType.MONOHULL, true, "6 Meter", "6 Metre", "6", "6M", "6-metre", "6 metre"),